}()
}
+ // For signatures, Checker.instance will always succeed because the type argument
+ // count is correct at this point (see assertion above); hence the type assertion
+ // to *Signature will always succeed.
inst := check.instance(pos, typ, targs, nil, check.context()).(*Signature)
assert(inst.TypeParams().Len() == 0) // signature is not generic anymore
check.recordInstance(expr, targs, inst)
// instance instantiates the given original (generic) function or type with the
// provided type arguments and returns the resulting instance. If an identical
// instance exists already in the given contexts, it returns that instance,
-// otherwise it creates a new one.
+// otherwise it creates a new one. If there is an error (such as wrong number
+// of type arguments), the result is Typ[Invalid].
//
// If expanding is non-nil, it is the Named instance type currently being
// expanded. If ctxt is non-nil, it is the context associated with the current
assert(expanding == nil) // Alias instances cannot be reached from Named types
}
+ // verify type parameter count (see go.dev/issue/71198 for a test case)
tparams := orig.TypeParams()
- // TODO(gri) investigate if this is needed (type argument and parameter count seem to be correct here)
- if !check.validateTArgLen(pos, orig.String(), tparams.Len(), len(targs)) {
+ if !check.validateTArgLen(pos, orig.obj.Name(), tparams.Len(), len(targs)) {
+ // TODO(gri) Consider returning a valid alias instance with invalid
+ // underlying (aliased) type to match behavior of *Named
+ // types. Then this function will never return an invalid
+ // result.
return Typ[Invalid]
}
if tparams.Len() == 0 {
-// Copyright 2024 The Go Authors. All rights reserved.
+// Copyright 2025 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.
}
// create instance
- // The instance is not generic anymore as it has type arguments, but it still
- // satisfies the genericType interface because it has type parameters, too.
- inst := check.instance(x.Pos(), gtyp, targs, nil, check.context()).(genericType)
+ // The instance is not generic anymore as it has type arguments, but unless
+ // instantiation failed, it still satisfies the genericType interface because
+ // it has type parameters, too.
+ ityp := check.instance(x.Pos(), gtyp, targs, nil, check.context())
+ inst, _ := ityp.(genericType)
+ if inst == nil {
+ return Typ[Invalid]
+ }
// For Named types, orig.tparams may not be set up, so we need to do expansion later.
check.later(func() {
}()
}
+ // For signatures, Checker.instance will always succeed because the type argument
+ // count is correct at this point (see assertion above); hence the type assertion
+ // to *Signature will always succeed.
inst := check.instance(pos, typ, targs, nil, check.context()).(*Signature)
assert(inst.TypeParams().Len() == 0) // signature is not generic anymore
check.recordInstance(expr, targs, inst)
// instance instantiates the given original (generic) function or type with the
// provided type arguments and returns the resulting instance. If an identical
// instance exists already in the given contexts, it returns that instance,
-// otherwise it creates a new one.
+// otherwise it creates a new one. If there is an error (such as wrong number
+// of type arguments), the result is Typ[Invalid].
//
// If expanding is non-nil, it is the Named instance type currently being
// expanded. If ctxt is non-nil, it is the context associated with the current
assert(expanding == nil) // Alias instances cannot be reached from Named types
}
+ // verify type parameter count (see go.dev/issue/71198 for a test case)
tparams := orig.TypeParams()
- // TODO(gri) investigate if this is needed (type argument and parameter count seem to be correct here)
- if !check.validateTArgLen(pos, orig.String(), tparams.Len(), len(targs)) {
+ if !check.validateTArgLen(pos, orig.obj.Name(), tparams.Len(), len(targs)) {
+ // TODO(gri) Consider returning a valid alias instance with invalid
+ // underlying (aliased) type to match behavior of *Named
+ // types. Then this function will never return an invalid
+ // result.
return Typ[Invalid]
}
if tparams.Len() == 0 {
-// Copyright 2024 The Go Authors. All rights reserved.
+// Copyright 2025 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.
}
// create instance
- // The instance is not generic anymore as it has type arguments, but it still
- // satisfies the genericType interface because it has type parameters, too.
- inst := check.instance(ix.Pos(), gtyp, targs, nil, check.context()).(genericType)
+ // The instance is not generic anymore as it has type arguments, but unless
+ // instantiation failed, it still satisfies the genericType interface because
+ // it has type parameters, too.
+ ityp := check.instance(ix.Pos(), gtyp, targs, nil, check.context())
+ inst, _ := ityp.(genericType)
+ if inst == nil {
+ return Typ[Invalid]
+ }
// For Named types, orig.tparams may not be set up, so we need to do expansion later.
check.later(func() {
--- /dev/null
+// -gotypesalias=1
+
+// Copyright 2025 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 p
+
+type A[_ any] = any
+
+// This must not panic; also the error message must match the style for non-alias types, below.
+func _[_ A /* ERROR "too many type arguments for type A: have 2, want 1" */ [int, string]]() {}
+
+type T[_ any] any
+
+func _[_ T /* ERROR "too many type arguments for type T: have 2, want 1" */ [int, string]]() {}