@@ -47,7 +47,6 @@ use ty::relate::{RelateResult, TypeRelation};
47
47
use traits:: PredicateObligations ;
48
48
49
49
use syntax:: ast;
50
- use syntax:: util:: small_vector:: SmallVector ;
51
50
use syntax_pos:: Span ;
52
51
53
52
#[ derive( Clone ) ]
@@ -174,6 +173,15 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
174
173
Glb :: new ( self , a_is_expected)
175
174
}
176
175
176
+ /// Here dir is either EqTo, SubtypeOf, or SupertypeOf. The
177
+ /// idea is that we should ensure that the type `a_ty` is equal
178
+ /// to, a subtype of, or a supertype of (respectively) the type
179
+ /// to which `b_vid` is bound.
180
+ ///
181
+ /// Since `b_vid` has not yet been instantiated with a type, we
182
+ /// will first instantiate `b_vid` with a *generalized* version
183
+ /// of `a_ty`. Generalization introduces other inference
184
+ /// variables wherever subtyping could occur.
177
185
pub fn instantiate ( & mut self ,
178
186
a_ty : Ty < ' tcx > ,
179
187
dir : RelationDir ,
@@ -183,109 +191,64 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
183
191
{
184
192
use self :: RelationDir :: * ;
185
193
186
- // We use SmallVector here instead of Vec because this code is hot and
187
- // it's rare that the stack length exceeds 1.
188
- let mut stack = SmallVector :: new ( ) ;
189
- stack. push ( ( a_ty, dir, b_vid) ) ;
190
- loop {
191
- // For each turn of the loop, we extract a tuple
192
- //
193
- // (a_ty, dir, b_vid)
194
- //
195
- // to relate. Here dir is either SubtypeOf or
196
- // SupertypeOf. The idea is that we should ensure that
197
- // the type `a_ty` is a subtype or supertype (respectively) of the
198
- // type to which `b_vid` is bound.
199
- //
200
- // If `b_vid` has not yet been instantiated with a type
201
- // (which is always true on the first iteration, but not
202
- // necessarily true on later iterations), we will first
203
- // instantiate `b_vid` with a *generalized* version of
204
- // `a_ty`. Generalization introduces other inference
205
- // variables wherever subtyping could occur (at time of
206
- // this writing, this means replacing free regions with
207
- // region variables).
208
- let ( a_ty, dir, b_vid) = match stack. pop ( ) {
209
- None => break ,
210
- Some ( e) => e,
211
- } ;
212
- // Get the actual variable that b_vid has been inferred to
213
- let ( b_vid, b_ty) = {
214
- let mut variables = self . infcx . type_variables . borrow_mut ( ) ;
215
- let b_vid = variables. root_var ( b_vid) ;
216
- ( b_vid, variables. probe_root ( b_vid) )
217
- } ;
218
-
219
- debug ! ( "instantiate(a_ty={:?} dir={:?} b_vid={:?})" ,
220
- a_ty,
221
- dir,
222
- b_vid) ;
223
-
224
- // Check whether `vid` has been instantiated yet. If not,
225
- // make a generalized form of `ty` and instantiate with
226
- // that.
227
- //
228
- // FIXME(#18653) -- we need to generalize nested type
229
- // variables too.
230
- let b_ty = match b_ty {
231
- Some ( t) => t, // ...already instantiated.
232
- None => { // ...not yet instantiated:
233
- // Generalize type if necessary.
234
- let generalized_ty = match dir {
235
- EqTo => self . generalize ( a_ty, b_vid, false ) ,
236
- SupertypeOf | SubtypeOf => self . generalize ( a_ty, b_vid, true ) ,
237
- } ?;
238
- debug ! ( "instantiate(a_ty={:?}, dir={:?}, \
239
- b_vid={:?}, generalized_ty={:?})",
240
- a_ty, dir, b_vid,
241
- generalized_ty) ;
242
- self . infcx . type_variables
243
- . borrow_mut ( )
244
- . instantiate ( b_vid, generalized_ty) ;
245
- generalized_ty
246
- }
247
- } ;
248
-
249
- // The original triple was `(a_ty, dir, b_vid)` -- now we have
250
- // resolved `b_vid` to `b_ty`, so apply `(a_ty, dir, b_ty)`:
251
- //
252
- // FIXME(#16847): This code is non-ideal because all these subtype
253
- // relations wind up attributed to the same spans. We need
254
- // to associate causes/spans with each of the relations in
255
- // the stack to get this right.
256
- match dir {
257
- EqTo => self . equate ( a_is_expected) . relate ( & a_ty, & b_ty) ,
258
- SubtypeOf => self . sub ( a_is_expected) . relate ( & a_ty, & b_ty) ,
259
- SupertypeOf => self . sub ( a_is_expected) . relate_with_variance (
260
- ty:: Contravariant , & a_ty, & b_ty) ,
261
- } ?;
262
- }
194
+ // Get the actual variable that b_vid has been inferred to
195
+ debug_assert ! ( self . infcx. type_variables. borrow_mut( ) . probe( b_vid) . is_none( ) ) ;
196
+
197
+ debug ! ( "instantiate(a_ty={:?} dir={:?} b_vid={:?})" , a_ty, dir, b_vid) ;
198
+
199
+ // Generalize type of `a_ty` appropriately depending on the
200
+ // direction. As an example, assume:
201
+ //
202
+ // - `a_ty == &'x ?1`, where `'x` is some free region and `?1` is an
203
+ // inference variable,
204
+ // - and `dir` == `SubtypeOf`.
205
+ //
206
+ // Then the generalized form `b_ty` would be `&'?2 ?3`, where
207
+ // `'?2` and `?3` are fresh region/type inference
208
+ // variables. (Down below, we will relate `a_ty <: b_ty`,
209
+ // adding constraints like `'x: '?2` and `?1 <: ?3`.)
210
+ let b_ty = self . generalize ( a_ty, b_vid, dir == EqTo ) ?;
211
+ debug ! ( "instantiate(a_ty={:?}, dir={:?}, b_vid={:?}, generalized b_ty={:?})" ,
212
+ a_ty, dir, b_vid, b_ty) ;
213
+ self . infcx . type_variables . borrow_mut ( ) . instantiate ( b_vid, b_ty) ;
214
+
215
+ // Finally, relate `b_ty` to `a_ty`, as described in previous comment.
216
+ //
217
+ // FIXME(#16847): This code is non-ideal because all these subtype
218
+ // relations wind up attributed to the same spans. We need
219
+ // to associate causes/spans with each of the relations in
220
+ // the stack to get this right.
221
+ match dir {
222
+ EqTo => self . equate ( a_is_expected) . relate ( & a_ty, & b_ty) ,
223
+ SubtypeOf => self . sub ( a_is_expected) . relate ( & a_ty, & b_ty) ,
224
+ SupertypeOf => self . sub ( a_is_expected) . relate_with_variance (
225
+ ty:: Contravariant , & a_ty, & b_ty) ,
226
+ } ?;
263
227
264
228
Ok ( ( ) )
265
229
}
266
230
267
231
/// Attempts to generalize `ty` for the type variable `for_vid`.
268
232
/// This checks for cycle -- that is, whether the type `ty`
269
- /// references `for_vid`. If `make_region_vars` is true, it will
270
- /// also replace all regions with fresh variables. Returns
271
- /// `TyError` in the case of a cycle, `Ok` otherwise.
233
+ /// references `for_vid`. If `is_eq_relation` is false, it will
234
+ /// also replace all regions/unbound-type-variables with fresh
235
+ /// variables. Returns `TyError` in the case of a cycle, `Ok`
236
+ /// otherwise.
272
237
///
273
238
/// Preconditions:
274
239
///
275
240
/// - `for_vid` is a "root vid"
276
241
fn generalize ( & self ,
277
242
ty : Ty < ' tcx > ,
278
243
for_vid : ty:: TyVid ,
279
- make_region_vars : bool )
244
+ is_eq_relation : bool )
280
245
-> RelateResult < ' tcx , Ty < ' tcx > >
281
246
{
282
- debug_assert ! ( self . infcx. type_variables. borrow_mut( ) . root_var( for_vid) == for_vid) ;
283
-
284
247
let mut generalize = Generalizer {
285
248
infcx : self . infcx ,
286
249
span : self . trace . cause . span ,
287
250
for_vid_sub_root : self . infcx . type_variables . borrow_mut ( ) . sub_root_var ( for_vid) ,
288
- make_region_vars : make_region_vars ,
251
+ is_eq_relation : is_eq_relation ,
289
252
cycle_detected : false
290
253
} ;
291
254
let u = ty. fold_with ( & mut generalize) ;
@@ -301,7 +264,7 @@ struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
301
264
infcx : & ' cx InferCtxt < ' cx , ' gcx , ' tcx > ,
302
265
span : Span ,
303
266
for_vid_sub_root : ty:: TyVid ,
304
- make_region_vars : bool ,
267
+ is_eq_relation : bool ,
305
268
cycle_detected : bool ,
306
269
}
307
270
@@ -332,7 +295,7 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
332
295
self . fold_ty ( u)
333
296
}
334
297
None => {
335
- if self . make_region_vars {
298
+ if ! self . is_eq_relation {
336
299
let origin = variables. origin ( vid) ;
337
300
let new_var_id = variables. new_var ( false , origin, None ) ;
338
301
let u = self . tcx ( ) . mk_var ( new_var_id) ;
@@ -379,7 +342,7 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
379
342
ty:: ReScope ( ..) |
380
343
ty:: ReVar ( ..) |
381
344
ty:: ReFree ( ..) => {
382
- if ! self . make_region_vars {
345
+ if self . is_eq_relation {
383
346
return r;
384
347
}
385
348
}
0 commit comments