33use self :: CombineMapType :: * ;
44use self :: UndoLog :: * ;
55
6- use super :: unify_key;
76use super :: {
87 InferCtxtUndoLogs , MiscVariable , RegionVariableOrigin , Rollback , Snapshot , SubregionOrigin ,
98} ;
@@ -12,9 +11,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1211use rustc_data_structures:: sync:: Lrc ;
1312use rustc_data_structures:: undo_log:: UndoLogs ;
1413use rustc_data_structures:: unify as ut;
15- use rustc_data_structures:: unify:: UnifyKey ;
1614use rustc_hir:: def_id:: DefId ;
1715use rustc_index:: vec:: IndexVec ;
16+ use rustc_middle:: infer:: unify_key:: { RegionVidKey , UnifiedRegion } ;
1817use rustc_middle:: ty:: ReStatic ;
1918use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
2019use rustc_middle:: ty:: { ReLateBound , ReVar } ;
@@ -54,7 +53,7 @@ pub struct RegionConstraintStorage<'tcx> {
5453 /// code is iterating to a fixed point, because otherwise we sometimes
5554 /// would wind up with a fresh stream of region variables that have been
5655 /// equated but appear distinct.
57- pub ( super ) unification_table : ut:: UnificationTableStorage < ty :: RegionVid > ,
56+ pub ( super ) unification_table : ut:: UnificationTableStorage < RegionVidKey < ' tcx > > ,
5857
5958 /// a flag set to true when we perform any unifications; this is used
6059 /// to micro-optimize `take_and_reset_data`
@@ -407,8 +406,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
407406 // `RegionConstraintData` contains the relationship here.
408407 if * any_unifications {
409408 * any_unifications = false ;
410- self . unification_table ( )
411- . reset_unifications ( |vid| unify_key:: RegionVidKey { min_vid : vid } ) ;
409+ self . unification_table ( ) . reset_unifications ( |_| UnifiedRegion ( None ) ) ;
412410 }
413411
414412 data
@@ -435,8 +433,8 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
435433 ) -> RegionVid {
436434 let vid = self . var_infos . push ( RegionVariableInfo { origin, universe } ) ;
437435
438- let u_vid = self . unification_table ( ) . new_key ( unify_key :: RegionVidKey { min_vid : vid } ) ;
439- assert_eq ! ( vid, u_vid) ;
436+ let u_vid = self . unification_table ( ) . new_key ( UnifiedRegion ( None ) ) ;
437+ assert_eq ! ( vid, u_vid. vid ) ;
440438 self . undo_log . push ( AddVar ( vid) ) ;
441439 debug ! ( "created new region variable {:?} in {:?} with origin {:?}" , vid, universe, origin) ;
442440 vid
@@ -498,10 +496,18 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
498496 self . make_subregion ( origin. clone ( ) , sub, sup) ;
499497 self . make_subregion ( origin, sup, sub) ;
500498
501- if let ( ty:: ReVar ( sub) , ty:: ReVar ( sup) ) = ( * sub, * sup) {
502- debug ! ( "make_eqregion: uniying {:?} with {:?}" , sub, sup) ;
503- self . unification_table ( ) . union ( sub, sup) ;
504- self . any_unifications = true ;
499+ match ( sub, sup) {
500+ ( & ty:: ReVar ( sub) , & ty:: ReVar ( sup) ) => {
501+ debug ! ( "make_eqregion: unifying {:?} with {:?}" , sub, sup) ;
502+ self . unification_table ( ) . union ( sub, sup) ;
503+ self . any_unifications = true ;
504+ }
505+ ( & ty:: ReVar ( vid) , value) | ( value, & ty:: ReVar ( vid) ) => {
506+ debug ! ( "make_eqregion: unifying {:?} with {:?}" , vid, value) ;
507+ self . unification_table ( ) . union_value ( vid, UnifiedRegion ( Some ( value) ) ) ;
508+ self . any_unifications = true ;
509+ }
510+ ( _, _) => { }
505511 }
506512 }
507513 }
@@ -617,8 +623,29 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
617623 }
618624 }
619625
620- pub fn opportunistic_resolve_var ( & mut self , rid : RegionVid ) -> ty:: RegionVid {
621- self . unification_table ( ) . probe_value ( rid) . min_vid
626+ /// Resolves the passed RegionVid to the root RegionVid in the unification table
627+ pub fn opportunistic_resolve_var ( & mut self , rid : ty:: RegionVid ) -> ty:: RegionVid {
628+ self . unification_table ( ) . find ( rid) . vid
629+ }
630+
631+ /// If the Region is a `ReVar`, then resolves it either to the root value in
632+ /// the unification table, if it exists, or to the root `ReVar` in the table.
633+ /// If the Region is not a `ReVar`, just returns the Region itself.
634+ pub fn opportunistic_resolve_region (
635+ & mut self ,
636+ tcx : TyCtxt < ' tcx > ,
637+ region : ty:: Region < ' tcx > ,
638+ ) -> ty:: Region < ' tcx > {
639+ match region {
640+ ty:: ReVar ( rid) => {
641+ let unified_region = self . unification_table ( ) . probe_value ( * rid) ;
642+ unified_region. 0 . unwrap_or_else ( || {
643+ let root = self . unification_table ( ) . find ( * rid) . vid ;
644+ tcx. reuse_or_mk_region ( region, ty:: ReVar ( root) )
645+ } )
646+ }
647+ _ => region,
648+ }
622649 }
623650
624651 fn combine_map ( & mut self , t : CombineMapType ) -> & mut CombineMap < ' tcx > {
@@ -673,8 +700,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
673700 & self ,
674701 value_count : usize ,
675702 ) -> ( Range < RegionVid > , Vec < RegionVariableOrigin > ) {
676- let range = RegionVid :: from_index ( value_count as u32 )
677- ..RegionVid :: from_index ( self . unification_table . len ( ) as u32 ) ;
703+ let range = RegionVid :: from ( value_count) ..RegionVid :: from ( self . unification_table . len ( ) ) ;
678704 (
679705 range. clone ( ) ,
680706 ( range. start . index ( ) ..range. end . index ( ) )
@@ -696,7 +722,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
696722 }
697723
698724 #[ inline]
699- fn unification_table ( & mut self ) -> super :: UnificationTable < ' _ , ' tcx , ty :: RegionVid > {
725+ fn unification_table ( & mut self ) -> super :: UnificationTable < ' _ , ' tcx , RegionVidKey < ' tcx > > {
700726 ut:: UnificationTable :: with_log ( & mut self . storage . unification_table , self . undo_log )
701727 }
702728}
0 commit comments