1
0
mirror of https://github.com/golang/go synced 2024-11-14 07:00:21 -07:00

go/types: disallow aliases for generic types

This is a port of CL 346294 to go/types.

Change-Id: Ib70541a92e352c8df8123c8b82bb4eeedce3b89f
Reviewed-on: https://go-review.googlesource.com/c/go/+/346560
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
Robert Findley 2021-08-31 18:32:21 -04:00
parent 36ac2214fa
commit f4e24599dd
5 changed files with 17 additions and 21 deletions

View File

@ -603,7 +603,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
} }
obj.typ = Typ[Invalid] obj.typ = Typ[Invalid]
rhs = check.anyType(tdecl.Type) rhs = check.varType(tdecl.Type)
obj.typ = rhs obj.typ = rhs
return return
} }

View File

@ -17,13 +17,15 @@ type T2[P any] struct {
type List[P any] []P 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 type A1[P any] = /* ERROR cannot be alias */ P
// But an alias may refer to a generic, uninstantiated type. // Pending clarification of #46477 we disallow aliases
type A2 = List // of generic types.
type A2 = List // ERROR cannot use generic type
var _ A2[int] var _ A2[int]
var _ A2 /* ERROR without instantiation */ var _ A2
type A3 = List[int] type A3 = List[int]
var _ A3 var _ A3

View File

@ -5,9 +5,9 @@
package p package p
type T[P any] P type T[P any] P
type A = T type A = T // ERROR cannot use generic type
var x A[int] var x A[int]
var _ A /* ERROR cannot use generic type */ var _ A
type B = T[int] type B = T[int]
var y B = x var y B = x
@ -16,5 +16,5 @@ var _ B /* ERROR not a generic type */ [int]
// test case from issue // test case from issue
type Vector[T any] []T type Vector[T any] []T
type VectorAlias = Vector type VectorAlias = Vector // ERROR cannot use generic type
var v Vector[int] var v Vector[int]

View File

@ -8,7 +8,7 @@ type T[P any] struct{}
func (T[P]) m1() func (T[P]) m1()
type A1 = T type A1 = T // ERROR cannot use generic type
func (A1[P]) m2() {} func (A1[P]) m2() {}

View File

@ -36,12 +36,15 @@ func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, wantType bool)
} }
return return
case universeAny, universeComparable: case universeAny, universeComparable:
// complain if necessary but keep going // complain if necessary
if !check.allowVersion(check.pkg, 1, 18) { if !check.allowVersion(check.pkg, 1, 18) {
check.softErrorf(e, _UndeclaredName, "undeclared name: %s (requires version go1.18 or later)", e.Name) check.errorf(e, _UndeclaredName, "undeclared name: %s (requires version go1.18 or later)", e.Name)
} else if obj == universeAny { return // avoid follow-on errors
}
if obj == universeAny {
// If we allow "any" for general use, this if-statement can be removed (issue #33232). // If we allow "any" for general use, this if-statement can be removed (issue #33232).
check.softErrorf(e, _Todo, "cannot use any outside constraint position") check.softErrorf(e, _Todo, "cannot use any outside constraint position")
// ok to continue
} }
} }
check.recordUse(e, obj) check.recordUse(e, obj)
@ -155,15 +158,6 @@ func (check *Checker) varType(e ast.Expr) Type {
return typ 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 ast.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. // 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 // 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 // in a type declaration, and def.underlying will be set to the type of e before