1
0
mirror of https://github.com/golang/go synced 2024-11-26 17:07:09 -07:00

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>
This commit is contained in:
Robert Findley 2021-08-16 16:01:42 -04:00
parent 4d00fcbc43
commit e49775e057
2 changed files with 26 additions and 25 deletions

View File

@ -25,12 +25,12 @@ import (
// Any methods attached to a *Named are simply copied; they are not // Any methods attached to a *Named are simply copied; they are not
// instantiated. // instantiated.
func (check *Checker) Instantiate(pos token.Pos, typ Type, targs []Type, posList []token.Pos, verify bool) (res Type) { 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) { switch t := typ.(type) {
case *Named: case *Named:
return check.instantiateLazy(pos, t, targs, posList, verify) inst = check.instantiateLazy(pos, t, targs)
case *Signature: case *Signature:
tparams = t.TParams().list() tparams := t.TParams().list()
defer func() { defer func() {
// If we had an unexpected failure somewhere don't panic below when // If we had an unexpected failure somewhere don't panic below when
// asserting res.(*Signature). Check for *Signature in case Typ[Invalid] // 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. // anymore; we need to set tparams to nil.
res.(*Signature).tparams = nil res.(*Signature).tparams = nil
}() }()
inst = check.instantiate(pos, typ, tparams, targs, nil)
default: default:
// only types and functions can be generic // only types and functions can be generic
panic(fmt.Sprintf("%v: cannot instantiate %v", pos, typ)) panic(fmt.Sprintf("%v: cannot instantiate %v", pos, typ))
} }
inst := check.instantiate(pos, typ, tparams, targs, nil)
if verify { if verify {
if check == nil {
panic("cannot have nil Checker if verifying constraints")
}
assert(len(posList) <= len(targs)) 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) { if len(tparams) == len(targs) {
check.verify(pos, tparams, targs, posList) check.verify(pos, tparams, targs, posList)
} }
})
} }
return inst 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 // instantiateLazy avoids actually instantiating the type until needed. typ
// must be a *Named type. // must be a *Named type.
func (check *Checker) instantiateLazy(pos token.Pos, orig *Named, targs []Type, posList []token.Pos, verify bool) Type { func (check *Checker) instantiateLazy(pos token.Pos, orig *Named, targs []Type) 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)
})
}
}
h := instantiatedHash(orig, targs) h := instantiatedHash(orig, targs)
if check != nil { if check != nil {
// typ may already have been instantiated with identical type arguments. In // 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) { 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) smap := makeSubstMap(tparams, targs)
for i, tname := range tparams { for i, tname := range tparams {
// best position for error reporting // best position for error reporting

View File

@ -433,7 +433,7 @@ func (check *Checker) instantiatedType(x ast.Expr, targsx []ast.Expr, def *Named
posList[i] = arg.Pos() 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) def.setUnderlying(typ)
// make sure we check instantiation works at least once // make sure we check instantiation works at least once