@@ -65,15 +65,41 @@ pub enum Verify<'tcx> {
65
65
// outlive `RS`. Therefore verify that `R <= RS[i]` for some
66
66
// `i`. Inference variables may be involved (but this verification
67
67
// step doesn't influence inference).
68
- VerifyGenericBound ( GenericKind < ' tcx > , SubregionOrigin < ' tcx > , Region , Vec < Region > ) ,
68
+ VerifyGenericBound ( GenericKind < ' tcx > , SubregionOrigin < ' tcx > , Region , VerifyBound ) ,
69
69
}
70
70
71
- #[ derive( Clone , PartialEq , Eq ) ]
71
+ #[ derive( Copy , Clone , PartialEq , Eq ) ]
72
72
pub enum GenericKind < ' tcx > {
73
73
Param ( ty:: ParamTy ) ,
74
74
Projection ( ty:: ProjectionTy < ' tcx > ) ,
75
75
}
76
76
77
+ // When we introduce a verification step, we wish to test that a
78
+ // particular region (let's call it `'min`) meets some bound.
79
+ // The bound is described the by the following grammar:
80
+ #[ derive( Debug ) ]
81
+ pub enum VerifyBound {
82
+ // B = exists {R} --> some 'r in {R} must outlive 'min
83
+ //
84
+ // Put another way, the subject value is known to outlive all
85
+ // regions in {R}, so if any of those outlives 'min, then the
86
+ // bound is met.
87
+ AnyRegion ( Vec < Region > ) ,
88
+
89
+ // B = forall {R} --> all 'r in {R} must outlive 'min
90
+ //
91
+ // Put another way, the subject value is known to outlive some
92
+ // region in {R}, so if all of those outlives 'min, then the bound
93
+ // is met.
94
+ AllRegions ( Vec < Region > ) ,
95
+
96
+ // B = exists {B} --> 'min must meet some bound b in {B}
97
+ AnyBound ( Vec < VerifyBound > ) ,
98
+
99
+ // B = forall {B} --> 'min must meet all bounds b in {B}
100
+ AllBounds ( Vec < VerifyBound > ) ,
101
+ }
102
+
77
103
#[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
78
104
pub struct TwoRegions {
79
105
a : Region ,
@@ -103,12 +129,11 @@ pub enum RegionResolutionError<'tcx> {
103
129
/// `o` requires that `a <= b`, but this does not hold
104
130
ConcreteFailure ( SubregionOrigin < ' tcx > , Region , Region ) ,
105
131
106
- /// `GenericBoundFailure(p, s, a, bs )
132
+ /// `GenericBoundFailure(p, s, a)
107
133
///
108
134
/// The parameter/associated-type `p` must be known to outlive the lifetime
109
- /// `a`, but it is only known to outlive `bs` (and none of the
110
- /// regions in `bs` outlive `a`).
111
- GenericBoundFailure ( SubregionOrigin < ' tcx > , GenericKind < ' tcx > , Region , Vec < Region > ) ,
135
+ /// `a` (but none of the known bounds are sufficient).
136
+ GenericBoundFailure ( SubregionOrigin < ' tcx > , GenericKind < ' tcx > , Region ) ,
112
137
113
138
/// `SubSupConflict(v, sub_origin, sub_r, sup_origin, sup_r)`:
114
139
///
@@ -409,6 +434,14 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
409
434
debug ! ( "RegionVarBindings: add_verify({:?})" ,
410
435
verify) ;
411
436
437
+ // skip no-op cases known to be satisfied
438
+ match verify {
439
+ VerifyGenericBound ( _, _, _, VerifyBound :: AllBounds ( ref bs) ) if bs. len ( ) == 0 => {
440
+ return ;
441
+ }
442
+ _ => { }
443
+ }
444
+
412
445
let mut verifys = self . verifys . borrow_mut ( ) ;
413
446
let index = verifys. len ( ) ;
414
447
verifys. push ( verify) ;
@@ -498,8 +531,8 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
498
531
origin : SubregionOrigin < ' tcx > ,
499
532
kind : GenericKind < ' tcx > ,
500
533
sub : Region ,
501
- sups : Vec < Region > ) {
502
- self . add_verify ( VerifyGenericBound ( kind, origin, sub, sups ) ) ;
534
+ bound : VerifyBound ) {
535
+ self . add_verify ( VerifyGenericBound ( kind, origin, sub, bound ) ) ;
503
536
}
504
537
505
538
pub fn lub_regions ( & self ,
@@ -664,12 +697,11 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
664
697
& mut result_set, r,
665
698
a, b) ;
666
699
}
667
- VerifyGenericBound ( _, _, a, ref bs) => {
668
- for & b in bs {
669
- consider_adding_bidirectional_edges (
670
- & mut result_set, r,
671
- a, b) ;
672
- }
700
+ VerifyGenericBound ( _, _, a, ref bound) => {
701
+ bound. for_each_region ( & mut |b| {
702
+ consider_adding_bidirectional_edges ( & mut result_set, r,
703
+ a, b)
704
+ } ) ;
673
705
}
674
706
}
675
707
}
@@ -1264,20 +1296,13 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
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
+ errors. push ( GenericBoundFailure ( ( * origin) . clone ( ) , kind. clone ( ) , sub) ) ;
1281
1306
}
1282
1307
}
1283
1308
}
@@ -1723,3 +1748,82 @@ impl<'tcx> GenericKind<'tcx> {
1723
1748
}
1724
1749
}
1725
1750
}
1751
+
1752
+ impl VerifyBound {
1753
+ fn for_each_region ( & self , f : & mut FnMut ( ty:: Region ) ) {
1754
+ match self {
1755
+ & VerifyBound :: AnyRegion ( ref rs) |
1756
+ & VerifyBound :: AllRegions ( ref rs) =>
1757
+ for & r in rs { f ( r) ; } ,
1758
+
1759
+ & VerifyBound :: AnyBound ( ref bs) |
1760
+ & VerifyBound :: AllBounds ( ref bs) =>
1761
+ for b in bs { b. for_each_region ( f) ; } ,
1762
+ }
1763
+ }
1764
+
1765
+ pub fn must_hold ( & self ) -> bool {
1766
+ match self {
1767
+ & VerifyBound :: AnyRegion ( ref bs) => bs. contains ( & ty:: ReStatic ) ,
1768
+ & VerifyBound :: AllRegions ( ref bs) => bs. is_empty ( ) ,
1769
+ & VerifyBound :: AnyBound ( ref bs) => bs. iter ( ) . any ( |b| b. must_hold ( ) ) ,
1770
+ & VerifyBound :: AllBounds ( ref bs) => bs. iter ( ) . all ( |b| b. must_hold ( ) ) ,
1771
+ }
1772
+ }
1773
+
1774
+ pub fn cannot_hold ( & self ) -> bool {
1775
+ match self {
1776
+ & VerifyBound :: AnyRegion ( ref bs) => bs. is_empty ( ) ,
1777
+ & VerifyBound :: AllRegions ( ref bs) => bs. contains ( & ty:: ReEmpty ) ,
1778
+ & VerifyBound :: AnyBound ( ref bs) => bs. iter ( ) . all ( |b| b. cannot_hold ( ) ) ,
1779
+ & VerifyBound :: AllBounds ( ref bs) => bs. iter ( ) . any ( |b| b. cannot_hold ( ) ) ,
1780
+ }
1781
+ }
1782
+
1783
+ pub fn or ( self , vb : VerifyBound ) -> VerifyBound {
1784
+ if self . must_hold ( ) || vb. cannot_hold ( ) {
1785
+ self
1786
+ } else if self . cannot_hold ( ) || vb. must_hold ( ) {
1787
+ vb
1788
+ } else {
1789
+ VerifyBound :: AnyBound ( vec ! [ self , vb] )
1790
+ }
1791
+ }
1792
+
1793
+ pub fn and ( self , vb : VerifyBound ) -> VerifyBound {
1794
+ if self . must_hold ( ) && vb. must_hold ( ) {
1795
+ self
1796
+ } else if self . cannot_hold ( ) && vb. cannot_hold ( ) {
1797
+ self
1798
+ } else {
1799
+ VerifyBound :: AllBounds ( vec ! [ self , vb] )
1800
+ }
1801
+ }
1802
+
1803
+ fn is_met < ' tcx > ( & self ,
1804
+ tcx : & ty:: ctxt < ' tcx > ,
1805
+ free_regions : & FreeRegionMap ,
1806
+ var_values : & Vec < VarValue > ,
1807
+ min : ty:: Region )
1808
+ -> bool {
1809
+ match self {
1810
+ & VerifyBound :: AnyRegion ( ref rs) =>
1811
+ rs. iter ( )
1812
+ . map ( |& r| normalize ( var_values, r) )
1813
+ . any ( |r| free_regions. is_subregion_of ( tcx, min, r) ) ,
1814
+
1815
+ & VerifyBound :: AllRegions ( ref rs) =>
1816
+ rs. iter ( )
1817
+ . map ( |& r| normalize ( var_values, r) )
1818
+ . all ( |r| free_regions. is_subregion_of ( tcx, min, r) ) ,
1819
+
1820
+ & VerifyBound :: AnyBound ( ref bs) =>
1821
+ bs. iter ( )
1822
+ . any ( |b| b. is_met ( tcx, free_regions, var_values, min) ) ,
1823
+
1824
+ & VerifyBound :: AllBounds ( ref bs) =>
1825
+ bs. iter ( )
1826
+ . all ( |b| b. is_met ( tcx, free_regions, var_values, min) ) ,
1827
+ }
1828
+ }
1829
+ }
0 commit comments