@@ -64,15 +64,41 @@ pub enum Verify<'tcx> {
64
64
// outlive `RS`. Therefore verify that `R <= RS[i]` for some
65
65
// `i`. Inference variables may be involved (but this verification
66
66
// step doesn't influence inference).
67
- VerifyGenericBound ( GenericKind < ' tcx > , SubregionOrigin < ' tcx > , Region , Vec < Region > ) ,
67
+ VerifyGenericBound ( GenericKind < ' tcx > , SubregionOrigin < ' tcx > , Region , VerifyBound ) ,
68
68
}
69
69
70
- #[ derive( Clone , PartialEq , Eq ) ]
70
+ #[ derive( Copy , Clone , PartialEq , Eq ) ]
71
71
pub enum GenericKind < ' tcx > {
72
72
Param ( ty:: ParamTy ) ,
73
73
Projection ( ty:: ProjectionTy < ' tcx > ) ,
74
74
}
75
75
76
+ // When we introduce a verification step, we wish to test that a
77
+ // particular region (let's call it `'min`) meets some bound.
78
+ // The bound is described the by the following grammar:
79
+ #[ derive( Debug ) ]
80
+ pub enum VerifyBound {
81
+ // B = exists {R} --> some 'r in {R} must outlive 'min
82
+ //
83
+ // Put another way, the subject value is known to outlive all
84
+ // regions in {R}, so if any of those outlives 'min, then the
85
+ // bound is met.
86
+ AnyRegion ( Vec < Region > ) ,
87
+
88
+ // B = forall {R} --> all 'r in {R} must outlive 'min
89
+ //
90
+ // Put another way, the subject value is known to outlive some
91
+ // region in {R}, so if all of those outlives 'min, then the bound
92
+ // is met.
93
+ AllRegions ( Vec < Region > ) ,
94
+
95
+ // B = exists {B} --> 'min must meet some bound b in {B}
96
+ AnyBound ( Vec < VerifyBound > ) ,
97
+
98
+ // B = forall {B} --> 'min must meet all bounds b in {B}
99
+ AllBounds ( Vec < VerifyBound > ) ,
100
+ }
101
+
76
102
#[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
77
103
pub struct TwoRegions {
78
104
a : Region ,
@@ -102,12 +128,11 @@ pub enum RegionResolutionError<'tcx> {
102
128
/// `o` requires that `a <= b`, but this does not hold
103
129
ConcreteFailure ( SubregionOrigin < ' tcx > , Region , Region ) ,
104
130
105
- /// `GenericBoundFailure(p, s, a, bs )
131
+ /// `GenericBoundFailure(p, s, a)
106
132
///
107
133
/// The parameter/associated-type `p` must be known to outlive the lifetime
108
- /// `a`, but it is only known to outlive `bs` (and none of the
109
- /// regions in `bs` outlive `a`).
110
- GenericBoundFailure ( SubregionOrigin < ' tcx > , GenericKind < ' tcx > , Region , Vec < Region > ) ,
134
+ /// `a` (but none of the known bounds are sufficient).
135
+ GenericBoundFailure ( SubregionOrigin < ' tcx > , GenericKind < ' tcx > , Region ) ,
111
136
112
137
/// `SubSupConflict(v, sub_origin, sub_r, sup_origin, sup_r)`:
113
138
///
@@ -408,6 +433,14 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
408
433
debug ! ( "RegionVarBindings: add_verify({:?})" ,
409
434
verify) ;
410
435
436
+ // skip no-op cases known to be satisfied
437
+ match verify {
438
+ VerifyGenericBound ( _, _, _, VerifyBound :: AllBounds ( ref bs) ) if bs. len ( ) == 0 => {
439
+ return ;
440
+ }
441
+ _ => { }
442
+ }
443
+
411
444
let mut verifys = self . verifys . borrow_mut ( ) ;
412
445
let index = verifys. len ( ) ;
413
446
verifys. push ( verify) ;
@@ -497,8 +530,8 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
497
530
origin : SubregionOrigin < ' tcx > ,
498
531
kind : GenericKind < ' tcx > ,
499
532
sub : Region ,
500
- sups : Vec < Region > ) {
501
- self . add_verify ( VerifyGenericBound ( kind, origin, sub, sups ) ) ;
533
+ bound : VerifyBound ) {
534
+ self . add_verify ( VerifyGenericBound ( kind, origin, sub, bound ) ) ;
502
535
}
503
536
504
537
pub fn lub_regions ( & self ,
@@ -663,12 +696,11 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
663
696
& mut result_set, r,
664
697
a, b) ;
665
698
}
666
- VerifyGenericBound ( _, _, a, ref bs) => {
667
- for & b in bs {
668
- consider_adding_bidirectional_edges (
669
- & mut result_set, r,
670
- a, b) ;
671
- }
699
+ VerifyGenericBound ( _, _, a, ref bound) => {
700
+ bound. for_each_region ( & mut |b| {
701
+ consider_adding_bidirectional_edges ( & mut result_set, r,
702
+ a, b)
703
+ } ) ;
672
704
}
673
705
}
674
706
}
@@ -1258,26 +1290,22 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
1258
1290
continue ;
1259
1291
}
1260
1292
1261
- debug ! ( "ConcreteFailure: !(sub <= sup): sub= {:?}, sup= {:?}" ,
1262
- sub,
1263
- sup ) ;
1293
+ debug ! ( "region inference error at {:?}: {:?} <= {:?} is not true " ,
1294
+ origin , sub, sup ) ;
1295
+
1264
1296
errors. push ( ConcreteFailure ( ( * origin) . clone ( ) , sub, sup) ) ;
1265
1297
}
1266
1298
1267
- VerifyGenericBound ( ref kind, ref origin, sub, ref sups ) => {
1299
+ VerifyGenericBound ( ref kind, ref origin, sub, ref bound ) => {
1268
1300
let sub = normalize ( values, sub) ;
1269
- if sups. iter ( )
1270
- . map ( |& sup| normalize ( values, sup) )
1271
- . any ( |sup| free_regions. is_subregion_of ( self . tcx , sub, sup) )
1272
- {
1301
+ if bound. is_met ( self . tcx , free_regions, values, sub) {
1273
1302
continue ;
1274
1303
}
1275
1304
1276
- let sups = sups. iter ( ) . map ( |& sup| normalize ( values, sup) )
1277
- . collect ( ) ;
1278
- errors. push (
1279
- GenericBoundFailure (
1280
- ( * origin) . clone ( ) , kind. clone ( ) , sub, sups) ) ;
1305
+ debug ! ( "region inference error at {:?}: verifying {:?} <= {:?}" ,
1306
+ origin, sub, bound) ;
1307
+
1308
+ errors. push ( GenericBoundFailure ( ( * origin) . clone ( ) , kind. clone ( ) , sub) ) ;
1281
1309
}
1282
1310
}
1283
1311
}
@@ -1438,10 +1466,12 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
1438
1466
if !free_regions. is_subregion_of ( self . tcx ,
1439
1467
lower_bound. region ,
1440
1468
upper_bound. region ) {
1441
- debug ! ( "pushing SubSupConflict sub: {:?} sup: {:?}" ,
1442
- lower_bound. region, upper_bound. region) ;
1469
+ let origin = ( * self . var_origins . borrow ( ) ) [ node_idx. index as usize ] . clone ( ) ;
1470
+ debug ! ( "region inference error at {:?} for {:?}: \
1471
+ SubSupConflict sub: {:?} sup: {:?}",
1472
+ origin, node_idx, lower_bound. region, upper_bound. region) ;
1443
1473
errors. push ( SubSupConflict (
1444
- ( * self . var_origins . borrow ( ) ) [ node_idx . index as usize ] . clone ( ) ,
1474
+ origin ,
1445
1475
lower_bound. origin . clone ( ) ,
1446
1476
lower_bound. region ,
1447
1477
upper_bound. origin . clone ( ) ,
@@ -1484,16 +1514,20 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
1484
1514
match self . glb_concrete_regions ( free_regions,
1485
1515
upper_bound_1. region ,
1486
1516
upper_bound_2. region ) {
1487
- Ok ( _) => { }
1488
- Err ( _) => {
1489
- errors. push ( SupSupConflict (
1490
- ( * self . var_origins . borrow ( ) ) [ node_idx. index as usize ] . clone ( ) ,
1491
- upper_bound_1. origin . clone ( ) ,
1492
- upper_bound_1. region ,
1493
- upper_bound_2. origin . clone ( ) ,
1494
- upper_bound_2. region ) ) ;
1495
- return ;
1496
- }
1517
+ Ok ( _) => { }
1518
+ Err ( _) => {
1519
+ let origin = ( * self . var_origins . borrow ( ) ) [ node_idx. index as usize ] . clone ( ) ;
1520
+ debug ! ( "region inference error at {:?} for {:?}: \
1521
+ SupSupConflict sub: {:?} sup: {:?}",
1522
+ origin, node_idx, upper_bound_1. region, upper_bound_2. region) ;
1523
+ errors. push ( SupSupConflict (
1524
+ origin,
1525
+ upper_bound_1. origin . clone ( ) ,
1526
+ upper_bound_1. region ,
1527
+ upper_bound_2. origin . clone ( ) ,
1528
+ upper_bound_2. region ) ) ;
1529
+ return ;
1530
+ }
1497
1531
}
1498
1532
}
1499
1533
}
@@ -1676,3 +1710,82 @@ impl<'tcx> GenericKind<'tcx> {
1676
1710
}
1677
1711
}
1678
1712
}
1713
+
1714
+ impl VerifyBound {
1715
+ fn for_each_region ( & self , f : & mut FnMut ( ty:: Region ) ) {
1716
+ match self {
1717
+ & VerifyBound :: AnyRegion ( ref rs) |
1718
+ & VerifyBound :: AllRegions ( ref rs) =>
1719
+ for & r in rs { f ( r) ; } ,
1720
+
1721
+ & VerifyBound :: AnyBound ( ref bs) |
1722
+ & VerifyBound :: AllBounds ( ref bs) =>
1723
+ for b in bs { b. for_each_region ( f) ; } ,
1724
+ }
1725
+ }
1726
+
1727
+ pub fn must_hold ( & self ) -> bool {
1728
+ match self {
1729
+ & VerifyBound :: AnyRegion ( ref bs) => bs. contains ( & ty:: ReStatic ) ,
1730
+ & VerifyBound :: AllRegions ( ref bs) => bs. is_empty ( ) ,
1731
+ & VerifyBound :: AnyBound ( ref bs) => bs. iter ( ) . any ( |b| b. must_hold ( ) ) ,
1732
+ & VerifyBound :: AllBounds ( ref bs) => bs. iter ( ) . all ( |b| b. must_hold ( ) ) ,
1733
+ }
1734
+ }
1735
+
1736
+ pub fn cannot_hold ( & self ) -> bool {
1737
+ match self {
1738
+ & VerifyBound :: AnyRegion ( ref bs) => bs. is_empty ( ) ,
1739
+ & VerifyBound :: AllRegions ( ref bs) => bs. contains ( & ty:: ReEmpty ) ,
1740
+ & VerifyBound :: AnyBound ( ref bs) => bs. iter ( ) . all ( |b| b. cannot_hold ( ) ) ,
1741
+ & VerifyBound :: AllBounds ( ref bs) => bs. iter ( ) . any ( |b| b. cannot_hold ( ) ) ,
1742
+ }
1743
+ }
1744
+
1745
+ pub fn or ( self , vb : VerifyBound ) -> VerifyBound {
1746
+ if self . must_hold ( ) || vb. cannot_hold ( ) {
1747
+ self
1748
+ } else if self . cannot_hold ( ) || vb. must_hold ( ) {
1749
+ vb
1750
+ } else {
1751
+ VerifyBound :: AnyBound ( vec ! [ self , vb] )
1752
+ }
1753
+ }
1754
+
1755
+ pub fn and ( self , vb : VerifyBound ) -> VerifyBound {
1756
+ if self . must_hold ( ) && vb. must_hold ( ) {
1757
+ self
1758
+ } else if self . cannot_hold ( ) && vb. cannot_hold ( ) {
1759
+ self
1760
+ } else {
1761
+ VerifyBound :: AllBounds ( vec ! [ self , vb] )
1762
+ }
1763
+ }
1764
+
1765
+ fn is_met < ' tcx > ( & self ,
1766
+ tcx : & ty:: ctxt < ' tcx > ,
1767
+ free_regions : & FreeRegionMap ,
1768
+ var_values : & Vec < VarValue > ,
1769
+ min : ty:: Region )
1770
+ -> bool {
1771
+ match self {
1772
+ & VerifyBound :: AnyRegion ( ref rs) =>
1773
+ rs. iter ( )
1774
+ . map ( |& r| normalize ( var_values, r) )
1775
+ . any ( |r| free_regions. is_subregion_of ( tcx, min, r) ) ,
1776
+
1777
+ & VerifyBound :: AllRegions ( ref rs) =>
1778
+ rs. iter ( )
1779
+ . map ( |& r| normalize ( var_values, r) )
1780
+ . all ( |r| free_regions. is_subregion_of ( tcx, min, r) ) ,
1781
+
1782
+ & VerifyBound :: AnyBound ( ref bs) =>
1783
+ bs. iter ( )
1784
+ . any ( |b| b. is_met ( tcx, free_regions, var_values, min) ) ,
1785
+
1786
+ & VerifyBound :: AllBounds ( ref bs) =>
1787
+ bs. iter ( )
1788
+ . all ( |b| b. is_met ( tcx, free_regions, var_values, min) ) ,
1789
+ }
1790
+ }
1791
+ }
0 commit comments