mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile/internal/types2: remove targs from substMap
Now that we always capture targs when constructing an instance, we no longer need to pass them via the substMap. This simplifies the code and resolves a TODO. Change-Id: I592dccaeb89c7cc31ac037d919137bb762820365 Reviewed-on: https://go-review.googlesource.com/c/go/+/341859 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
456759b246
commit
b2253c8041
2 changed files with 34 additions and 51 deletions
|
|
@ -152,7 +152,7 @@ func (check *Checker) verify(pos syntax.Pos, tparams []*TypeName, targs []Type,
|
||||||
// parameter tpar (after any of its type parameters have been substituted through smap).
|
// parameter tpar (after any of its type parameters have been substituted through smap).
|
||||||
// A suitable error is reported if the result is false.
|
// A suitable error is reported if the result is false.
|
||||||
// TODO(gri) This should be a method of interfaces or type sets.
|
// TODO(gri) This should be a method of interfaces or type sets.
|
||||||
func (check *Checker) satisfies(pos syntax.Pos, targ Type, tpar *TypeParam, smap *substMap) bool {
|
func (check *Checker) satisfies(pos syntax.Pos, targ Type, tpar *TypeParam, smap substMap) bool {
|
||||||
iface := tpar.iface()
|
iface := tpar.iface()
|
||||||
if iface.Empty() {
|
if iface.Empty() {
|
||||||
return true // no type bound
|
return true // no type bound
|
||||||
|
|
|
||||||
|
|
@ -9,38 +9,27 @@ package types2
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"cmd/compile/internal/syntax"
|
"cmd/compile/internal/syntax"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type substMap struct {
|
type substMap map[*TypeParam]Type
|
||||||
// The targs field is currently needed for *Named type substitution.
|
|
||||||
// TODO(gri) rewrite that code, get rid of this field, and make this
|
|
||||||
// struct just the map (proj)
|
|
||||||
targs []Type
|
|
||||||
proj map[*TypeParam]Type
|
|
||||||
}
|
|
||||||
|
|
||||||
// makeSubstMap creates a new substitution map mapping tpars[i] to targs[i].
|
// makeSubstMap creates a new substitution map mapping tpars[i] to targs[i].
|
||||||
// If targs[i] is nil, tpars[i] is not substituted.
|
// If targs[i] is nil, tpars[i] is not substituted.
|
||||||
func makeSubstMap(tpars []*TypeName, targs []Type) *substMap {
|
func makeSubstMap(tpars []*TypeName, targs []Type) substMap {
|
||||||
assert(len(tpars) == len(targs))
|
assert(len(tpars) == len(targs))
|
||||||
proj := make(map[*TypeParam]Type, len(tpars))
|
proj := make(substMap, len(tpars))
|
||||||
for i, tpar := range tpars {
|
for i, tpar := range tpars {
|
||||||
proj[tpar.typ.(*TypeParam)] = targs[i]
|
proj[tpar.typ.(*TypeParam)] = targs[i]
|
||||||
}
|
}
|
||||||
return &substMap{targs, proj}
|
return proj
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *substMap) String() string {
|
func (m substMap) empty() bool {
|
||||||
return fmt.Sprintf("%s", m.proj)
|
return len(m) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *substMap) empty() bool {
|
func (m substMap) lookup(tpar *TypeParam) Type {
|
||||||
return len(m.proj) == 0
|
if t := m[tpar]; t != nil {
|
||||||
}
|
|
||||||
|
|
||||||
func (m *substMap) lookup(tpar *TypeParam) Type {
|
|
||||||
if t := m.proj[tpar]; t != nil {
|
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
return tpar
|
return tpar
|
||||||
|
|
@ -53,7 +42,7 @@ func (m *substMap) lookup(tpar *TypeParam) Type {
|
||||||
// from the incoming type.
|
// from the incoming type.
|
||||||
//
|
//
|
||||||
// If the given typMap is nil and check is non-nil, check.typMap is used.
|
// If the given typMap is nil and check is non-nil, check.typMap is used.
|
||||||
func (check *Checker) subst(pos syntax.Pos, typ Type, smap *substMap, typMap map[string]*Named) Type {
|
func (check *Checker) subst(pos syntax.Pos, typ Type, smap substMap, typMap map[string]*Named) Type {
|
||||||
if smap.empty() {
|
if smap.empty() {
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +80,7 @@ func (check *Checker) subst(pos syntax.Pos, typ Type, smap *substMap, typMap map
|
||||||
|
|
||||||
type subster struct {
|
type subster struct {
|
||||||
pos syntax.Pos
|
pos syntax.Pos
|
||||||
smap *substMap
|
smap substMap
|
||||||
check *Checker // nil if called via Instantiate
|
check *Checker // nil if called via Instantiate
|
||||||
typMap map[string]*Named
|
typMap map[string]*Named
|
||||||
}
|
}
|
||||||
|
|
@ -199,40 +188,34 @@ func (subst *subster) typ(typ Type) Type {
|
||||||
return t // type is not parameterized
|
return t // type is not parameterized
|
||||||
}
|
}
|
||||||
|
|
||||||
var new_targs []Type
|
var newTArgs []Type
|
||||||
|
assert(len(t.targs) == t.TParams().Len())
|
||||||
|
|
||||||
if len(t.targs) > 0 {
|
// already instantiated
|
||||||
// already instantiated
|
dump(">>> %s already instantiated", t)
|
||||||
dump(">>> %s already instantiated", t)
|
// For each (existing) type argument targ, determine if it needs
|
||||||
assert(len(t.targs) == t.TParams().Len())
|
// to be substituted; i.e., if it is or contains a type parameter
|
||||||
// For each (existing) type argument targ, determine if it needs
|
// that has a type argument for it.
|
||||||
// to be substituted; i.e., if it is or contains a type parameter
|
for i, targ := range t.targs {
|
||||||
// that has a type argument for it.
|
dump(">>> %d targ = %s", i, targ)
|
||||||
for i, targ := range t.targs {
|
new_targ := subst.typ(targ)
|
||||||
dump(">>> %d targ = %s", i, targ)
|
if new_targ != targ {
|
||||||
new_targ := subst.typ(targ)
|
dump(">>> substituted %d targ %s => %s", i, targ, new_targ)
|
||||||
if new_targ != targ {
|
if newTArgs == nil {
|
||||||
dump(">>> substituted %d targ %s => %s", i, targ, new_targ)
|
newTArgs = make([]Type, t.TParams().Len())
|
||||||
if new_targs == nil {
|
copy(newTArgs, t.targs)
|
||||||
new_targs = make([]Type, t.TParams().Len())
|
|
||||||
copy(new_targs, t.targs)
|
|
||||||
}
|
|
||||||
new_targs[i] = new_targ
|
|
||||||
}
|
}
|
||||||
|
newTArgs[i] = new_targ
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if new_targs == nil {
|
if newTArgs == nil {
|
||||||
dump(">>> nothing to substitute in %s", t)
|
dump(">>> nothing to substitute in %s", t)
|
||||||
return t // nothing to substitute
|
return t // nothing to substitute
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// not yet instantiated
|
|
||||||
dump(">>> first instantiation of %s", t)
|
|
||||||
new_targs = subst.smap.targs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// before creating a new named type, check if we have this one already
|
// before creating a new named type, check if we have this one already
|
||||||
h := instantiatedHash(t, new_targs)
|
h := instantiatedHash(t, newTArgs)
|
||||||
dump(">>> new type hash: %s", h)
|
dump(">>> new type hash: %s", h)
|
||||||
if named, found := subst.typMap[h]; found {
|
if named, found := subst.typMap[h]; found {
|
||||||
dump(">>> found %s", named)
|
dump(">>> found %s", named)
|
||||||
|
|
@ -243,12 +226,12 @@ func (subst *subster) typ(typ Type) Type {
|
||||||
tname := NewTypeName(subst.pos, t.obj.pkg, t.obj.name, nil)
|
tname := NewTypeName(subst.pos, t.obj.pkg, t.obj.name, nil)
|
||||||
t.load()
|
t.load()
|
||||||
named := subst.check.newNamed(tname, t.orig, t.underlying, t.TParams(), t.methods) // method signatures are updated lazily
|
named := subst.check.newNamed(tname, t.orig, t.underlying, t.TParams(), t.methods) // method signatures are updated lazily
|
||||||
named.targs = new_targs
|
named.targs = newTArgs
|
||||||
subst.typMap[h] = named
|
subst.typMap[h] = named
|
||||||
t.expand(subst.typMap) // must happen after typMap update to avoid infinite recursion
|
t.expand(subst.typMap) // must happen after typMap update to avoid infinite recursion
|
||||||
|
|
||||||
// do the substitution
|
// do the substitution
|
||||||
dump(">>> subst %s with %s (new: %s)", t.underlying, subst.smap, new_targs)
|
dump(">>> subst %s with %s (new: %s)", t.underlying, subst.smap, newTArgs)
|
||||||
named.underlying = subst.typOrNil(t.underlying)
|
named.underlying = subst.typOrNil(t.underlying)
|
||||||
dump(">>> underlying: %v", named.underlying)
|
dump(">>> underlying: %v", named.underlying)
|
||||||
assert(named.underlying != nil)
|
assert(named.underlying != nil)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue