list := p.parseParameterList(name0, token.RBRACK)
closePos := p.expect(token.RBRACK)
spec.TypeParams = &ast.FieldList{Opening: openPos, List: list, Closing: closePos}
- // Type alias cannot have type parameters. Accept them for robustness but complain.
+ // Let the type checker decide whether to accept type parameters on aliases:
+ // see issue #46477.
if p.tok == token.ASSIGN {
- p.error(p.pos, "generic type cannot be alias")
+ // type alias
+ spec.Assign = p.pos
p.next()
}
spec.Type = p.parseType()
`package p; type I1[T any /* ERROR "expected ']', found any" */ ] interface{}; type I2 interface{ I1[int] }`,
`package p; type I1[T any /* ERROR "expected ']', found any" */ ] interface{}; type I2[T any] interface{ I1[T] }`,
`package p; type _ interface { f[ /* ERROR "expected ';', found '\['" */ T any]() }`,
+ `package p; type T[P any /* ERROR "expected ']'" */ ] = T0`,
}
func TestValid(t *testing.T) {
// error messages produced when ParseTypeParams is set.
var invalidTParamErrs = []string{
`package p; type _[_ any] int; var _ = T[] /* ERROR "expected operand" */ {}`,
- `package p; type T[P any] = /* ERROR "cannot be alias" */ T0`,
`package p; var _ func[ /* ERROR "cannot have type parameters" */ T any](T)`,
`package p; func _[]/* ERROR "empty type parameter list" */()`,
if alias && tdecl.TypeParams.NumFields() != 0 {
// The parser will ensure this but we may still get an invalid AST.
// Complain and continue as regular type definition.
- check.error(atPos(tdecl.Assign), 0, "generic type cannot be alias")
+ check.error(atPos(tdecl.Assign), _Todo, "generic type cannot be alias")
alias = false
}