]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: disallow aliases for generic types
authorRobert Griesemer <gri@golang.org>
Tue, 31 Aug 2021 03:30:25 +0000 (20:30 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 31 Aug 2021 16:43:46 +0000 (16:43 +0000)
The existing approach (alias name stands for generic type name)
is an exception: it's the only place where a generic type could
be used without explicit instantiation. The correct solution is
currently under discussion (see proposal issue #46477).

This CL requires that the RHS of an alias type declaration be
an instantiated non-generic type. If #46477 is accepted, the
implementation will require proper representation of alias
types.

Change-Id: Ie85b923213a64f39837e56e38e14757458272b93
Reviewed-on: https://go-review.googlesource.com/c/go/+/346294
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/decl.go
src/cmd/compile/internal/types2/testdata/check/typeinst.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue39768.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue47968.go2
src/cmd/compile/internal/types2/typexpr.go
test/typeparam/aliasimp.dir/main.go

index d7a33546aa4478391e33a86f442a1131002f4ae6..b61d282b143922852960c3f746ef8e12930726e7 100644 (file)
@@ -555,7 +555,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
                }
 
                obj.typ = Typ[Invalid]
-               rhs = check.anyType(tdecl.Type)
+               rhs = check.varType(tdecl.Type)
                obj.typ = rhs
                return
        }
index 0d628cb9d06996e1dd35418e328829119508a72a..3fab2cb9ad2d981c2db54ac1854ad5a4bc2df0b0 100644 (file)
@@ -17,13 +17,15 @@ type T2[P any] struct {
 
 type List[P any] []P
 
-// Alias type declarations cannot have type parameters. Syntax error.
+// Alias type declarations cannot have type parameters.
+// Issue #46477 proposses to change that.
 type A1[P any] = /* ERROR cannot be alias */ P
 
-// But an alias may refer to a generic, uninstantiated type.
-type A2 = List
+// Pending clarification of #46477 we disallow aliases
+// of generic types.
+type A2 = List // ERROR cannot use generic type
 var _ A2[int]
-var _ A2 /* ERROR without instantiation */
+var _ A2
 
 type A3 = List[int]
 var _ A3
index abac141d7f08dd359a26ba18c36b696d7970d40a..fb522733e0b83f0e86b388a561f458514ee15f3c 100644 (file)
@@ -5,9 +5,9 @@
 package p
 
 type T[P any] P
-type A = T
+type A = T  // ERROR cannot use generic type
 var x A[int]
-var _ A /* ERROR cannot use generic type */
+var _ A
 
 type B = T[int]
 var y B = x
@@ -16,5 +16,5 @@ var _ B /* ERROR not a generic type */ [int]
 // test case from issue
 
 type Vector[T any] []T
-type VectorAlias = Vector
+type VectorAlias = Vector // ERROR cannot use generic type
 var v Vector[int]
index bbbe6805f2dd330c469d21072301906d5e73599c..711e50a55a1d5eeb9661ff259a03ea78618dd82e 100644 (file)
@@ -8,7 +8,7 @@ type T[P any] struct{}
 
 func (T[P]) m1()
 
-type A1 = T
+type A1 = T // ERROR cannot use generic type
 
 func (A1[P]) m2() {}
 
index 73b143ce1b15d71fe0168408685d5307fca30e1d..f3db3bbba936014ac47d26c1c2e7ad6fdf09a894 100644 (file)
@@ -38,12 +38,15 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *Named, wantType boo
                }
                return
        case universeAny, universeComparable:
-               // complain if necessary but keep going
+               // complain if necessary
                if !check.allowVersion(check.pkg, 1, 18) {
-                       check.softErrorf(e, "undeclared name: %s (requires version go1.18 or later)", e.Value)
-               } else if obj == universeAny {
+                       check.errorf(e, "undeclared name: %s (requires version go1.18 or later)", e.Value)
+                       return // avoid follow-on errors
+               }
+               if obj == universeAny {
                        // If we allow "any" for general use, this if-statement can be removed (issue #33232).
                        check.softErrorf(e, "cannot use any outside constraint position")
+                       // ok to continue
                }
        }
        check.recordUse(e, obj)
@@ -159,15 +162,6 @@ func (check *Checker) varType(e syntax.Expr) Type {
        return typ
 }
 
-// anyType type-checks the type expression e and returns its type, or Typ[Invalid].
-// The type may be generic or instantiated.
-func (check *Checker) anyType(e syntax.Expr) Type {
-       typ := check.typInternal(e, nil)
-       assert(isTyped(typ))
-       check.recordTypeAndValue(e, typexpr, typ, nil)
-       return typ
-}
-
 // definedType is like typ but also accepts a type name def.
 // If def != nil, e is the type specification for the defined type def, declared
 // in a type declaration, and def.underlying will be set to the type of e before
index 221a6c758dcf4a1dfe8c48eb1b0c41aaa497db1b..24ce95472f4ab4c2f041730b07b08c74f7186f0a 100644 (file)
@@ -10,16 +10,18 @@ type R[T any] struct {
        F T
 }
 
-type S = R
+// type S = R // disallowed for now
 
 type Sint = R[int]
 
-type Simp = a.Rimp
+// type Simp = a.Rimp // disallowed for now
 
-type SimpString Simp[string]
+// type SimpString Simp[string] // disallowed for now
+type SimpString a.Rimp[string]
 
 func main() {
-       var s S[int]
+       // var s S[int] // disallowed for now
+       var s R[int]
        if s.F != 0 {
                panic(s.F)
        }
@@ -27,7 +29,8 @@ func main() {
        if s2.F != 0 {
                panic(s2.F)
        }
-       var s3 Simp[string]
+       // var s3 Simp[string] // disallowed for now
+       var s3 a.Rimp[string]
        if s3.F != "" {
                panic(s3.F)
        }