@@ -121,6 +121,11 @@ pub struct RegionInferenceContext<'tcx> {
121
121
/// Information about how the universally quantified regions in
122
122
/// scope on this function relate to one another.
123
123
universal_region_relations : Frozen < UniversalRegionRelations < ' tcx > > ,
124
+
125
+ /// Whether we are operating with polonius=next or not. False
126
+ /// means the regular NLL machinery is in use, true means use the
127
+ /// new Polonius constraint propagation.
128
+ polonius_next_enabled : bool ,
124
129
}
125
130
126
131
/// Each time that `apply_member_constraint` is successful, it appends
@@ -322,7 +327,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
322
327
/// The `outlives_constraints` and `type_tests` are an initial set
323
328
/// of constraints produced by the MIR type check.
324
329
pub ( crate ) fn new < ' cx > (
325
- _infcx : & BorrowckInferCtxt < ' cx , ' tcx > ,
330
+ infcx : & BorrowckInferCtxt < ' cx , ' tcx > ,
326
331
var_infos : VarInfos ,
327
332
universal_regions : Rc < UniversalRegions < ' tcx > > ,
328
333
placeholder_indices : Rc < PlaceholderIndices > ,
@@ -345,13 +350,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
345
350
. map ( |info| RegionDefinition :: new ( info. universe , info. origin ) )
346
351
. collect ( ) ;
347
352
348
- let constraints = Frozen :: freeze ( outlives_constraints) ;
353
+ let polonius_next_enabled = infcx. tcx . sess . opts . unstable_opts . polonius . is_next_enabled ( ) ;
354
+
355
+ let constraints = if polonius_next_enabled {
356
+ Frozen :: freeze (
357
+ outlives_constraints. placeholders_to_static ( & universal_regions, & definitions) ,
358
+ )
359
+ } else {
360
+ Frozen :: freeze ( outlives_constraints)
361
+ } ;
349
362
let constraint_graph = Frozen :: freeze ( constraints. graph ( definitions. len ( ) ) ) ;
350
363
let fr_static = universal_regions. fr_static ;
351
364
let constraint_sccs = Rc :: new ( constraints. compute_sccs ( & constraint_graph, fr_static) ) ;
352
365
353
366
if cfg ! ( debug_assertions) {
354
- sccs_info ( _infcx , constraint_sccs. clone ( ) ) ;
367
+ sccs_info ( infcx , constraint_sccs. clone ( ) ) ;
355
368
}
356
369
357
370
let mut scc_values =
@@ -386,6 +399,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
386
399
type_tests,
387
400
universal_regions,
388
401
universal_region_relations,
402
+ polonius_next_enabled,
389
403
} ;
390
404
391
405
result. init_free_and_bound_regions ( ) ;
@@ -535,7 +549,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
535
549
// This iterator has unstable order but we collect it all into an IndexVec
536
550
for ( external_name, variable) in self . universal_regions . named_universal_regions ( ) {
537
551
debug ! (
538
- "init_universal_regions : region {:?} has external name {:?}" ,
552
+ "init_free_and_bound_regions : region {:?} has external name {:?}" ,
539
553
variable, external_name
540
554
) ;
541
555
self . definitions [ variable] . external_name = Some ( external_name) ;
@@ -561,8 +575,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
561
575
// its universe `ui` and its extensions. So we
562
576
// can't just add it into `scc` unless the
563
577
// universe of the scc can name this region.
578
+ // This case is handled separately when Polonius
579
+ // is enabled.
564
580
let scc_universe = self . scc_universes [ scc] ;
565
- if scc_universe. can_name ( placeholder. universe ) {
581
+ if self . polonius_next_enabled || scc_universe. can_name ( placeholder. universe ) {
566
582
self . scc_values . add_element ( scc, placeholder) ;
567
583
} else {
568
584
debug ! (
@@ -760,12 +776,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
760
776
// Walk each SCC `B` such that `A: B`...
761
777
for & scc_b in constraint_sccs. successors ( scc_a) {
762
778
debug ! ( ?scc_b) ;
763
-
764
779
// ...and add elements from `B` into `A`. One complication
765
780
// arises because of universes: If `B` contains something
766
781
// that `A` cannot name, then `A` can only contain `B` if
767
782
// it outlives static.
768
- if self . universe_compatible ( scc_b, scc_a) {
783
+ if self . polonius_next_enabled || self . universe_compatible ( scc_b, scc_a) {
769
784
// `A` can name everything that is in `B`, so just
770
785
// merge the bits.
771
786
self . scc_values . add_region ( scc_a, scc_b) ;
@@ -828,7 +843,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
828
843
return ;
829
844
}
830
845
debug_assert ! (
831
- self . scc_values. placeholders_contained_in( scc) . next( ) . is_none( ) ,
846
+ self . polonius_next_enabled
847
+ || self . scc_values. placeholders_contained_in( scc) . next( ) . is_none( ) ,
832
848
"scc {:?} in a member constraint has placeholder value: {:?}" ,
833
849
scc,
834
850
self . scc_values. region_value_str( scc) ,
@@ -1563,7 +1579,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1563
1579
// Because this free region must be in the ROOT universe, we
1564
1580
// know it cannot contain any bound universes.
1565
1581
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( ) ) ;
1582
+ debug_assert ! (
1583
+ self . polonius_next_enabled
1584
+ || self . scc_values. placeholders_contained_in( longer_fr_scc) . next( ) . is_none( )
1585
+ ) ;
1567
1586
1568
1587
// Only check all of the relations for the main representative of each
1569
1588
// SCC, otherwise just check that we outlive said representative. This
0 commit comments