@@ -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,15 +360,13 @@ 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
- placeholder_indices,
366
365
member_constraints,
367
366
} = lowered_constraints;
368
367
369
368
debug ! ( "universal_regions: {:#?}" , universal_region_relations. universal_regions) ;
370
369
debug ! ( "outlives constraints: {:#?}" , outlives_constraints) ;
371
- debug ! ( "placeholder_indices: {:#?}" , placeholder_indices) ;
372
370
debug ! ( "type tests: {:#?}" , type_tests) ;
373
371
374
372
let constraint_graph = Frozen :: freeze ( outlives_constraints. graph ( definitions. len ( ) ) ) ;
@@ -377,8 +375,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
377
375
sccs_info ( infcx, & constraint_sccs) ;
378
376
}
379
377
380
- let mut scc_values =
381
- RegionValues :: new ( location_map, universal_regions. len ( ) , placeholder_indices) ;
378
+ let mut scc_values = RegionValues :: new ( location_map, universal_regions. len ( ) ) ;
382
379
383
380
for region in liveness_constraints. regions ( ) {
384
381
let scc = constraint_sccs. scc ( region) ;
@@ -388,7 +385,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
388
385
let member_constraints =
389
386
Rc :: new ( member_constraints. into_mapped ( |r| constraint_sccs. scc ( r) ) ) ;
390
387
391
- let mut result = Self {
388
+ for variable in definitions. indices ( ) {
389
+ if let NllRegionVariableOrigin :: FreeRegion = definitions[ variable] . origin {
390
+ // For each free, universally quantified region X:
391
+
392
+ let scc = constraint_sccs. scc ( variable) ;
393
+
394
+ // Add all nodes in the CFG to liveness constraints
395
+ liveness_constraints. add_all_points ( variable) ;
396
+ scc_values. add_all_points ( scc) ;
397
+
398
+ // Add `end(X)` into the set for X.
399
+ scc_values. add_element ( scc, variable) ;
400
+ }
401
+ }
402
+
403
+ Self {
392
404
definitions,
393
405
liveness_constraints,
394
406
constraints : outlives_constraints,
@@ -402,90 +414,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
402
414
scc_values,
403
415
type_tests,
404
416
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
417
}
490
418
}
491
419
@@ -542,14 +470,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
542
470
self . scc_values . region_value_str ( scc)
543
471
}
544
472
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
473
/// Once region solving has completed, this function will return the member constraints that
554
474
/// were applied to the value of a given SCC `scc`. See `AppliedMemberConstraint`.
555
475
pub ( crate ) fn applied_member_constraints (
@@ -901,8 +821,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
901
821
//
902
822
// It doesn't matter *what* universe because the promoted `T` will
903
823
// 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) ;
824
+ if let PlaceholderReachability :: Placeholders { min_placeholder, .. } =
825
+ self . scc_annotations [ r_scc] . reachable_placeholders ( )
826
+ {
827
+ debug ! (
828
+ "encountered placeholder in higher universe: {min_placeholder:?}, requiring 'static"
829
+ ) ;
830
+
906
831
let static_r = self . universal_regions ( ) . fr_static ;
907
832
propagated_outlives_requirements. push ( ClosureOutlivesRequirement {
908
833
subject,
@@ -1792,14 +1717,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1792
1717
match * element {
1793
1718
RegionElement :: Location ( l) => self . find_sub_region_live_at ( longer_fr, l) ,
1794
1719
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
1720
}
1804
1721
}
1805
1722
@@ -2082,6 +1999,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2082
1999
self . scc_annotations [ scc] . representative . rvid ( )
2083
2000
}
2084
2001
2002
+ /// If the representative of an SCC is a placeholder, return
2003
+ /// its originating `PlaceholderRegion`.
2004
+ pub ( crate ) fn placeholder_representative (
2005
+ & self ,
2006
+ scc : ConstraintSccIndex ,
2007
+ ) -> Option < ty:: PlaceholderRegion > {
2008
+ if let Representative :: Placeholder ( r) = self . scc_annotations [ scc] . representative
2009
+ && let NllRegionVariableOrigin :: Placeholder ( p) = self . definitions [ r] . origin
2010
+ {
2011
+ Some ( p)
2012
+ } else {
2013
+ None
2014
+ }
2015
+ }
2016
+
2085
2017
pub ( crate ) fn liveness_constraints ( & self ) -> & LivenessValues {
2086
2018
& self . liveness_constraints
2087
2019
}
0 commit comments