cmd/compile/internal/types2: simplify Named.under

Remove some unnecessary logic from Named.under:
 - no need to have special handling for Typ[Invalid]: this is the same
   as other cases where the underlying type is resolved.
 - use Underlying() to get the loaded and expanded underlying
 - no need for special handling of the first iteration

Change-Id: I2029711f51fa9eaaee11debadd55974a1376a980
Reviewed-on: https://go-review.googlesource.com/c/go/+/341857
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>
This commit is contained in:
Rob Findley 2021-08-11 13:36:26 -04:00 committed by Robert Findley
parent 50f4ebbdd3
commit 2d250043b4

View file

@ -166,18 +166,13 @@ func (t *Named) String() string { return TypeString(t, nil) }
// is detected, the result is Typ[Invalid]. If a cycle is detected and // is detected, the result is Typ[Invalid]. If a cycle is detected and
// n0.check != nil, the cycle is reported. // n0.check != nil, the cycle is reported.
func (n0 *Named) under() Type { func (n0 *Named) under() Type {
n0.expand(nil) u := n0.Underlying()
u := n0.load().underlying
if u == Typ[Invalid] {
return u
}
// If the underlying type of a defined type is not a defined // If the underlying type of a defined type is not a defined
// (incl. instance) type, then that is the desired underlying // (incl. instance) type, then that is the desired underlying
// type. // type.
switch u.(type) { var n1 *Named
switch u1 := u.(type) {
case nil: case nil:
return Typ[Invalid] return Typ[Invalid]
default: default:
@ -185,6 +180,7 @@ func (n0 *Named) under() Type {
return u return u
case *Named: case *Named:
// handled below // handled below
n1 = u1
} }
if n0.check == nil { if n0.check == nil {
@ -194,43 +190,33 @@ func (n0 *Named) under() Type {
// Invariant: after this point n0 as well as any named types in its // Invariant: after this point n0 as well as any named types in its
// underlying chain should be set up when this function exits. // underlying chain should be set up when this function exits.
check := n0.check check := n0.check
n := n0
// If we can't expand u at this point, it is invalid. seen := make(map[*Named]int) // types that need their underlying resolved
n := asNamed(u) var path []Object // objects encountered, for cycle reporting
if n == nil {
n0.underlying = Typ[Invalid]
return n0.underlying
}
// Otherwise, follow the forward chain. loop:
seen := map[*Named]int{n0: 0}
path := []Object{n0.obj}
for { for {
u = n.load().underlying
if u == nil {
u = Typ[Invalid]
break
}
var n1 *Named
switch u1 := u.(type) {
case *Named:
u1.expand(nil)
n1 = u1
}
if n1 == nil {
break // end of chain
}
seen[n] = len(seen) seen[n] = len(seen)
path = append(path, n.obj) path = append(path, n.obj)
n = n1 n = n1
if i, ok := seen[n]; ok { if i, ok := seen[n]; ok {
// cycle // cycle
check.cycleError(path[i:]) check.cycleError(path[i:])
u = Typ[Invalid] u = Typ[Invalid]
break break
} }
u = n.Underlying()
switch u1 := u.(type) {
case nil:
u = Typ[Invalid]
break loop
default:
break loop
case *Named:
// Continue collecting *Named types in the chain.
n1 = u1
}
} }
for n := range seen { for n := range seen {