mirror of https://github.com/golang/go.git
cmd/compile/internal/types2: return an error from Instantiate on incorrect len(targs)
This CL is a clean port of CL 363635 from go/types to types2. Updates #47916 Change-Id: Ib46758435c31ad9a6a4a63f552503d5afa66b5c0 Reviewed-on: https://go-review.googlesource.com/c/go/+/364534 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
2f937d9bfc
commit
3c00a2839a
|
|
@ -13,40 +13,50 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// Instantiate instantiates the type typ with the given type arguments targs.
|
||||
// typ must be a *Named or a *Signature type, and its number of type parameters
|
||||
// must match the number of provided type arguments. The result is a new,
|
||||
// instantiated (not parameterized) type of the same kind (either a *Named or a
|
||||
// *Signature). Any methods attached to a *Named are simply copied; they are
|
||||
// not instantiated.
|
||||
// Instantiate instantiates the type orig with the given type arguments targs.
|
||||
// orig must be a *Named or a *Signature type. If there is no error, the
|
||||
// resulting Type is a new, instantiated (not parameterized) type of the same
|
||||
// kind (either a *Named or a *Signature). Methods attached to a *Named type
|
||||
// are also instantiated, and associated with a new *Func that has the same
|
||||
// position as the original method, but nil function scope.
|
||||
//
|
||||
// If ctxt is non-nil, it may be used to de-dupe the instance against previous
|
||||
// instances with the same identity.
|
||||
// If ctxt is non-nil, it may be used to de-duplicate the instance against
|
||||
// previous instances with the same identity. As a special case, generic
|
||||
// *Signature origin types are only considered identical if they are pointer
|
||||
// equivalent, so that instantiating distinct (but possibly identical)
|
||||
// signatures will yield different instances.
|
||||
//
|
||||
// If verify is set and constraint satisfaction fails, the returned error may
|
||||
// wrap an *ArgumentError indicating which type argument did not satisfy its
|
||||
// corresponding type parameter constraint, and why.
|
||||
// If validate is set, Instantiate verifies that the number of type arguments
|
||||
// and parameters match, and that the type arguments satisfy their
|
||||
// corresponding type constraints. If verification fails, the resulting error
|
||||
// may wrap an *ArgumentError indicating which type argument did not satisfy
|
||||
// its corresponding type parameter constraint, and why.
|
||||
//
|
||||
// TODO(rfindley): change this function to also return an error if lengths of
|
||||
// tparams and targs do not match.
|
||||
func Instantiate(ctxt *Context, typ Type, targs []Type, validate bool) (Type, error) {
|
||||
inst := (*Checker)(nil).instance(nopos, typ, targs, ctxt)
|
||||
|
||||
var err error
|
||||
// If validate is not set, Instantiate does not verify the type argument count
|
||||
// or whether the type arguments satisfy their constraints. Instantiate is
|
||||
// guaranteed to not return an error, but may panic. Specifically, for
|
||||
// *Signature types, Instantiate will panic immediately if the type argument
|
||||
// count is incorrect; for *Named types, a panic may occur later inside the
|
||||
// *Named API.
|
||||
func Instantiate(ctxt *Context, orig Type, targs []Type, validate bool) (Type, error) {
|
||||
if validate {
|
||||
var tparams []*TypeParam
|
||||
switch t := typ.(type) {
|
||||
switch t := orig.(type) {
|
||||
case *Named:
|
||||
tparams = t.TypeParams().list()
|
||||
case *Signature:
|
||||
tparams = t.TypeParams().list()
|
||||
}
|
||||
if len(targs) != len(tparams) {
|
||||
return nil, fmt.Errorf("got %d type arguments but %s has %d type parameters", len(targs), orig, len(tparams))
|
||||
}
|
||||
if i, err := (*Checker)(nil).verify(nopos, tparams, targs); err != nil {
|
||||
return inst, &ArgumentError{i, err}
|
||||
return nil, &ArgumentError{i, err}
|
||||
}
|
||||
}
|
||||
|
||||
return inst, err
|
||||
inst := (*Checker)(nil).instance(nopos, orig, targs, ctxt)
|
||||
return inst, nil
|
||||
}
|
||||
|
||||
// instance creates a type or function instance using the given original type
|
||||
|
|
|
|||
Loading…
Reference in New Issue