]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types: simplify under() and fix a crash
authorRobert Findley <rfindley@google.com>
Thu, 18 Nov 2021 00:20:52 +0000 (19:20 -0500)
committerRobert Findley <rfindley@google.com>
Thu, 18 Nov 2021 02:15:36 +0000 (02:15 +0000)
This is a port of CL 363665 from types2 to go/types.

Change-Id: I20c4e20ab97f1e4de66a29095dc4a9b160810fe5
Reviewed-on: https://go-review.googlesource.com/c/go/+/364897
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>
src/go/types/lookup.go
src/go/types/testdata/check/cycles.src
src/go/types/type.go
src/go/types/typexpr.go

index 1462d30b309d43ea3624455ca5e7ab662bf47250..e3c43a94f7156d8dd22208be275550f58c0a9dd0 100644 (file)
@@ -469,6 +469,13 @@ func (check *Checker) assertableTo(V *Interface, T Type) (method, wrongType *Fun
 // Otherwise it returns (typ, false).
 func deref(typ Type) (Type, bool) {
        if p, _ := typ.(*Pointer); p != nil {
+               // p.base should never be nil, but be conservative
+               if p.base == nil {
+                       if debug {
+                               panic("pointer with nil base type (possibly due to an invalid cyclic declaration)")
+                       }
+                       return Typ[Invalid], true
+               }
                return p.base, true
        }
        return typ, false
index 218b4cad6abe6b4fdf6eb57d3f9c07f8274d078d..27b6111822948bc0556afdd8096903f8eb0c92bc 100644 (file)
@@ -45,6 +45,7 @@ type (
 
        // pointers
        P0 *P0
+       PP *struct{ PP.f /* ERROR no field or method f */ }
 
        // functions
        F0 func(F0)
index 97de5e49d1ed08cbc02be381ea6841394684ee39..6611c25f2533a7a10d89e1a4209051955603781a 100644 (file)
@@ -21,13 +21,10 @@ type Type interface {
 // under must only be called when a type is known
 // to be fully set up.
 func under(t Type) Type {
-       switch t := t.(type) {
-       case *Named:
+       if t, _ := t.(*Named); t != nil {
                return t.under()
-       case *TypeParam:
-               return t.iface()
        }
-       return t
+       return t.Underlying()
 }
 
 // If x and y are identical, match returns x.
index c6ab7cd564f23342b086b984715fe60b12ef618c..5664d8175fda322244a734422a44f9fc002fb661 100644 (file)
@@ -308,6 +308,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
 
        case *ast.StarExpr:
                typ := new(Pointer)
+               typ.base = Typ[Invalid] // avoid nil base in invalid recursive type declaration
                def.setUnderlying(typ)
                typ.base = check.varType(e.X)
                return typ