-
Notifications
You must be signed in to change notification settings - Fork 17.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/compile/internal/types2: implement types2.Instantiate
Instantiation support for imports. This is experimental but it also doesn't affect Go 1.17 as this code is not executed unless we enable generics (in the parser). Change-Id: If2da09ac3a557ec6a180707a53f75f3ce354f3e9 Reviewed-on: https://go-review.googlesource.com/c/go/+/314773 Trust: Robert Griesemer <gri@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
- Loading branch information
Showing
2 changed files
with
83 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Copyright 2021 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package types2 | ||
|
||
import ( | ||
"cmd/compile/internal/syntax" | ||
"fmt" | ||
) | ||
|
||
// Instantiate instantiates the type typ with the given type arguments. | ||
// typ must be a *Named or a *Signature type, it must be generic, and | ||
// its number of type parameters must match the number of provided type | ||
// arguments. The result is a new, instantiated (not generic) type of | ||
// the same kind (either a *Named or a *Signature). The type arguments | ||
// are not checked against the constraints of the type parameters. | ||
// Any methods attached to a *Named are simply copied; they are not | ||
// instantiated. | ||
func Instantiate(pos syntax.Pos, typ Type, targs []Type) (res Type) { | ||
// TODO(gri) This code is basically identical to the prolog | ||
// in Checker.instantiate. Factor. | ||
var tparams []*TypeName | ||
switch t := typ.(type) { | ||
case *Named: | ||
tparams = t.tparams | ||
case *Signature: | ||
tparams = t.tparams | ||
defer func() { | ||
// If we had an unexpected failure somewhere don't panic below when | ||
// asserting res.(*Signature). Check for *Signature in case Typ[Invalid] | ||
// is returned. | ||
if _, ok := res.(*Signature); !ok { | ||
return | ||
} | ||
// If the signature doesn't use its type parameters, subst | ||
// will not make a copy. In that case, make a copy now (so | ||
// we can set tparams to nil w/o causing side-effects). | ||
if t == res { | ||
copy := *t | ||
res = © | ||
} | ||
// After instantiating a generic signature, it is not generic | ||
// anymore; we need to set tparams to nil. | ||
res.(*Signature).tparams = nil | ||
}() | ||
|
||
default: | ||
panic(fmt.Sprintf("%v: cannot instantiate %v", pos, typ)) | ||
} | ||
|
||
// the number of supplied types must match the number of type parameters | ||
if len(targs) != len(tparams) { | ||
panic(fmt.Sprintf("%v: got %d arguments but %d type parameters", pos, len(targs), len(tparams))) | ||
} | ||
|
||
if len(tparams) == 0 { | ||
return typ // nothing to do (minor optimization) | ||
} | ||
|
||
smap := makeSubstMap(tparams, targs) | ||
return (*Checker)(nil).subst(pos, typ, smap) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters