diff options
author | Robert Griesemer <gri@golang.org> | 2021-05-26 21:42:09 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2021-05-27 17:51:15 +0000 |
commit | 8c99e5db431c28ef563fc4980b05b26f82172864 (patch) | |
tree | 480c65e8cd68a9a62c4d6b4f80b597bff104f0db /src/cmd/compile/internal/types2/decl.go | |
parent | 963f33b03b88e2c010d6a9876c3f0cc8d1f36f2d (diff) | |
download | go-8c99e5db431c28ef563fc4980b05b26f82172864.tar.gz go-8c99e5db431c28ef563fc4980b05b26f82172864.zip |
[dev.typeparams] cmd/compile/internal/types2: ensure that Named.check is nilled out once it is expanded
This is a port of
- https://golang.org/cl/318849
- https://golang.org/cl/322974
For #45580.
Change-Id: Ie0700ed6c8d472305d5ba7ff97da1ae063152aa3
Reviewed-on: https://go-review.googlesource.com/c/go/+/323030
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/decl.go')
-rw-r--r-- | src/cmd/compile/internal/types2/decl.go | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/src/cmd/compile/internal/types2/decl.go b/src/cmd/compile/internal/types2/decl.go index 1333e4c0ec..aa70f3880b 100644 --- a/src/cmd/compile/internal/types2/decl.go +++ b/src/cmd/compile/internal/types2/decl.go @@ -523,15 +523,37 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init syntax.Expr) { // n0.check != nil, the cycle is reported. func (n0 *Named) under() Type { u := n0.underlying - if u == nil { - return Typ[Invalid] + + if u == Typ[Invalid] { + return u } // If the underlying type of a defined type is not a defined - // type, then that is the desired underlying type. + // (incl. instance) type, then that is the desired underlying + // type. + switch u.(type) { + case nil: + return Typ[Invalid] + default: + // common case + return u + case *Named, *instance: + // handled below + } + + if n0.check == nil { + panic("internal error: Named.check == nil but type is incomplete") + } + + // 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 + + // If we can't expand u at this point, it is invalid. n := asNamed(u) if n == nil { - return u // common case + n0.underlying = Typ[Invalid] + return n0.underlying } // Otherwise, follow the forward chain. @@ -543,7 +565,16 @@ func (n0 *Named) under() Type { u = Typ[Invalid] break } - n1 := asNamed(u) + var n1 *Named + switch u1 := u.(type) { + case *Named: + n1 = u1 + case *instance: + n1, _ = u1.expand().(*Named) + if n1 == nil { + u = Typ[Invalid] + } + } if n1 == nil { break // end of chain } @@ -554,11 +585,7 @@ func (n0 *Named) under() Type { if i, ok := seen[n]; ok { // cycle - // TODO(gri) revert this to a method on Checker. Having a possibly - // nil Checker on Named and TypeParam is too subtle. - if n0.check != nil { - n0.check.cycleError(path[i:]) - } + check.cycleError(path[i:]) u = Typ[Invalid] break } @@ -568,8 +595,8 @@ func (n0 *Named) under() Type { // We should never have to update the underlying type of an imported type; // those underlying types should have been resolved during the import. // Also, doing so would lead to a race condition (was issue #31749). - // Do this check always, not just in debug more (it's cheap). - if n0.check != nil && n.obj.pkg != n0.check.pkg { + // Do this check always, not just in debug mode (it's cheap). + if n.obj.pkg != check.pkg { panic("internal error: imported type with unresolved underlying type") } n.underlying = u |