@@ -62,7 +62,7 @@ pub struct RegionTracker {
62
62
/// The representative Region Variable Id for this SCC. We prefer
63
63
/// placeholders over existentially quantified variables, otherwise
64
64
/// it's the one with the smallest Region Variable ID.
65
- representative : RegionVid ,
65
+ pub ( crate ) representative : RegionVid ,
66
66
67
67
/// Is the current representative a placeholder?
68
68
representative_is_placeholder : bool ,
@@ -97,7 +97,7 @@ impl scc::Annotation for RegionTracker {
97
97
}
98
98
99
99
impl RegionTracker {
100
- fn new ( rvid : RegionVid , definition : & RegionDefinition < ' _ > ) -> Self {
100
+ pub ( crate ) fn new ( rvid : RegionVid , definition : & RegionDefinition < ' _ > ) -> Self {
101
101
let ( representative_is_placeholder, representative_is_existential) = match definition. origin
102
102
{
103
103
rustc_infer:: infer:: NllRegionVariableOrigin :: FreeRegion => ( false , false ) ,
@@ -116,7 +116,9 @@ impl RegionTracker {
116
116
representative_is_existential,
117
117
}
118
118
}
119
- fn universe ( self ) -> UniverseIndex {
119
+
120
+ /// The smallest-indexed universe reachable from and/or in this SCC.
121
+ fn min_universe ( self ) -> UniverseIndex {
120
122
self . min_reachable_universe
121
123
}
122
124
@@ -132,8 +134,8 @@ impl RegionTracker {
132
134
133
135
/// Returns `true` if during the annotated SCC reaches a placeholder
134
136
/// with a universe larger than the smallest reachable one, `false` otherwise.
135
- pub fn has_incompatible_universes ( & self ) -> bool {
136
- self . universe ( ) . cannot_name ( self . max_placeholder_universe_reached )
137
+ pub ( crate ) fn has_incompatible_universes ( & self ) -> bool {
138
+ self . min_universe ( ) . cannot_name ( self . max_placeholder_universe_reached )
137
139
}
138
140
}
139
141
@@ -163,7 +165,7 @@ pub struct RegionInferenceContext<'tcx> {
163
165
/// The SCC computed from `constraints` and the constraint
164
166
/// graph. We have an edge from SCC A to SCC B if `A: B`. Used to
165
167
/// compute the values of each region.
166
- constraint_sccs : Rc < ConstraintSccs > ,
168
+ constraint_sccs : ConstraintSccs ,
167
169
168
170
/// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if
169
171
/// `B: A`. This is used to compute the universal regions that are required
@@ -401,7 +403,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
401
403
universal_regions : Rc < UniversalRegions < ' tcx > > ,
402
404
placeholder_indices : Rc < PlaceholderIndices > ,
403
405
universal_region_relations : Frozen < UniversalRegionRelations < ' tcx > > ,
404
- outlives_constraints : OutlivesConstraintSet < ' tcx > ,
406
+ mut outlives_constraints : OutlivesConstraintSet < ' tcx > ,
405
407
member_constraints_in : MemberConstraintSet < ' tcx , RegionVid > ,
406
408
universe_causes : FxIndexMap < ty:: UniverseIndex , UniverseInfo < ' tcx > > ,
407
409
type_tests : Vec < TypeTest < ' tcx > > ,
@@ -419,17 +421,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
419
421
. map ( |info| RegionDefinition :: new ( info. universe , info. origin ) )
420
422
. collect ( ) ;
421
423
422
- let fr_static = universal_regions. fr_static ;
424
+ let constraint_sccs =
425
+ outlives_constraints. add_outlives_static ( & universal_regions, & definitions) ;
423
426
let constraints = Frozen :: freeze ( outlives_constraints) ;
424
427
let constraint_graph = Frozen :: freeze ( constraints. graph ( definitions. len ( ) ) ) ;
425
- let constraint_sccs = {
426
- let constraint_graph = constraints. graph ( definitions. len ( ) ) ;
427
- let region_graph = & constraint_graph. region_graph ( & constraints, fr_static) ;
428
- let sccs = ConstraintSccs :: new_with_annotation ( & region_graph, |r| {
429
- RegionTracker :: new ( r, & definitions[ r] )
430
- } ) ;
431
- Rc :: new ( sccs)
432
- } ;
433
428
434
429
if cfg ! ( debug_assertions) {
435
430
sccs_info ( infcx, & constraint_sccs) ;
@@ -548,21 +543,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
548
543
}
549
544
550
545
NllRegionVariableOrigin :: Placeholder ( placeholder) => {
551
- // Each placeholder region is only visible from
552
- // its universe `ui` and its extensions. So we
553
- // can't just add it into `scc` unless the
554
- // universe of the scc can name this region.
555
- let scc_universe = self . scc_universe ( scc) ;
556
- if scc_universe. can_name ( placeholder. universe ) {
557
- self . scc_values . add_element ( scc, placeholder) ;
558
- } else {
559
- debug ! (
560
- "init_free_and_bound_regions: placeholder {:?} is \
561
- not compatible with universe {:?} of its SCC {:?}",
562
- placeholder, scc_universe, scc,
563
- ) ;
564
- self . add_incompatible_universe ( scc) ;
565
- }
546
+ self . scc_values . add_element ( scc, placeholder) ;
566
547
}
567
548
568
549
NllRegionVariableOrigin :: Existential { .. } => {
@@ -744,23 +725,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
744
725
/// (which is assured by iterating over SCCs in dependency order).
745
726
#[ instrument( skip( self ) , level = "debug" ) ]
746
727
fn compute_value_for_scc ( & mut self , scc_a : ConstraintSccIndex ) {
747
- let constraint_sccs = self . constraint_sccs . clone ( ) ;
748
-
749
728
// Walk each SCC `B` such that `A: B`...
750
- for & scc_b in constraint_sccs. successors ( scc_a) {
729
+ for & scc_b in self . constraint_sccs . successors ( scc_a) {
751
730
debug ! ( ?scc_b) ;
752
-
753
- // ...and add elements from `B` into `A`. One complication
754
- // arises because of universes: If `B` contains something
755
- // that `A` cannot name, then `A` can only contain `B` if
756
- // it outlives static.
757
- if self . universe_compatible ( scc_b, scc_a) {
758
- // `A` can name everything that is in `B`, so just
759
- // merge the bits.
760
- self . scc_values . add_region ( scc_a, scc_b) ;
761
- } else {
762
- self . add_incompatible_universe ( scc_a) ;
763
- }
731
+ self . scc_values . add_region ( scc_a, scc_b) ;
764
732
}
765
733
766
734
// Now take member constraints into account.
@@ -814,7 +782,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
814
782
// If the member region lives in a higher universe, we currently choose
815
783
// the most conservative option by leaving it unchanged.
816
784
817
- if !self . constraint_sccs ( ) . annotation ( scc) . universe ( ) . is_root ( ) {
785
+ if !self . constraint_sccs ( ) . annotation ( scc) . min_universe ( ) . is_root ( ) {
818
786
return ;
819
787
}
820
788
@@ -886,35 +854,20 @@ impl<'tcx> RegionInferenceContext<'tcx> {
886
854
/// in `scc_a`. Used during constraint propagation, and only once
887
855
/// the value of `scc_b` has been computed.
888
856
fn universe_compatible ( & self , scc_b : ConstraintSccIndex , scc_a : ConstraintSccIndex ) -> bool {
889
- let universe_a = self . constraint_sccs ( ) . annotation ( scc_a) . universe ( ) ;
890
- let universe_b = self . constraint_sccs ( ) . annotation ( scc_b) . universe ( ) ;
857
+ let a_annotation = self . constraint_sccs ( ) . annotation ( scc_a) ;
858
+ let b_annotation = self . constraint_sccs ( ) . annotation ( scc_b) ;
859
+ let a_universe = a_annotation. min_universe ( ) ;
891
860
892
- // Quick check: if scc_b's declared universe is a subset of
861
+ // If scc_b's declared universe is a subset of
893
862
// scc_a's declared universe (typically, both are ROOT), then
894
863
// it cannot contain any problematic universe elements.
895
- if universe_a . can_name ( universe_b ) {
864
+ if a_universe . can_name ( b_annotation . min_universe ( ) ) {
896
865
return true ;
897
866
}
898
867
899
- // Otherwise, we have to iterate over the universe elements in
900
- // B's value, and check whether all of them are nameable
901
- // from universe_a
902
- self . scc_values . placeholders_contained_in ( scc_b) . all ( |p| universe_a. can_name ( p. universe ) )
903
- }
904
-
905
- /// Extend `scc` so that it can outlive some placeholder region
906
- /// from a universe it can't name; at present, the only way for
907
- /// this to be true is if `scc` outlives `'static`. This is
908
- /// actually stricter than necessary: ideally, we'd support bounds
909
- /// like `for<'a: 'b>` that might then allow us to approximate
910
- /// `'a` with `'b` and not `'static`. But it will have to do for
911
- /// now.
912
- fn add_incompatible_universe ( & mut self , scc : ConstraintSccIndex ) {
913
- debug ! ( "add_incompatible_universe(scc={:?})" , scc) ;
914
-
915
- let fr_static = self . universal_regions . fr_static ;
916
- self . scc_values . add_all_points ( scc) ;
917
- self . scc_values . add_element ( scc, fr_static) ;
868
+ // Otherwise, there can be no placeholder in `b` with a too high
869
+ // universe index to name from `a`.
870
+ a_universe. can_name ( b_annotation. max_placeholder_universe_reached )
918
871
}
919
872
920
873
/// Once regions have been propagated, this method is used to see
@@ -1022,7 +975,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1022
975
"lower_bound = {:?} r_scc={:?} universe={:?}" ,
1023
976
lower_bound,
1024
977
r_scc,
1025
- self . constraint_sccs. annotation( r_scc) . universe ( )
978
+ self . constraint_sccs. annotation( r_scc) . min_universe ( )
1026
979
) ;
1027
980
1028
981
// If the type test requires that `T: 'a` where `'a` is a
@@ -1539,7 +1492,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1539
1492
/// The minimum universe of any variable reachable from this
1540
1493
/// SCC, inside or outside of it.
1541
1494
fn scc_universe ( & self , scc : ConstraintSccIndex ) -> UniverseIndex {
1542
- self . constraint_sccs ( ) . annotation ( scc) . universe ( )
1495
+ self . constraint_sccs ( ) . annotation ( scc) . min_universe ( )
1543
1496
}
1544
1497
/// Checks the final value for the free region `fr` to see if it
1545
1498
/// grew too large. In particular, examine what `end(X)` points
@@ -1896,6 +1849,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1896
1849
1897
1850
// This loop can be hot.
1898
1851
for constraint in outgoing_edges_from_graph {
1852
+ if matches ! ( constraint. category, ConstraintCategory :: IllegalUniverse ) {
1853
+ debug ! ( "Ignoring illegal universe constraint: {constraint:?}" ) ;
1854
+ continue ;
1855
+ }
1899
1856
handle_constraint ( constraint) ;
1900
1857
}
1901
1858
0 commit comments