@@ -71,7 +71,7 @@ pub struct RegionInferenceContext<'tcx> {
71
71
/// The SCC computed from `constraints` and the constraint
72
72
/// graph. We have an edge from SCC A to SCC B if `A: B`. Used to
73
73
/// compute the values of each region.
74
- constraint_sccs : Rc < Sccs < RegionVid , ConstraintSccIndex > > ,
74
+ constraint_sccs : Sccs < RegionVid , ConstraintSccIndex > ,
75
75
76
76
/// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if
77
77
/// `B: A`. This is used to compute the universal regions that are required
@@ -251,7 +251,7 @@ pub enum ExtraConstraintInfo {
251
251
#[ instrument( skip( infcx, sccs) , level = "debug" ) ]
252
252
fn sccs_info < ' cx , ' tcx > (
253
253
infcx : & ' cx BorrowckInferCtxt < ' cx , ' tcx > ,
254
- sccs : Rc < Sccs < RegionVid , ConstraintSccIndex > > ,
254
+ sccs : & Sccs < RegionVid , ConstraintSccIndex > ,
255
255
) {
256
256
use crate :: renumber:: RegionCtxt ;
257
257
@@ -322,12 +322,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
322
322
/// The `outlives_constraints` and `type_tests` are an initial set
323
323
/// of constraints produced by the MIR type check.
324
324
pub ( crate ) fn new < ' cx > (
325
- _infcx : & BorrowckInferCtxt < ' cx , ' tcx > ,
325
+ infcx : & BorrowckInferCtxt < ' cx , ' tcx > ,
326
326
var_infos : VarInfos ,
327
327
universal_regions : Rc < UniversalRegions < ' tcx > > ,
328
328
placeholder_indices : Rc < PlaceholderIndices > ,
329
329
universal_region_relations : Frozen < UniversalRegionRelations < ' tcx > > ,
330
- outlives_constraints : OutlivesConstraintSet < ' tcx > ,
330
+ mut outlives_constraints : OutlivesConstraintSet < ' tcx > ,
331
331
member_constraints_in : MemberConstraintSet < ' tcx , RegionVid > ,
332
332
universe_causes : FxIndexMap < ty:: UniverseIndex , UniverseInfo < ' tcx > > ,
333
333
type_tests : Vec < TypeTest < ' tcx > > ,
@@ -345,13 +345,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
345
345
. map ( |info| RegionDefinition :: new ( info. universe , info. origin ) )
346
346
. collect ( ) ;
347
347
348
+ outlives_constraints. placeholders_to_static ( & universal_regions, & definitions) ;
349
+
348
350
let constraints = Frozen :: freeze ( outlives_constraints) ;
349
351
let constraint_graph = Frozen :: freeze ( constraints. graph ( definitions. len ( ) ) ) ;
350
352
let fr_static = universal_regions. fr_static ;
351
- let constraint_sccs = Rc :: new ( constraints. compute_sccs ( & constraint_graph, fr_static) ) ;
353
+ let constraint_sccs = constraints. compute_sccs ( & constraint_graph, fr_static) ;
352
354
353
355
if cfg ! ( debug_assertions) {
354
- sccs_info ( _infcx , constraint_sccs. clone ( ) ) ;
356
+ sccs_info ( infcx , & constraint_sccs) ;
355
357
}
356
358
357
359
let mut scc_values =
@@ -535,7 +537,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
535
537
// This iterator has unstable order but we collect it all into an IndexVec
536
538
for ( external_name, variable) in self . universal_regions . named_universal_regions ( ) {
537
539
debug ! (
538
- "init_universal_regions : region {:?} has external name {:?}" ,
540
+ "init_free_and_bound_regions : region {:?} has external name {:?}" ,
539
541
variable, external_name
540
542
) ;
541
543
self . definitions [ variable] . external_name = Some ( external_name) ;
@@ -557,21 +559,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
557
559
}
558
560
559
561
NllRegionVariableOrigin :: Placeholder ( placeholder) => {
560
- // Each placeholder region is only visible from
561
- // its universe `ui` and its extensions. So we
562
- // can't just add it into `scc` unless the
563
- // universe of the scc can name this region.
564
- let scc_universe = self . scc_universes [ scc] ;
565
- if scc_universe. can_name ( placeholder. universe ) {
566
- self . scc_values . add_element ( scc, placeholder) ;
567
- } else {
568
- debug ! (
569
- "init_free_and_bound_regions: placeholder {:?} is \
570
- not compatible with universe {:?} of its SCC {:?}",
571
- placeholder, scc_universe, scc,
572
- ) ;
573
- self . add_incompatible_universe ( scc) ;
574
- }
562
+ self . scc_values . add_element ( scc, placeholder) ;
575
563
}
576
564
577
565
NllRegionVariableOrigin :: Existential { .. } => {
@@ -739,8 +727,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
739
727
// SCC. For each SCC, we visit its successors and compute
740
728
// their values, then we union all those values to get our
741
729
// own.
742
- let constraint_sccs = self . constraint_sccs . clone ( ) ;
743
- for scc in constraint_sccs. all_sccs ( ) {
730
+ for scc in self . constraint_sccs . all_sccs ( ) {
744
731
self . compute_value_for_scc ( scc) ;
745
732
}
746
733
@@ -755,23 +742,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
755
742
/// (which is assured by iterating over SCCs in dependency order).
756
743
#[ instrument( skip( self ) , level = "debug" ) ]
757
744
fn compute_value_for_scc ( & mut self , scc_a : ConstraintSccIndex ) {
758
- let constraint_sccs = self . constraint_sccs . clone ( ) ;
759
-
760
745
// Walk each SCC `B` such that `A: B`...
761
- for & scc_b in constraint_sccs. successors ( scc_a) {
746
+ for & scc_b in self . constraint_sccs . successors ( scc_a) {
762
747
debug ! ( ?scc_b) ;
763
-
764
- // ...and add elements from `B` into `A`. One complication
765
- // arises because of universes: If `B` contains something
766
- // that `A` cannot name, then `A` can only contain `B` if
767
- // it outlives static.
768
- if self . universe_compatible ( scc_b, scc_a) {
769
- // `A` can name everything that is in `B`, so just
770
- // merge the bits.
771
- self . scc_values . add_region ( scc_a, scc_b) ;
772
- } else {
773
- self . add_incompatible_universe ( scc_a) ;
774
- }
748
+ self . scc_values . add_region ( scc_a, scc_b) ;
775
749
}
776
750
777
751
// Now take member constraints into account.
@@ -827,12 +801,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
827
801
if self . scc_universes [ scc] != ty:: UniverseIndex :: ROOT {
828
802
return ;
829
803
}
830
- debug_assert ! (
831
- self . scc_values. placeholders_contained_in( scc) . next( ) . is_none( ) ,
832
- "scc {:?} in a member constraint has placeholder value: {:?}" ,
833
- scc,
834
- self . scc_values. region_value_str( scc) ,
835
- ) ;
836
804
837
805
// The existing value for `scc` is a lower-bound. This will
838
806
// consist of some set `{P} + {LB}` of points `{P}` and
@@ -917,21 +885,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
917
885
self . scc_values . placeholders_contained_in ( scc_b) . all ( |p| universe_a. can_name ( p. universe ) )
918
886
}
919
887
920
- /// Extend `scc` so that it can outlive some placeholder region
921
- /// from a universe it can't name; at present, the only way for
922
- /// this to be true is if `scc` outlives `'static`. This is
923
- /// actually stricter than necessary: ideally, we'd support bounds
924
- /// like `for<'a: 'b>` that might then allow us to approximate
925
- /// `'a` with `'b` and not `'static`. But it will have to do for
926
- /// now.
927
- fn add_incompatible_universe ( & mut self , scc : ConstraintSccIndex ) {
928
- debug ! ( "add_incompatible_universe(scc={:?})" , scc) ;
929
-
930
- let fr_static = self . universal_regions . fr_static ;
931
- self . scc_values . add_all_points ( scc) ;
932
- self . scc_values . add_element ( scc, fr_static) ;
933
- }
934
-
935
888
/// Once regions have been propagated, this method is used to see
936
889
/// whether the "type tests" produced by typeck were satisfied;
937
890
/// type tests encode type-outlives relationships like `T:
@@ -1563,7 +1516,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1563
1516
// Because this free region must be in the ROOT universe, we
1564
1517
// know it cannot contain any bound universes.
1565
1518
assert ! ( self . scc_universes[ longer_fr_scc] == ty:: UniverseIndex :: ROOT ) ;
1566
- debug_assert ! ( self . scc_values. placeholders_contained_in( longer_fr_scc) . next( ) . is_none( ) ) ;
1567
1519
1568
1520
// Only check all of the relations for the main representative of each
1569
1521
// SCC, otherwise just check that we outlive said representative. This
@@ -1772,20 +1724,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1772
1724
/// that cannot be named by `fr1`; in that case, we will require
1773
1725
/// that `fr1: 'static` because it is the only way to `fr1: r` to
1774
1726
/// be satisfied. (See `add_incompatible_universe`.)
1727
+ #[ instrument( skip( self ) , ret) ]
1775
1728
pub ( crate ) fn provides_universal_region (
1776
1729
& self ,
1777
1730
r : RegionVid ,
1778
1731
fr1 : RegionVid ,
1779
1732
fr2 : RegionVid ,
1780
1733
) -> bool {
1781
- debug ! ( "provides_universal_region(r={:?}, fr1={:?}, fr2={:?})" , r, fr1, fr2) ;
1782
- let result = {
1783
- r == fr2 || {
1784
- fr2 == self . universal_regions . fr_static && self . cannot_name_placeholder ( fr1, r)
1785
- }
1786
- } ;
1787
- debug ! ( "provides_universal_region: result = {:?}" , result) ;
1788
- result
1734
+ let fr2_is_static = fr2 == self . universal_regions . fr_static ;
1735
+ r == fr2 || ( fr2_is_static && self . cannot_name_placeholder ( fr1, r) )
1789
1736
}
1790
1737
1791
1738
/// If `r2` represents a placeholder region, then this returns
@@ -1900,6 +1847,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1900
1847
1901
1848
// This loop can be hot.
1902
1849
for constraint in outgoing_edges_from_graph {
1850
+ if matches ! ( constraint. category, ConstraintCategory :: IllegalUniverse ) {
1851
+ debug ! ( "Ignoring illegal universe constraint: {constraint:?}" ) ;
1852
+ continue ;
1853
+ }
1903
1854
handle_constraint ( constraint) ;
1904
1855
}
1905
1856
@@ -2249,7 +2200,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2249
2200
2250
2201
/// Access to the SCC constraint graph.
2251
2202
pub ( crate ) fn constraint_sccs ( & self ) -> & Sccs < RegionVid , ConstraintSccIndex > {
2252
- self . constraint_sccs . as_ref ( )
2203
+ & self . constraint_sccs
2253
2204
}
2254
2205
2255
2206
/// Access to the region graph, built from the outlives constraints.
0 commit comments