3
3
use self :: CombineMapType :: * ;
4
4
use self :: UndoLog :: * ;
5
5
6
- use super :: unify_key;
7
6
use super :: {
8
7
InferCtxtUndoLogs , MiscVariable , RegionVariableOrigin , Rollback , Snapshot , SubregionOrigin ,
9
8
} ;
@@ -12,9 +11,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
12
11
use rustc_data_structures:: sync:: Lrc ;
13
12
use rustc_data_structures:: undo_log:: UndoLogs ;
14
13
use rustc_data_structures:: unify as ut;
15
- use rustc_data_structures:: unify:: UnifyKey ;
16
14
use rustc_hir:: def_id:: DefId ;
17
15
use rustc_index:: vec:: IndexVec ;
16
+ use rustc_middle:: infer:: unify_key:: { RegionVidKey , UnifiedRegion } ;
18
17
use rustc_middle:: ty:: ReStatic ;
19
18
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
20
19
use rustc_middle:: ty:: { ReLateBound , ReVar } ;
@@ -54,7 +53,7 @@ pub struct RegionConstraintStorage<'tcx> {
54
53
/// code is iterating to a fixed point, because otherwise we sometimes
55
54
/// would wind up with a fresh stream of region variables that have been
56
55
/// equated but appear distinct.
57
- pub ( super ) unification_table : ut:: UnificationTableStorage < ty :: RegionVid > ,
56
+ pub ( super ) unification_table : ut:: UnificationTableStorage < RegionVidKey < ' tcx > > ,
58
57
59
58
/// a flag set to true when we perform any unifications; this is used
60
59
/// to micro-optimize `take_and_reset_data`
@@ -407,8 +406,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
407
406
// `RegionConstraintData` contains the relationship here.
408
407
if * any_unifications {
409
408
* 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 ) ) ;
412
410
}
413
411
414
412
data
@@ -435,8 +433,8 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
435
433
) -> RegionVid {
436
434
let vid = self . var_infos . push ( RegionVariableInfo { origin, universe } ) ;
437
435
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 ) ;
440
438
self . undo_log . push ( AddVar ( vid) ) ;
441
439
debug ! ( "created new region variable {:?} in {:?} with origin {:?}" , vid, universe, origin) ;
442
440
vid
@@ -498,10 +496,18 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
498
496
self . make_subregion ( origin. clone ( ) , sub, sup) ;
499
497
self . make_subregion ( origin, sup, sub) ;
500
498
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
+ ( _, _) => { }
505
511
}
506
512
}
507
513
}
@@ -617,8 +623,29 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
617
623
}
618
624
}
619
625
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
+ }
622
649
}
623
650
624
651
fn combine_map ( & mut self , t : CombineMapType ) -> & mut CombineMap < ' tcx > {
@@ -673,8 +700,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
673
700
& self ,
674
701
value_count : usize ,
675
702
) -> ( 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 ( ) ) ;
678
704
(
679
705
range. clone ( ) ,
680
706
( range. start . index ( ) ..range. end . index ( ) )
@@ -696,7 +722,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
696
722
}
697
723
698
724
#[ inline]
699
- fn unification_table ( & mut self ) -> super :: UnificationTable < ' _ , ' tcx , ty :: RegionVid > {
725
+ fn unification_table ( & mut self ) -> super :: UnificationTable < ' _ , ' tcx , RegionVidKey < ' tcx > > {
700
726
ut:: UnificationTable :: with_log ( & mut self . storage . unification_table , self . undo_log )
701
727
}
702
728
}
0 commit comments