@@ -255,10 +255,24 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
255
255
RelationDir :: SupertypeOf => ty:: Contravariant ,
256
256
} ;
257
257
258
+ debug ! ( "generalize: ambient_variance = {:?}" , ambient_variance) ;
259
+
260
+ let for_universe = match self . infcx . type_variables . borrow_mut ( ) . probe ( for_vid) {
261
+ v @ TypeVariableValue :: Known { .. } => panic ! (
262
+ "instantiating {:?} which has a known value {:?}" ,
263
+ for_vid,
264
+ v,
265
+ ) ,
266
+ TypeVariableValue :: Unknown { universe } => universe,
267
+ } ;
268
+
269
+ debug ! ( "generalize: for_universe = {:?}" , for_universe) ;
270
+
258
271
let mut generalize = Generalizer {
259
272
infcx : self . infcx ,
260
273
span : self . trace . cause . span ,
261
274
for_vid_sub_root : self . infcx . type_variables . borrow_mut ( ) . sub_root_var ( for_vid) ,
275
+ for_universe,
262
276
ambient_variance,
263
277
needs_wf : false ,
264
278
root_ty : ty,
@@ -288,6 +302,11 @@ struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
288
302
/// that means we would have created a cyclic type.
289
303
for_vid_sub_root : ty:: TyVid ,
290
304
305
+ /// The universe of the type variable that is in the process of
306
+ /// being instantiated. Any fresh variables that we create in this
307
+ /// process should be in that same universe.
308
+ for_universe : ty:: UniverseIndex ,
309
+
291
310
/// Track the variance as we descend into the type.
292
311
ambient_variance : ty:: Variance ,
293
312
@@ -386,6 +405,8 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
386
405
fn tys ( & mut self , t : Ty < ' tcx > , t2 : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
387
406
assert_eq ! ( t, t2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
388
407
408
+ debug ! ( "generalize: t={:?}" , t) ;
409
+
389
410
// Check to see whether the type we are genealizing references
390
411
// any other type variable related to `vid` via
391
412
// subtyping. This is basically our "occurs check", preventing
@@ -403,12 +424,17 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
403
424
match variables. probe ( vid) {
404
425
TypeVariableValue :: Known { value : u } => {
405
426
drop ( variables) ;
427
+ debug ! ( "generalize: known value {:?}" , u) ;
406
428
self . relate ( & u, & u)
407
429
}
408
430
TypeVariableValue :: Unknown { universe } => {
409
431
match self . ambient_variance {
410
432
// Invariant: no need to make a fresh type variable.
411
- ty:: Invariant => return Ok ( t) ,
433
+ ty:: Invariant => {
434
+ if self . for_universe . can_name ( universe) {
435
+ return Ok ( t) ;
436
+ }
437
+ }
412
438
413
439
// Bivariant: make a fresh var, but we
414
440
// may need a WF predicate. See
@@ -422,7 +448,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
422
448
}
423
449
424
450
let origin = * variables. var_origin ( vid) ;
425
- let new_var_id = variables. new_var ( universe , false , origin) ;
451
+ let new_var_id = variables. new_var ( self . for_universe , false , origin) ;
426
452
let u = self . tcx ( ) . mk_var ( new_var_id) ;
427
453
debug ! ( "generalize: replacing original vid={:?} with new={:?}" ,
428
454
vid, u) ;
@@ -448,6 +474,8 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
448
474
-> RelateResult < ' tcx , ty:: Region < ' tcx > > {
449
475
assert_eq ! ( r, r2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
450
476
477
+ debug ! ( "generalize: regions r={:?}" , r) ;
478
+
451
479
match * r {
452
480
// Never make variables for regions bound within the type itself,
453
481
// nor for erased regions.
@@ -456,37 +484,40 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
456
484
return Ok ( r) ;
457
485
}
458
486
459
- // Always make a fresh region variable for placeholder
460
- // regions; the higher-ranked decision procedures rely on
461
- // this.
462
- ty:: RePlaceholder ( ..) => { }
487
+ ty:: ReClosureBound ( ..) => {
488
+ span_bug ! (
489
+ self . span,
490
+ "encountered unexpected ReClosureBound: {:?}" ,
491
+ r,
492
+ ) ;
493
+ }
463
494
464
- // For anything else, we make a region variable, unless we
465
- // are *equating*, in which case it's just wasteful.
495
+ ty :: RePlaceholder ( .. ) |
496
+ ty :: ReVar ( .. ) |
466
497
ty:: ReEmpty |
467
498
ty:: ReStatic |
468
499
ty:: ReScope ( ..) |
469
- ty:: ReVar ( ..) |
470
500
ty:: ReEarlyBound ( ..) |
471
501
ty:: ReFree ( ..) => {
472
- match self . ambient_variance {
473
- ty:: Invariant => return Ok ( r) ,
474
- ty:: Bivariant | ty:: Covariant | ty:: Contravariant => ( ) ,
475
- }
502
+ // see common code below
476
503
}
504
+ }
477
505
478
- ty:: ReClosureBound ( ..) => {
479
- span_bug ! (
480
- self . span,
481
- "encountered unexpected ReClosureBound: {:?}" ,
482
- r,
483
- ) ;
506
+ // If we are in an invariant context, we can re-use the region
507
+ // as is, unless it happens to be in some universe that we
508
+ // can't name. (In the case of a region *variable*, we could
509
+ // use it if we promoted it into our universe, but we don't
510
+ // bother.)
511
+ if let ty:: Invariant = self . ambient_variance {
512
+ let r_universe = self . infcx . universe_of_region ( r) ;
513
+ if self . for_universe . can_name ( r_universe) {
514
+ return Ok ( r) ;
484
515
}
485
516
}
486
517
487
518
// FIXME: This is non-ideal because we don't give a
488
519
// very descriptive origin for this region variable.
489
- Ok ( self . infcx . next_region_var ( MiscVariable ( self . span ) ) )
520
+ Ok ( self . infcx . next_region_var_in_universe ( MiscVariable ( self . span ) , self . for_universe ) )
490
521
}
491
522
}
492
523
0 commit comments