mirror of
https://github.com/golang/go
synced 2024-11-23 00:40:08 -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:
parent
4d00fcbc43
commit
e49775e057
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user