]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: simplify Named.under
authorRobert Findley <rfindley@google.com>
Mon, 16 Aug 2021 17:20:29 +0000 (13:20 -0400)
committerRobert Findley <rfindley@google.com>
Mon, 16 Aug 2021 18:44:48 +0000 (18:44 +0000)
This is a straighforward port of CL 341857 to go/types.

Change-Id: I3407676232b595662c1470627771a13263703061
Reviewed-on: https://go-review.googlesource.com/c/go/+/342479
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>

src/go/types/named.go

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