@@ -24,6 +24,7 @@ use rustc::mir::{
24
24
use rustc:: ty:: { self , RegionVid , Ty , TyCtxt , TypeFoldable } ;
25
25
use rustc:: util:: common:: { self , ErrorReported } ;
26
26
use rustc_data_structures:: bitvec:: BitVector ;
27
+ use rustc_data_structures:: fx:: FxHashSet ;
27
28
use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
28
29
use std:: fmt;
29
30
use std:: rc:: Rc ;
@@ -66,6 +67,7 @@ pub struct RegionInferenceContext<'tcx> {
66
67
67
68
/// The constraints we have accumulated and used during solving.
68
69
constraints : IndexVec < ConstraintIndex , OutlivesConstraint > ,
70
+ seen_constraints : FxHashSet < ( RegionVid , RegionVid ) > ,
69
71
70
72
/// Type constraints that we check after solving.
71
73
type_tests : Vec < TypeTest < ' tcx > > ,
@@ -143,6 +145,12 @@ pub struct OutlivesConstraint {
143
145
pub span : Span ,
144
146
}
145
147
148
+ impl OutlivesConstraint {
149
+ fn dedup_key ( & self ) -> ( RegionVid , RegionVid ) {
150
+ ( self . sup , self . sub )
151
+ }
152
+ }
153
+
146
154
newtype_index ! ( ConstraintIndex { DEBUG_FORMAT = "ConstraintIndex({})" } ) ;
147
155
148
156
/// A "type test" corresponds to an outlives constraint between a type
@@ -266,11 +274,16 @@ impl<'tcx> RegionInferenceContext<'tcx> {
266
274
liveness_constraints : RegionValues :: new ( elements, num_region_variables) ,
267
275
inferred_values : None ,
268
276
dependency_map : None ,
269
- constraints : IndexVec :: from_raw ( outlives_constraints) ,
277
+ constraints : Default :: default ( ) ,
278
+ seen_constraints : Default :: default ( ) ,
270
279
type_tests,
271
280
universal_regions,
272
281
} ;
273
282
283
+ for c in outlives_constraints {
284
+ result. add_outlives_iner ( c) ;
285
+ }
286
+
274
287
result. init_universal_regions ( ) ;
275
288
276
289
result
@@ -392,15 +405,29 @@ impl<'tcx> RegionInferenceContext<'tcx> {
392
405
sub : RegionVid ,
393
406
point : Location ,
394
407
) {
395
- debug ! ( "add_outlives({:?}: {:?} @ {:?}" , sup, sub, point) ;
396
- assert ! ( self . inferred_values. is_none( ) , "values already inferred" ) ;
397
- self . constraints . push ( OutlivesConstraint {
408
+ self . add_outlives_iner ( OutlivesConstraint {
398
409
span,
399
410
sup,
400
411
sub,
401
412
point,
402
413
next : None ,
403
- } ) ;
414
+ } )
415
+ }
416
+
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
+ }
404
431
}
405
432
406
433
/// Perform region inference and report errors if we see any
0 commit comments