mirror of
https://github.com/golang/go
synced 2024-11-17 21:04:43 -07:00
go/types: delay union element checks
This is a clean port of CL 351969 from types2 to go/types with a minor adjustment for error handling (provide an error code). For #46461. Change-Id: I493dde12d8ccf86aa33f4913ac6e82f2eb459088 Reviewed-on: https://go-review.googlesource.com/c/go/+/351971 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
4dd5f0994f
commit
0f1159bf54
@ -4,8 +4,17 @@
|
|||||||
|
|
||||||
package p
|
package p
|
||||||
|
|
||||||
|
// test case 1
|
||||||
type T[U interface{ M() T[U] }] int
|
type T[U interface{ M() T[U] }] int
|
||||||
|
|
||||||
type X int
|
type X int
|
||||||
|
|
||||||
func (X) M() T[X] { return 0 }
|
func (X) M() T[X] { return 0 }
|
||||||
|
|
||||||
|
// test case 2
|
||||||
|
type A[T interface{ A[T] }] interface{}
|
||||||
|
|
||||||
|
// test case 3
|
||||||
|
type A2[U interface{ A2[U] }] interface{ M() A2[U] }
|
||||||
|
|
||||||
|
type I interface{ A2[I]; M() A2[I] }
|
||||||
|
@ -289,8 +289,8 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
|
|||||||
terms = tset.terms
|
terms = tset.terms
|
||||||
case *TypeParam:
|
case *TypeParam:
|
||||||
// Embedding stand-alone type parameters is not permitted.
|
// Embedding stand-alone type parameters is not permitted.
|
||||||
// This case is handled during union parsing.
|
// Union parsing reports a (delayed) error, so we can ignore this entry.
|
||||||
unreachable()
|
continue
|
||||||
default:
|
default:
|
||||||
if typ == Typ[Invalid] {
|
if typ == Typ[Invalid] {
|
||||||
continue
|
continue
|
||||||
@ -370,8 +370,8 @@ func computeUnionTypeSet(check *Checker, pos token.Pos, utyp *Union) *_TypeSet {
|
|||||||
terms = computeInterfaceTypeSet(check, pos, u).terms
|
terms = computeInterfaceTypeSet(check, pos, u).terms
|
||||||
case *TypeParam:
|
case *TypeParam:
|
||||||
// A stand-alone type parameters is not permitted as union term.
|
// A stand-alone type parameters is not permitted as union term.
|
||||||
// This case is handled during union parsing.
|
// Union parsing reports a (delayed) error, so we can ignore this entry.
|
||||||
unreachable()
|
continue
|
||||||
default:
|
default:
|
||||||
if t.typ == Typ[Invalid] {
|
if t.typ == Typ[Invalid] {
|
||||||
continue
|
continue
|
||||||
|
@ -57,7 +57,10 @@ func parseUnion(check *Checker, tlist []ast.Expr) Type {
|
|||||||
for _, x := range tlist {
|
for _, x := range tlist {
|
||||||
tilde, typ := parseTilde(check, x)
|
tilde, typ := parseTilde(check, x)
|
||||||
if len(tlist) == 1 && !tilde {
|
if len(tlist) == 1 && !tilde {
|
||||||
return typ // single type (optimization)
|
// Single type. Ok to return early because all relevant
|
||||||
|
// checks have been performed in parseTilde (no need to
|
||||||
|
// run through term validity check below).
|
||||||
|
return typ
|
||||||
}
|
}
|
||||||
if len(terms) >= maxTermCount {
|
if len(terms) >= maxTermCount {
|
||||||
check.errorf(x, _Todo, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
|
check.errorf(x, _Todo, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
|
||||||
@ -126,11 +129,16 @@ func parseTilde(check *Checker, x ast.Expr) (tilde bool, typ Type) {
|
|||||||
tilde = true
|
tilde = true
|
||||||
}
|
}
|
||||||
typ = check.typ(x)
|
typ = check.typ(x)
|
||||||
// embedding stand-alone type parameters is not permitted (issue #47127).
|
// Embedding stand-alone type parameters is not permitted (issue #47127).
|
||||||
|
// Do this check later because it requires computation of the underlying type (see also issue #46461).
|
||||||
|
// Note: If an underlying type cannot be a type parameter, the call to
|
||||||
|
// under() will not be needed and then we don't need to delay this
|
||||||
|
// check to later and could return Typ[Invalid] instead.
|
||||||
|
check.later(func() {
|
||||||
if _, ok := under(typ).(*TypeParam); ok {
|
if _, ok := under(typ).(*TypeParam); ok {
|
||||||
check.error(x, _Todo, "cannot embed a type parameter")
|
check.error(x, _Todo, "cannot embed a type parameter")
|
||||||
typ = Typ[Invalid]
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user