mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile/internal/types2: consolidate verification logic
Change an internal call of instantiateLazy to call Instantiate, so that we can consolidate the logic for invoking verification. This made verification of signatures lazy, which is not necessary but should be harmless. Change-Id: I2e59b04ac859e08c2e2910ded3c183093d1e34a7 Reviewed-on: https://go-review.googlesource.com/c/go/+/342149 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:
parent
165ebd85a7
commit
8f0578ef39
2 changed files with 26 additions and 25 deletions
|
|
@ -26,12 +26,12 @@ import (
|
||||||
// instantiated.
|
// instantiated.
|
||||||
func (check *Checker) Instantiate(pos syntax.Pos, typ Type, targs []Type, posList []syntax.Pos, verify bool) (res Type) {
|
func (check *Checker) Instantiate(pos syntax.Pos, typ Type, targs []Type, posList []syntax.Pos, verify bool) (res Type) {
|
||||||
// TODO(gri) What is better here: work with TypeParams, or work with TypeNames?
|
// TODO(gri) What is better here: work with TypeParams, or work with TypeNames?
|
||||||
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]
|
||||||
|
|
@ -50,18 +50,35 @@ func (check *Checker) Instantiate(pos syntax.Pos, typ Type, targs []Type, posLis
|
||||||
// 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 {
|
||||||
assert(len(posList) <= len(targs))
|
if check == nil {
|
||||||
if len(tparams) == len(targs) {
|
panic("cannot have nil Checker if verifying constraints")
|
||||||
check.verify(pos, tparams, targs, posList)
|
|
||||||
}
|
}
|
||||||
|
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
|
return inst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,20 +118,7 @@ func (check *Checker) instantiate(pos syntax.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 syntax.Pos, orig *Named, targs []Type, posList []syntax.Pos, verify bool) Type {
|
func (check *Checker) instantiateLazy(pos syntax.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
|
||||||
|
|
@ -136,9 +140,6 @@ func (check *Checker) instantiateLazy(pos syntax.Pos, orig *Named, targs []Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (check *Checker) verify(pos syntax.Pos, tparams []*TypeName, targs []Type, posList []syntax.Pos) {
|
func (check *Checker) verify(pos syntax.Pos, tparams []*TypeName, targs []Type, posList []syntax.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
|
||||||
|
|
|
||||||
|
|
@ -444,7 +444,7 @@ func (check *Checker) instantiatedType(x syntax.Expr, targsx []syntax.Expr, def
|
||||||
posList[i] = syntax.StartPos(arg)
|
posList[i] = syntax.StartPos(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue