mirror of
https://github.com/golang/go
synced 2024-11-26 14:36:52 -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:
parent
36ac2214fa
commit
f4e24599dd
@ -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
|
||||||
}
|
}
|
||||||
|
10
src/go/types/testdata/check/typeinst.go2
vendored
10
src/go/types/testdata/check/typeinst.go2
vendored
@ -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
|
||||||
|
@ -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]
|
||||||
|
@ -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() {}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user