@@ -219,6 +219,21 @@ func (n *Named) setUnderlying(typ Type) {
219
219
}
220
220
}
221
221
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
+
222
237
// expandNamed ensures that the underlying type of n is instantiated.
223
238
// The underlying type will be Typ[Invalid] if there was an error.
224
239
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
227
242
check := n .check
228
243
229
244
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
+
246
251
smap := makeSubstMap (n .orig .tparams .list (), n .targs .list ())
247
252
underlying = n .check .subst (instPos , n .orig .underlying , smap , env )
253
+
248
254
for i := 0 ; i < n .orig .NumMethods (); i ++ {
249
255
origm := n .orig .Method (i )
250
256
0 commit comments