Skip to content

Commit 986f8ea

Browse files
committed
cmd/compile/internal/types2: minor cleanup of instantiation
This is a clean port of CL 349429 from go/types to types2 with minor adjustments for types2 names. Change-Id: Ie6a39a01f074acb9e6565ffacb34c94666ae9a95 Reviewed-on: https://go-review.googlesource.com/c/go/+/349999 Trust: Robert Griesemer <[email protected]> Run-TryBot: Robert Griesemer <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent d1fd3eb commit 986f8ea

File tree

2 files changed

+29
-41
lines changed

2 files changed

+29
-41
lines changed

src/cmd/compile/internal/types2/named.go

+22-16
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,21 @@ func (n *Named) setUnderlying(typ Type) {
219219
}
220220
}
221221

222+
// bestEnv returns the best available environment. In order of preference:
223+
// - the given env, if non-nil
224+
// - the Checker env, if check is non-nil
225+
// - a new environment
226+
func (check *Checker) bestEnv(env *Environment) *Environment {
227+
if env != nil {
228+
return env
229+
}
230+
if check != nil {
231+
assert(check.conf.Environment != nil)
232+
return check.conf.Environment
233+
}
234+
return NewEnvironment()
235+
}
236+
222237
// expandNamed ensures that the underlying type of n is instantiated.
223238
// The underlying type will be Typ[Invalid] if there was an error.
224239
func expandNamed(env *Environment, n *Named, instPos syntax.Pos) (tparams *TypeParamList, underlying Type, methods []*Func) {
@@ -227,24 +242,15 @@ func expandNamed(env *Environment, n *Named, instPos syntax.Pos) (tparams *TypeP
227242
check := n.check
228243

229244
if check.validateTArgLen(instPos, n.orig.tparams.Len(), n.targs.Len()) {
230-
// TODO(rfindley): handling an optional Checker and Environment here (and
231-
// in subst) feels overly complicated. Can we simplify?
232-
if env == nil {
233-
if check != nil {
234-
env = check.conf.Environment
235-
} else {
236-
// If we're instantiating lazily, we might be outside the scope of a
237-
// type-checking pass. In that case we won't have a pre-existing
238-
// environment, but don't want to create a duplicate of the current
239-
// instance in the process of expansion.
240-
env = NewEnvironment()
241-
}
242-
h := env.TypeHash(n.orig, n.targs.list())
243-
// ensure that an instance is recorded for h to avoid infinite recursion.
244-
env.typeForHash(h, n)
245-
}
245+
// We must always have an env, to avoid infinite recursion.
246+
env = check.bestEnv(env)
247+
h := env.TypeHash(n.orig, n.targs.list())
248+
// ensure that an instance is recorded for h to avoid infinite recursion.
249+
env.typeForHash(h, n)
250+
246251
smap := makeSubstMap(n.orig.tparams.list(), n.targs.list())
247252
underlying = n.check.subst(instPos, n.orig.underlying, smap, env)
253+
248254
for i := 0; i < n.orig.NumMethods(); i++ {
249255
origm := n.orig.Method(i)
250256

src/cmd/compile/internal/types2/subst.go

+7-25
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,12 @@ func (check *Checker) subst(pos syntax.Pos, typ Type, smap substMap, env *Enviro
5252
}
5353

5454
// general case
55-
var subst subster
56-
subst.pos = pos
57-
subst.smap = smap
58-
59-
if check != nil {
60-
subst.check = check
61-
if env == nil {
62-
env = check.conf.Environment
63-
}
64-
}
65-
if env == nil {
66-
// If we don't have a *Checker and its global type map,
67-
// use a local version. Besides avoiding duplicate work,
68-
// the type map prevents infinite recursive substitution
69-
// for recursive types (example: type T[P any] *T[P]).
70-
env = NewEnvironment()
55+
subst := subster{
56+
pos: pos,
57+
smap: smap,
58+
check: check,
59+
env: check.bestEnv(env),
7160
}
72-
subst.env = env
73-
7461
return subst.typ(typ)
7562
}
7663

@@ -227,20 +214,15 @@ func (subst *subster) typ(typ Type) Type {
227214
// recursion. The position used here is irrelevant because validation only
228215
// occurs on t (we don't call validType on named), but we use subst.pos to
229216
// help with debugging.
230-
named := subst.check.instance(subst.pos, t.orig, newTArgs, subst.env).(*Named)
231-
// TODO(rfindley): we probably don't need to resolve here. Investigate if
232-
// this can be removed.
233-
named.resolve(subst.env)
234-
assert(named.underlying != nil)
217+
t.orig.resolve(subst.env)
218+
return subst.check.instance(subst.pos, t.orig, newTArgs, subst.env)
235219

236220
// Note that if we were to expose substitution more generally (not just in
237221
// the context of a declaration), we'd have to substitute in
238222
// named.underlying as well.
239223
//
240224
// But this is unnecessary for now.
241225

242-
return named
243-
244226
case *TypeParam:
245227
return subst.smap.lookup(t)
246228

0 commit comments

Comments
 (0)