aboutsummaryrefslogtreecommitdiff
path: root/src/go
diff options
context:
space:
mode:
authorRobert Findley <rfindley@google.com>2021-08-16 16:01:42 -0400
committerRobert Findley <rfindley@google.com>2021-08-20 18:45:05 +0000
commite49775e0579891479888a514c82cf6eea123763f (patch)
tree11557821ce2f298cca25193a6c87dfbc85c2ceb5 /src/go
parent4d00fcbc4303bca38ecfc1c8a07661089496c1ab (diff)
downloadgo-e49775e0579891479888a514c82cf6eea123763f.tar.gz
go-e49775e0579891479888a514c82cf6eea123763f.zip
go/types: consolidate verification logic
This is a straightforward port of CL 342149 to go/types. Change-Id: I468c5154b7545b7816bb3f240b8db91e7a1fd3f6 Reviewed-on: https://go-review.googlesource.com/c/go/+/342488 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>
Diffstat (limited to 'src/go')
-rw-r--r--src/go/types/instantiate.go49
-rw-r--r--src/go/types/typexpr.go2
2 files changed, 26 insertions, 25 deletions
diff --git a/src/go/types/instantiate.go b/src/go/types/instantiate.go
index 37184cb0ab..eeb9b03050 100644
--- a/src/go/types/instantiate.go
+++ b/src/go/types/instantiate.go
@@ -25,12 +25,12 @@ import (
// Any methods attached to a *Named are simply copied; they are not
// instantiated.
func (check *Checker) Instantiate(pos token.Pos, typ Type, targs []Type, posList []token.Pos, verify bool) (res Type) {
- var tparams []*TypeName
+ var inst Type
switch t := typ.(type) {
case *Named:
- return check.instantiateLazy(pos, t, targs, posList, verify)
+ inst = check.instantiateLazy(pos, t, targs)
case *Signature:
- tparams = t.TParams().list()
+ tparams := t.TParams().list()
defer func() {
// If we had an unexpected failure somewhere don't panic below when
// asserting res.(*Signature). Check for *Signature in case Typ[Invalid]
@@ -49,18 +49,35 @@ func (check *Checker) Instantiate(pos token.Pos, typ Type, targs []Type, posList
// anymore; we need to set tparams to nil.
res.(*Signature).tparams = nil
}()
+ inst = check.instantiate(pos, typ, tparams, targs, nil)
default:
// only types and functions can be generic
panic(fmt.Sprintf("%v: cannot instantiate %v", pos, typ))
}
- inst := check.instantiate(pos, typ, tparams, targs, nil)
if verify {
- assert(len(posList) <= len(targs))
- if len(tparams) == len(targs) {
- check.verify(pos, tparams, targs, posList)
+ if check == nil {
+ panic("cannot have nil Checker if verifying constraints")
}
+ assert(len(posList) <= len(targs))
+ check.later(func() {
+ // Collect tparams again because lazily loaded *Named types may not have
+ // had tparams set up above.
+ var tparams []*TypeName
+ switch t := typ.(type) {
+ case *Named:
+ tparams = t.TParams().list()
+ case *Signature:
+ tparams = t.TParams().list()
+ }
+ // Avoid duplicate errors; instantiate will have complained if tparams
+ // and targs do not have the same length.
+ if len(tparams) == len(targs) {
+ check.verify(pos, tparams, targs, posList)
+ }
+ })
}
+
return inst
}
@@ -102,20 +119,7 @@ func (check *Checker) instantiate(pos token.Pos, typ Type, tparams []*TypeName,
// instantiateLazy avoids actually instantiating the type until needed. typ
// must be a *Named type.
-func (check *Checker) instantiateLazy(pos token.Pos, orig *Named, targs []Type, posList []token.Pos, verify bool) Type {
- if verify {
- if check == nil {
- // Provide a more useful panic instead of panicking at check.later below.
- panic("cannot have nil Checker if verifying constraints")
- }
- assert(len(posList) <= len(targs))
- if orig.TParams().Len() == len(targs) {
- check.later(func() {
- check.verify(pos, orig.tparams.list(), targs, posList)
- })
- }
- }
-
+func (check *Checker) instantiateLazy(pos token.Pos, orig *Named, targs []Type) Type {
h := instantiatedHash(orig, targs)
if check != nil {
// typ may already have been instantiated with identical type arguments. In
@@ -138,9 +142,6 @@ func (check *Checker) instantiateLazy(pos token.Pos, orig *Named, targs []Type,
}
func (check *Checker) verify(pos token.Pos, tparams []*TypeName, targs []Type, posList []token.Pos) {
- if check == nil {
- panic("cannot have nil Checker if verifying constraints")
- }
smap := makeSubstMap(tparams, targs)
for i, tname := range tparams {
// best position for error reporting
diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go
index 8af6570072..def5871ce7 100644
--- a/src/go/types/typexpr.go
+++ b/src/go/types/typexpr.go
@@ -433,7 +433,7 @@ func (check *Checker) instantiatedType(x ast.Expr, targsx []ast.Expr, def *Named
posList[i] = arg.Pos()
}
- typ := check.instantiateLazy(x.Pos(), base, targs, posList, true)
+ typ := check.Instantiate(x.Pos(), base, targs, posList, true)
def.setUnderlying(typ)
// make sure we check instantiation works at least once