@@ -8,12 +8,11 @@ use super::{
8
8
} ;
9
9
10
10
use rustc_data_structures:: fx:: FxHashMap ;
11
- use rustc_data_structures:: intern:: Interned ;
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
14
use rustc_index:: IndexVec ;
16
- use rustc_middle:: infer:: unify_key:: { RegionVidKey , UnifiedRegion } ;
15
+ use rustc_middle:: infer:: unify_key:: { RegionVariableValue , RegionVidKey } ;
17
16
use rustc_middle:: ty:: ReStatic ;
18
17
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
19
18
use rustc_middle:: ty:: { ReBound , ReVar } ;
@@ -292,6 +291,18 @@ type CombineMap<'tcx> = FxHashMap<TwoRegions<'tcx>, RegionVid>;
292
291
#[ derive( Debug , Clone , Copy ) ]
293
292
pub struct RegionVariableInfo {
294
293
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`.
295
306
pub universe : ty:: UniverseIndex ,
296
307
}
297
308
@@ -395,7 +406,11 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
395
406
// `RegionConstraintData` contains the relationship here.
396
407
if * any_unifications {
397
408
* 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
+ } ) ;
399
414
}
400
415
401
416
data
@@ -422,18 +437,13 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
422
437
) -> RegionVid {
423
438
let vid = self . var_infos . push ( RegionVariableInfo { origin, universe } ) ;
424
439
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 } ) ;
426
441
assert_eq ! ( vid, u_vid. vid) ;
427
442
self . undo_log . push ( AddVar ( vid) ) ;
428
443
debug ! ( "created new region variable {:?} in {:?} with origin {:?}" , vid, universe, origin) ;
429
444
vid
430
445
}
431
446
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
-
437
447
/// Returns the origin for the given variable.
438
448
pub ( super ) fn var_origin ( & self , vid : RegionVid ) -> RegionVariableOrigin {
439
449
self . var_infos [ vid] . origin
@@ -467,26 +477,41 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
467
477
pub ( super ) fn make_eqregion (
468
478
& mut self ,
469
479
origin : SubregionOrigin < ' tcx > ,
470
- sub : Region < ' tcx > ,
471
- sup : Region < ' tcx > ,
480
+ a : Region < ' tcx > ,
481
+ b : Region < ' tcx > ,
472
482
) {
473
- if sub != sup {
483
+ if a != b {
474
484
// Eventually, it would be nice to add direct support for
475
485
// 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
+ } ;
484
505
}
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
+ } ;
490
515
}
491
516
( _, _) => { }
492
517
}
@@ -603,18 +628,21 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
603
628
tcx : TyCtxt < ' tcx > ,
604
629
vid : ty:: RegionVid ,
605
630
) -> 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 ( ) ;
607
632
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) ,
618
646
}
619
647
}
620
648
@@ -654,15 +682,18 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
654
682
new_r
655
683
}
656
684
657
- pub fn universe ( & self , region : Region < ' tcx > ) -> ty:: UniverseIndex {
685
+ pub fn universe ( & mut self , region : Region < ' tcx > ) -> ty:: UniverseIndex {
658
686
match * region {
659
687
ty:: ReStatic
660
688
| ty:: ReErased
661
689
| ty:: ReLateParam ( ..)
662
690
| ty:: ReEarlyParam ( ..)
663
691
| ty:: ReError ( _) => ty:: UniverseIndex :: ROOT ,
664
692
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
+ } ,
666
697
ty:: ReBound ( ..) => bug ! ( "universe(): encountered bound region {:?}" , region) ,
667
698
}
668
699
}
0 commit comments