@@ -8,12 +8,11 @@ use super::{
88} ;
99
1010use rustc_data_structures:: fx:: FxHashMap ;
11- use rustc_data_structures:: intern:: Interned ;
1211use rustc_data_structures:: sync:: Lrc ;
1312use rustc_data_structures:: undo_log:: UndoLogs ;
1413use rustc_data_structures:: unify as ut;
1514use rustc_index:: IndexVec ;
16- use rustc_middle:: infer:: unify_key:: { RegionVidKey , UnifiedRegion } ;
15+ use rustc_middle:: infer:: unify_key:: { RegionVariableValue , RegionVidKey } ;
1716use rustc_middle:: ty:: ReStatic ;
1817use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1918use rustc_middle:: ty:: { ReBound , ReVar } ;
@@ -292,6 +291,18 @@ type CombineMap<'tcx> = FxHashMap<TwoRegions<'tcx>, RegionVid>;
292291#[ derive( Debug , Clone , Copy ) ]
293292pub struct RegionVariableInfo {
294293 pub origin : RegionVariableOrigin ,
294+ // FIXME: This is only necessary for `fn take_and_reset_data` and
295+ // `lexical_region_resolve`. We should rework `lexical_region_resolve`
296+ // in the near/medium future anyways and could move the unverse info
297+ // for `fn take_and_reset_data` into a separate table which is
298+ // only populated when needed.
299+ //
300+ // For both of these cases it is fine that this can diverge from the
301+ // actual universe of the variable, which is directly stored in the
302+ // unification table for unknown region variables. At some point we could
303+ // stop emitting bidirectional outlives constraints if equate succeeds.
304+ // This would be currently unsound as it would cause us to drop the universe
305+ // changes in `lexical_region_resolve`.
295306 pub universe : ty:: UniverseIndex ,
296307}
297308
@@ -395,7 +406,11 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
395406 // `RegionConstraintData` contains the relationship here.
396407 if * any_unifications {
397408 * any_unifications = false ;
398- self . unification_table_mut ( ) . reset_unifications ( |_| UnifiedRegion :: new ( None ) ) ;
409+ // Manually inlined `self.unification_table_mut()` as `self` is used in the closure.
410+ ut:: UnificationTable :: with_log ( & mut self . storage . unification_table , & mut self . undo_log )
411+ . reset_unifications ( |key| RegionVariableValue :: Unknown {
412+ universe : self . storage . var_infos [ key. vid ] . universe ,
413+ } ) ;
399414 }
400415
401416 data
@@ -422,18 +437,13 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
422437 ) -> RegionVid {
423438 let vid = self . var_infos . push ( RegionVariableInfo { origin, universe } ) ;
424439
425- let u_vid = self . unification_table_mut ( ) . new_key ( UnifiedRegion :: new ( None ) ) ;
440+ let u_vid = self . unification_table_mut ( ) . new_key ( RegionVariableValue :: Unknown { universe } ) ;
426441 assert_eq ! ( vid, u_vid. vid) ;
427442 self . undo_log . push ( AddVar ( vid) ) ;
428443 debug ! ( "created new region variable {:?} in {:?} with origin {:?}" , vid, universe, origin) ;
429444 vid
430445 }
431446
432- /// Returns the universe for the given variable.
433- pub ( super ) fn var_universe ( & self , vid : RegionVid ) -> ty:: UniverseIndex {
434- self . var_infos [ vid] . universe
435- }
436-
437447 /// Returns the origin for the given variable.
438448 pub ( super ) fn var_origin ( & self , vid : RegionVid ) -> RegionVariableOrigin {
439449 self . var_infos [ vid] . origin
@@ -467,26 +477,41 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
467477 pub ( super ) fn make_eqregion (
468478 & mut self ,
469479 origin : SubregionOrigin < ' tcx > ,
470- sub : Region < ' tcx > ,
471- sup : Region < ' tcx > ,
480+ a : Region < ' tcx > ,
481+ b : Region < ' tcx > ,
472482 ) {
473- if sub != sup {
483+ if a != b {
474484 // Eventually, it would be nice to add direct support for
475485 // equating regions.
476- self . make_subregion ( origin. clone ( ) , sub, sup) ;
477- self . make_subregion ( origin, sup, sub) ;
478-
479- match ( sub, sup) {
480- ( Region ( Interned ( ReVar ( sub) , _) ) , Region ( Interned ( ReVar ( sup) , _) ) ) => {
481- debug ! ( "make_eqregion: unifying {:?} with {:?}" , sub, sup) ;
482- self . unification_table_mut ( ) . union ( * sub, * sup) ;
483- self . any_unifications = true ;
486+ self . make_subregion ( origin. clone ( ) , a, b) ;
487+ self . make_subregion ( origin, b, a) ;
488+
489+ match ( a. kind ( ) , b. kind ( ) ) {
490+ ( ty:: ReVar ( a) , ty:: ReVar ( b) ) => {
491+ debug ! ( "make_eqregion: unifying {:?} with {:?}" , a, b) ;
492+ if self . unification_table_mut ( ) . unify_var_var ( a, b) . is_ok ( ) {
493+ self . any_unifications = true ;
494+ }
495+ }
496+ ( ty:: ReVar ( vid) , _) => {
497+ debug ! ( "make_eqregion: unifying {:?} with {:?}" , vid, b) ;
498+ if self
499+ . unification_table_mut ( )
500+ . unify_var_value ( vid, RegionVariableValue :: Known { value : b } )
501+ . is_ok ( )
502+ {
503+ self . any_unifications = true ;
504+ } ;
484505 }
485- ( Region ( Interned ( ReVar ( vid) , _) ) , value)
486- | ( value, Region ( Interned ( ReVar ( vid) , _) ) ) => {
487- debug ! ( "make_eqregion: unifying {:?} with {:?}" , vid, value) ;
488- self . unification_table_mut ( ) . union_value ( * vid, UnifiedRegion :: new ( Some ( value) ) ) ;
489- self . any_unifications = true ;
506+ ( _, ty:: ReVar ( vid) ) => {
507+ debug ! ( "make_eqregion: unifying {:?} with {:?}" , a, vid) ;
508+ if self
509+ . unification_table_mut ( )
510+ . unify_var_value ( vid, RegionVariableValue :: Known { value : a } )
511+ . is_ok ( )
512+ {
513+ self . any_unifications = true ;
514+ } ;
490515 }
491516 ( _, _) => { }
492517 }
@@ -603,18 +628,21 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
603628 tcx : TyCtxt < ' tcx > ,
604629 vid : ty:: RegionVid ,
605630 ) -> ty:: Region < ' tcx > {
606- let mut ut = self . unification_table_mut ( ) ; // FIXME(rust-lang/ena#42): unnecessary mut
631+ let mut ut = self . unification_table_mut ( ) ;
607632 let root_vid = ut. find ( vid) . vid ;
608- let resolved = ut
609- . probe_value ( root_vid)
610- . get_value_ignoring_universes ( )
611- . unwrap_or_else ( || ty:: Region :: new_var ( tcx, root_vid) ) ;
612-
613- // Don't resolve a variable to a region that it cannot name.
614- if self . var_universe ( vid) . can_name ( self . universe ( resolved) ) {
615- resolved
616- } else {
617- ty:: Region :: new_var ( tcx, vid)
633+ match ut. probe_value ( root_vid) {
634+ RegionVariableValue :: Known { value } => value,
635+ RegionVariableValue :: Unknown { .. } => ty:: Region :: new_var ( tcx, root_vid) ,
636+ }
637+ }
638+
639+ pub fn probe_value (
640+ & mut self ,
641+ vid : ty:: RegionVid ,
642+ ) -> Result < ty:: Region < ' tcx > , ty:: UniverseIndex > {
643+ match self . unification_table_mut ( ) . probe_value ( vid) {
644+ RegionVariableValue :: Known { value } => Ok ( value) ,
645+ RegionVariableValue :: Unknown { universe } => Err ( universe) ,
618646 }
619647 }
620648
@@ -654,15 +682,18 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
654682 new_r
655683 }
656684
657- pub fn universe ( & self , region : Region < ' tcx > ) -> ty:: UniverseIndex {
685+ pub fn universe ( & mut self , region : Region < ' tcx > ) -> ty:: UniverseIndex {
658686 match * region {
659687 ty:: ReStatic
660688 | ty:: ReErased
661689 | ty:: ReLateParam ( ..)
662690 | ty:: ReEarlyParam ( ..)
663691 | ty:: ReError ( _) => ty:: UniverseIndex :: ROOT ,
664692 ty:: RePlaceholder ( placeholder) => placeholder. universe ,
665- ty:: ReVar ( vid) => self . var_universe ( vid) ,
693+ ty:: ReVar ( vid) => match self . probe_value ( vid) {
694+ Ok ( value) => self . universe ( value) ,
695+ Err ( universe) => universe,
696+ } ,
666697 ty:: ReBound ( ..) => bug ! ( "universe(): encountered bound region {:?}" , region) ,
667698 }
668699 }
0 commit comments