@@ -255,10 +255,24 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
255255 RelationDir :: SupertypeOf => ty:: Contravariant ,
256256 } ;
257257
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+
258271 let mut generalize = Generalizer {
259272 infcx : self . infcx ,
260273 span : self . trace . cause . span ,
261274 for_vid_sub_root : self . infcx . type_variables . borrow_mut ( ) . sub_root_var ( for_vid) ,
275+ for_universe,
262276 ambient_variance,
263277 needs_wf : false ,
264278 root_ty : ty,
@@ -288,6 +302,11 @@ struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
288302 /// that means we would have created a cyclic type.
289303 for_vid_sub_root : ty:: TyVid ,
290304
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+
291310 /// Track the variance as we descend into the type.
292311 ambient_variance : ty:: Variance ,
293312
@@ -386,6 +405,8 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
386405 fn tys ( & mut self , t : Ty < ' tcx > , t2 : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
387406 assert_eq ! ( t, t2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
388407
408+ debug ! ( "generalize: t={:?}" , t) ;
409+
389410 // Check to see whether the type we are genealizing references
390411 // any other type variable related to `vid` via
391412 // subtyping. This is basically our "occurs check", preventing
@@ -403,12 +424,17 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
403424 match variables. probe ( vid) {
404425 TypeVariableValue :: Known { value : u } => {
405426 drop ( variables) ;
427+ debug ! ( "generalize: known value {:?}" , u) ;
406428 self . relate ( & u, & u)
407429 }
408430 TypeVariableValue :: Unknown { universe } => {
409431 match self . ambient_variance {
410432 // 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+ }
412438
413439 // Bivariant: make a fresh var, but we
414440 // may need a WF predicate. See
@@ -422,7 +448,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
422448 }
423449
424450 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) ;
426452 let u = self . tcx ( ) . mk_var ( new_var_id) ;
427453 debug ! ( "generalize: replacing original vid={:?} with new={:?}" ,
428454 vid, u) ;
@@ -448,6 +474,8 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
448474 -> RelateResult < ' tcx , ty:: Region < ' tcx > > {
449475 assert_eq ! ( r, r2) ; // we are abusing TypeRelation here; both LHS and RHS ought to be ==
450476
477+ debug ! ( "generalize: regions r={:?}" , r) ;
478+
451479 match * r {
452480 // Never make variables for regions bound within the type itself,
453481 // nor for erased regions.
@@ -456,37 +484,40 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
456484 return Ok ( r) ;
457485 }
458486
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+ }
463494
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 ( .. ) |
466497 ty:: ReEmpty |
467498 ty:: ReStatic |
468499 ty:: ReScope ( ..) |
469- ty:: ReVar ( ..) |
470500 ty:: ReEarlyBound ( ..) |
471501 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
476503 }
504+ }
477505
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) ;
484515 }
485516 }
486517
487518 // FIXME: This is non-ideal because we don't give a
488519 // 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 ) )
490521 }
491522}
492523
0 commit comments