]> Cypherpunks repositories - gostls13.git/commitdiff
go/parser: allow parsing aliases with type parameters
authorRobert Findley <rfindley@google.com>
Sun, 31 Oct 2021 15:33:00 +0000 (11:33 -0400)
committerRobert Findley <rfindley@google.com>
Wed, 10 Nov 2021 02:26:41 +0000 (02:26 +0000)
We already guard against this in the type checker, and it will
eventually be allowed per the accepted proposal.

Add a placeholder error code for the corresponding type checker error.

Change-Id: I5cc2f1413ecc89ec2094f7178fdb156fb8cc2e43
Reviewed-on: https://go-review.googlesource.com/c/go/+/360235
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/parser/parser.go
src/go/parser/short_test.go
src/go/types/decl.go

index 8952a2bc2972e270bd725e34456a3a1e2c76bb9e..7c1a8be2fa45853cd60d87c3e125f3c08e9510ba 100644 (file)
@@ -2539,9 +2539,11 @@ func (p *parser) parseGenericType(spec *ast.TypeSpec, openPos token.Pos, name0 *
        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()
index 20450bfe8ed362b88d5d12646cc81490ad4cc31f..90a4ec9ecd0473d3806f183cf0805b455216ec5d 100644 (file)
@@ -123,6 +123,7 @@ var validWithTParamsOnly = []string{
        `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) {
@@ -240,7 +241,6 @@ var invalidNoTParamErrs = []string{
 // 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" */()`,
 
index 0188bdaaf95900e5fdb7975151b071b08a092c69..64d5bd195e870766fab91fe5f82c30c0bbbb3bb9 100644 (file)
@@ -631,7 +631,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
        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
        }