10
10
11
11
use super :: universal_regions:: UniversalRegions ;
12
12
use borrow_check:: nll:: region_infer:: values:: ToElementIndex ;
13
+ use borrow_check:: nll:: constraint_set:: ConstraintSet ;
13
14
use rustc:: hir:: def_id:: DefId ;
14
15
use rustc:: infer:: canonical:: QueryRegionConstraint ;
15
16
use rustc:: infer:: error_reporting:: nice_region_error:: NiceRegionError ;
@@ -24,7 +25,6 @@ use rustc::mir::{
24
25
use rustc:: ty:: { self , RegionVid , Ty , TyCtxt , TypeFoldable } ;
25
26
use rustc:: util:: common:: { self , ErrorReported } ;
26
27
use rustc_data_structures:: bitvec:: BitVector ;
27
- use rustc_data_structures:: fx:: FxHashSet ;
28
28
use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
29
29
use std:: fmt;
30
30
use std:: rc:: Rc ;
@@ -66,8 +66,7 @@ pub struct RegionInferenceContext<'tcx> {
66
66
dependency_map : Option < IndexVec < RegionVid , Option < ConstraintIndex > > > ,
67
67
68
68
/// The constraints we have accumulated and used during solving.
69
- constraints : IndexVec < ConstraintIndex , OutlivesConstraint > ,
70
- seen_constraints : FxHashSet < ( RegionVid , RegionVid ) > ,
69
+ constraints : ConstraintSet ,
71
70
72
71
/// Type constraints that we check after solving.
73
72
type_tests : Vec < TypeTest < ' tcx > > ,
@@ -146,7 +145,7 @@ pub struct OutlivesConstraint {
146
145
}
147
146
148
147
impl OutlivesConstraint {
149
- fn dedup_key ( & self ) -> ( RegionVid , RegionVid ) {
148
+ pub fn dedup_key ( & self ) -> ( RegionVid , RegionVid ) {
150
149
( self . sup , self . sub )
151
150
}
152
151
}
@@ -251,11 +250,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
251
250
var_infos : VarInfos ,
252
251
universal_regions : UniversalRegions < ' tcx > ,
253
252
mir : & Mir < ' tcx > ,
254
- mut outlives_constraints : Vec < OutlivesConstraint > ,
253
+ outlives_constraints : ConstraintSet ,
255
254
type_tests : Vec < TypeTest < ' tcx > > ,
256
255
) -> Self {
257
256
// The `next` field should not yet have been initialized:
258
- debug_assert ! ( outlives_constraints. iter( ) . all( |c| c. next. is_none( ) ) ) ;
257
+ debug_assert ! ( outlives_constraints. iner ( ) . iter( ) . all( |c| c. next. is_none( ) ) ) ;
259
258
260
259
let num_region_variables = var_infos. len ( ) ;
261
260
let num_universal_regions = universal_regions. len ( ) ;
@@ -268,18 +267,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
268
267
. map ( |info| RegionDefinition :: new ( info. origin ) )
269
268
. collect ( ) ;
270
269
271
- let mut seen_constraints: FxHashSet < ( RegionVid , RegionVid ) > = Default :: default ( ) ;
272
-
273
- outlives_constraints. retain ( |c| c. sup != c. sub && seen_constraints. insert ( c. dedup_key ( ) ) ) ;
274
-
275
270
let mut result = Self {
276
271
definitions,
277
272
elements : elements. clone ( ) ,
278
273
liveness_constraints : RegionValues :: new ( elements, num_region_variables) ,
279
274
inferred_values : None ,
280
275
dependency_map : None ,
281
- constraints : IndexVec :: from_raw ( outlives_constraints) ,
282
- seen_constraints,
276
+ constraints : outlives_constraints,
283
277
type_tests,
284
278
universal_regions,
285
279
} ;
@@ -405,7 +399,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
405
399
sub : RegionVid ,
406
400
point : Location ,
407
401
) {
408
- self . add_outlives_iner ( OutlivesConstraint {
402
+ assert ! ( self . inferred_values. is_none( ) , "values already inferred" ) ;
403
+ self . constraints . push ( OutlivesConstraint {
409
404
span,
410
405
sup,
411
406
sub,
@@ -414,22 +409,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
414
409
} )
415
410
}
416
411
417
- /// Indicates that the region variable `sup` must outlive `sub` is live at the point `point`.
418
- fn add_outlives_iner (
419
- & mut self ,
420
- outlives_constraint : OutlivesConstraint
421
- ) {
422
- debug ! ( "add_outlives({:?}: {:?} @ {:?}" , outlives_constraint. sup, outlives_constraint. sub, outlives_constraint. point) ;
423
- assert ! ( self . inferred_values. is_none( ) , "values already inferred" ) ;
424
- if outlives_constraint. sup == outlives_constraint. sub {
425
- // 'a: 'a is pretty uninteresting
426
- return ;
427
- }
428
- if self . seen_constraints . insert ( outlives_constraint. dedup_key ( ) ) {
429
- self . constraints . push ( outlives_constraint) ;
430
- }
431
- }
432
-
433
412
/// Perform region inference and report errors if we see any
434
413
/// unsatisfiable constraints. If this is a closure, returns the
435
414
/// region requirements to propagate to our creator, if any.
@@ -497,7 +476,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
497
476
fn compute_region_values ( & self , _mir : & Mir < ' tcx > ) -> RegionValues {
498
477
debug ! ( "compute_region_values()" ) ;
499
478
debug ! ( "compute_region_values: constraints={:#?}" , {
500
- let mut constraints: Vec <_> = self . constraints. iter( ) . collect( ) ;
479
+ let mut constraints: Vec <_> = self . constraints. iner ( ) . iter( ) . collect( ) ;
501
480
constraints. sort( ) ;
502
481
constraints
503
482
} ) ;
@@ -509,7 +488,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
509
488
let dependency_map = self . dependency_map . as_ref ( ) . unwrap ( ) ;
510
489
511
490
// Constraints that may need to be repropagated (initially all):
512
- let mut dirty_list: Vec < _ > = self . constraints . indices ( ) . collect ( ) ;
491
+ let mut dirty_list: Vec < _ > = self . constraints . iner ( ) . indices ( ) . collect ( ) ;
513
492
514
493
// Set to 0 for each constraint that is on the dirty list:
515
494
let mut clean_bit_vec = BitVector :: new ( dirty_list. len ( ) ) ;
@@ -518,7 +497,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
518
497
while let Some ( constraint_idx) = dirty_list. pop ( ) {
519
498
clean_bit_vec. insert ( constraint_idx. index ( ) ) ;
520
499
521
- let constraint = & self . constraints [ constraint_idx] ;
500
+ let constraint = & self . constraints . iner ( ) [ constraint_idx] ;
522
501
debug ! ( "propagate_constraints: constraint={:?}" , constraint) ;
523
502
524
503
if inferred_values. add_region ( constraint. sup , constraint. sub ) {
@@ -530,7 +509,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
530
509
if clean_bit_vec. remove ( dep_idx. index ( ) ) {
531
510
dirty_list. push ( dep_idx) ;
532
511
}
533
- opt_dep_idx = self . constraints [ dep_idx] . next ;
512
+ opt_dep_idx = self . constraints . iner ( ) [ dep_idx] . next ;
534
513
}
535
514
}
536
515
@@ -547,7 +526,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
547
526
fn build_dependency_map ( & mut self ) -> IndexVec < RegionVid , Option < ConstraintIndex > > {
548
527
let mut map = IndexVec :: from_elem ( None , & self . definitions ) ;
549
528
550
- for ( idx, constraint) in self . constraints . iter_enumerated_mut ( ) . rev ( ) {
529
+ for ( idx, constraint) in self . constraints . iner_mut ( ) . iter_enumerated_mut ( ) . rev ( ) {
551
530
let mut head = & mut map[ constraint. sub ] ;
552
531
debug_assert ! ( constraint. next. is_none( ) ) ;
553
532
constraint. next = * head;
@@ -995,7 +974,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
995
974
) ;
996
975
997
976
let blame_index = self . blame_constraint ( longer_fr, shorter_fr) ;
998
- let blame_span = self . constraints [ blame_index] . span ;
977
+ let blame_span = self . constraints . iner ( ) [ blame_index] . span ;
999
978
1000
979
if let Some ( propagated_outlives_requirements) = propagated_outlives_requirements {
1001
980
// Shrink `fr` until we find a non-local region (if we do).
@@ -1086,7 +1065,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1086
1065
// - `fr1: X` transitively
1087
1066
// - and `Y` is live at `elem`
1088
1067
let index = self . blame_constraint ( fr1, elem) ;
1089
- let region_sub = self . constraints [ index] . sub ;
1068
+ let region_sub = self . constraints . iner ( ) [ index] . sub ;
1090
1069
1091
1070
// then return why `Y` was live at `elem`
1092
1071
self . liveness_constraints . cause ( region_sub, elem)
@@ -1107,6 +1086,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1107
1086
// of dependencies, which doesn't account for the locations of
1108
1087
// contraints at all. But it will do for now.
1109
1088
let relevant_constraint = self . constraints
1089
+ . iner ( )
1110
1090
. iter_enumerated ( )
1111
1091
. filter_map ( |( i, constraint) | {
1112
1092
if !self . liveness_constraints . contains ( constraint. sub , elem) {
@@ -1142,7 +1122,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1142
1122
1143
1123
while changed {
1144
1124
changed = false ;
1145
- for constraint in & self . constraints {
1125
+ for constraint in self . constraints . iner ( ) {
1146
1126
if let Some ( n) = result_set[ constraint. sup ] {
1147
1127
let m = n + 1 ;
1148
1128
if result_set[ constraint. sub ]
0 commit comments