@@ -28,7 +28,7 @@ use crate::constraints::graph::{self, NormalConstraintGraph, RegionGraph};
28
28
use crate :: constraints:: { ConstraintSccIndex , OutlivesConstraint , OutlivesConstraintSet } ;
29
29
use crate :: dataflow:: BorrowIndex ;
30
30
use crate :: diagnostics:: { RegionErrorKind , RegionErrors , UniverseInfo } ;
31
- use crate :: handle_placeholders:: { LoweredConstraints , RegionTracker } ;
31
+ use crate :: handle_placeholders:: { LoweredConstraints , PlaceholderReachability , RegionTracker } ;
32
32
use crate :: member_constraints:: { MemberConstraintSet , NllMemberConstraintIndex } ;
33
33
use crate :: polonius:: LiveLoans ;
34
34
use crate :: polonius:: legacy:: PoloniusOutput ;
@@ -360,7 +360,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
360
360
outlives_constraints,
361
361
scc_annotations,
362
362
type_tests,
363
- liveness_constraints,
363
+ mut liveness_constraints,
364
364
universe_causes,
365
365
placeholder_indices,
366
366
member_constraints,
@@ -377,8 +377,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
377
377
sccs_info ( infcx, & constraint_sccs) ;
378
378
}
379
379
380
- let mut scc_values =
381
- RegionValues :: new ( location_map, universal_regions. len ( ) , placeholder_indices) ;
380
+ let mut scc_values = RegionValues :: new ( location_map, universal_regions. len ( ) ) ;
382
381
383
382
for region in liveness_constraints. regions ( ) {
384
383
let scc = constraint_sccs. scc ( region) ;
@@ -388,7 +387,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
388
387
let member_constraints =
389
388
Rc :: new ( member_constraints. into_mapped ( |r| constraint_sccs. scc ( r) ) ) ;
390
389
391
- let mut result = Self {
390
+ for variable in definitions. indices ( ) {
391
+ if let NllRegionVariableOrigin :: FreeRegion = definitions[ variable] . origin {
392
+ // For each free, universally quantified region X:
393
+
394
+ let scc = constraint_sccs. scc ( variable) ;
395
+
396
+ // Add all nodes in the CFG to liveness constraints
397
+ liveness_constraints. add_all_points ( variable) ;
398
+ scc_values. add_all_points ( scc) ;
399
+
400
+ // Add `end(X)` into the set for X.
401
+ scc_values. add_element ( scc, variable) ;
402
+ }
403
+ }
404
+
405
+ Self {
392
406
definitions,
393
407
liveness_constraints,
394
408
constraints : outlives_constraints,
@@ -402,90 +416,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
402
416
scc_values,
403
417
type_tests,
404
418
universal_region_relations,
405
- } ;
406
-
407
- result. init_free_and_bound_regions ( ) ;
408
-
409
- result
410
- }
411
-
412
- /// Initializes the region variables for each universally
413
- /// quantified region (lifetime parameter). The first N variables
414
- /// always correspond to the regions appearing in the function
415
- /// signature (both named and anonymous) and where-clauses. This
416
- /// function iterates over those regions and initializes them with
417
- /// minimum values.
418
- ///
419
- /// For example:
420
- /// ```
421
- /// fn foo<'a, 'b>( /* ... */ ) where 'a: 'b { /* ... */ }
422
- /// ```
423
- /// would initialize two variables like so:
424
- /// ```ignore (illustrative)
425
- /// R0 = { CFG, R0 } // 'a
426
- /// R1 = { CFG, R0, R1 } // 'b
427
- /// ```
428
- /// Here, R0 represents `'a`, and it contains (a) the entire CFG
429
- /// and (b) any universally quantified regions that it outlives,
430
- /// which in this case is just itself. R1 (`'b`) in contrast also
431
- /// outlives `'a` and hence contains R0 and R1.
432
- ///
433
- /// This bit of logic also handles invalid universe relations
434
- /// for higher-kinded types.
435
- ///
436
- /// We Walk each SCC `A` and `B` such that `A: B`
437
- /// and ensure that universe(A) can see universe(B).
438
- ///
439
- /// This serves to enforce the 'empty/placeholder' hierarchy
440
- /// (described in more detail on `RegionKind`):
441
- ///
442
- /// ```ignore (illustrative)
443
- /// static -----+
444
- /// | |
445
- /// empty(U0) placeholder(U1)
446
- /// | /
447
- /// empty(U1)
448
- /// ```
449
- ///
450
- /// In particular, imagine we have variables R0 in U0 and R1
451
- /// created in U1, and constraints like this;
452
- ///
453
- /// ```ignore (illustrative)
454
- /// R1: !1 // R1 outlives the placeholder in U1
455
- /// R1: R0 // R1 outlives R0
456
- /// ```
457
- ///
458
- /// Here, we wish for R1 to be `'static`, because it
459
- /// cannot outlive `placeholder(U1)` and `empty(U0)` any other way.
460
- ///
461
- /// Thanks to this loop, what happens is that the `R1: R0`
462
- /// constraint has lowered the universe of `R1` to `U0`, which in turn
463
- /// means that the `R1: !1` constraint here will cause
464
- /// `R1` to become `'static`.
465
- fn init_free_and_bound_regions ( & mut self ) {
466
- for variable in self . definitions . indices ( ) {
467
- let scc = self . constraint_sccs . scc ( variable) ;
468
-
469
- match self . definitions [ variable] . origin {
470
- NllRegionVariableOrigin :: FreeRegion => {
471
- // For each free, universally quantified region X:
472
-
473
- // Add all nodes in the CFG to liveness constraints
474
- self . liveness_constraints . add_all_points ( variable) ;
475
- self . scc_values . add_all_points ( scc) ;
476
-
477
- // Add `end(X)` into the set for X.
478
- self . scc_values . add_element ( scc, variable) ;
479
- }
480
-
481
- NllRegionVariableOrigin :: Placeholder ( placeholder) => {
482
- self . scc_values . add_element ( scc, placeholder) ;
483
- }
484
-
485
- NllRegionVariableOrigin :: Existential { .. } => {
486
- // For existential, regions, nothing to do.
487
- }
488
- }
489
419
}
490
420
}
491
421
@@ -542,14 +472,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
542
472
self . scc_values . region_value_str ( scc)
543
473
}
544
474
545
- pub ( crate ) fn placeholders_contained_in (
546
- & self ,
547
- r : RegionVid ,
548
- ) -> impl Iterator < Item = ty:: PlaceholderRegion > {
549
- let scc = self . constraint_sccs . scc ( r) ;
550
- self . scc_values . placeholders_contained_in ( scc)
551
- }
552
-
553
475
/// Once region solving has completed, this function will return the member constraints that
554
476
/// were applied to the value of a given SCC `scc`. See `AppliedMemberConstraint`.
555
477
pub ( crate ) fn applied_member_constraints (
@@ -901,8 +823,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
901
823
//
902
824
// It doesn't matter *what* universe because the promoted `T` will
903
825
// always be in the root universe.
904
- if let Some ( p) = self . scc_values . placeholders_contained_in ( r_scc) . next ( ) {
905
- debug ! ( "encountered placeholder in higher universe: {:?}, requiring 'static" , p) ;
826
+ if let PlaceholderReachability :: Placeholders { min_placeholder, .. } =
827
+ self . scc_annotations [ r_scc] . reachable_placeholders ( )
828
+ {
829
+ debug ! (
830
+ "encountered placeholder in higher universe: {min_placeholder:?}, requiring 'static"
831
+ ) ;
832
+
906
833
let static_r = self . universal_regions ( ) . fr_static ;
907
834
propagated_outlives_requirements. push ( ClosureOutlivesRequirement {
908
835
subject,
@@ -1792,14 +1719,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1792
1719
match * element {
1793
1720
RegionElement :: Location ( l) => self . find_sub_region_live_at ( longer_fr, l) ,
1794
1721
RegionElement :: RootUniversalRegion ( r) => r,
1795
- RegionElement :: PlaceholderRegion ( error_placeholder) => self
1796
- . definitions
1797
- . iter_enumerated ( )
1798
- . find_map ( |( r, definition) | match definition. origin {
1799
- NllRegionVariableOrigin :: Placeholder ( p) if p == error_placeholder => Some ( r) ,
1800
- _ => None ,
1801
- } )
1802
- . unwrap ( ) ,
1803
1722
}
1804
1723
}
1805
1724
@@ -2082,6 +2001,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2082
2001
self . scc_annotations [ scc] . representative . rvid ( )
2083
2002
}
2084
2003
2004
+ /// If the representative of an SCC is a placeholder, return
2005
+ /// its originating `PlaceholderRegion`.
2006
+ pub ( crate ) fn placeholder_representative (
2007
+ & self ,
2008
+ scc : ConstraintSccIndex ,
2009
+ ) -> Option < ty:: PlaceholderRegion > {
2010
+ if let Representative :: Placeholder ( r) = self . scc_annotations [ scc] . representative
2011
+ && let NllRegionVariableOrigin :: Placeholder ( p) = self . definitions [ r] . origin
2012
+ {
2013
+ Some ( p)
2014
+ } else {
2015
+ None
2016
+ }
2017
+ }
2018
+
2085
2019
pub ( crate ) fn liveness_constraints ( & self ) -> & LivenessValues {
2086
2020
& self . liveness_constraints
2087
2021
}
0 commit comments