@@ -155,29 +155,98 @@ pub enum GenericKind<'tcx> {
155
155
Projection ( ty:: ProjectionTy < ' tcx > ) ,
156
156
}
157
157
158
- /// When we introduce a verification step, we wish to test that a
159
- /// particular region (let's call it `'min`) meets some bound.
160
- /// The bound is described the by the following grammar:
158
+ EnumTypeFoldableImpl ! {
159
+ impl <' tcx> TypeFoldable <' tcx> for GenericKind <' tcx> {
160
+ ( GenericKind :: Param ) ( a) ,
161
+ ( GenericKind :: Projection ) ( a) ,
162
+ }
163
+ }
164
+
165
+ /// Describes the things that some `GenericKind` value G is known to
166
+ /// outlive. Each variant of `VerifyBound` can be thought of as a
167
+ /// function:
168
+ ///
169
+ /// fn(min: Region) -> bool { .. }
170
+ ///
171
+ /// where `true` means that the region `min` meets that `G: min`.
172
+ /// (False means nothing.)
173
+ ///
174
+ /// So, for example, if we have the type `T` and we have in scope that
175
+ /// `T: 'a` and `T: 'b`, then the verify bound might be:
176
+ ///
177
+ /// fn(min: Region) -> bool {
178
+ /// ('a: min) || ('b: min)
179
+ /// }
180
+ ///
181
+ /// This is described with a `AnyRegion('a, 'b)` node.
161
182
#[ derive( Debug , Clone ) ]
162
183
pub enum VerifyBound < ' tcx > {
163
- /// B = exists {R} --> some 'r in {R} must outlive 'min
184
+ /// Given a kind K and a bound B, expands to a function like the
185
+ /// following, where `G` is the generic for which this verify
186
+ /// bound was created:
187
+ ///
188
+ /// fn(min) -> bool {
189
+ /// if G == K {
190
+ /// B(min)
191
+ /// } else {
192
+ /// false
193
+ /// }
194
+ /// }
195
+ ///
196
+ /// In other words, if the generic `G` that we are checking is
197
+ /// equal to `K`, then check the associated verify bound
198
+ /// (otherwise, false).
199
+ ///
200
+ /// This is used when we have something in the environment that
201
+ /// may or may not be relevant, depending on the region inference
202
+ /// results. For example, we may have `where <T as
203
+ /// Trait<'a>>::Item: 'b` in our where clauses. If we are
204
+ /// generating the verify-bound for `<T as Trait<'0>>::Item`, then
205
+ /// this where-clause is only relevant if `'0` winds up inferred
206
+ /// to `'a`.
207
+ ///
208
+ /// So we would compile to a verify-bound like
164
209
///
165
- /// Put another way, the subject value is known to outlive all
166
- /// regions in {R}, so if any of those outlives 'min, then the
167
- /// bound is met.
210
+ /// IfEq(<T as Trait<'a>>::Item, AnyRegion('a))
211
+ ///
212
+ /// meaning, if the subject G is equal to `<T as Trait<'a>>::Item`
213
+ /// (after inference), and `'a: min`, then `G: min`.
214
+ IfEq ( Ty < ' tcx > , Box < VerifyBound < ' tcx > > ) ,
215
+
216
+ /// Given a set of regions `R`, expands to the function:
217
+ ///
218
+ /// fn(min) -> bool {
219
+ /// exists (r in R) { r: min }
220
+ /// }
221
+ ///
222
+ /// In other words, if some r in R outlives min, then G outlives
223
+ /// min. This is used when G is known to outlive all the regions
224
+ /// in R.
168
225
AnyRegion ( Vec < Region < ' tcx > > ) ,
169
226
170
- /// B = forall {R} --> all 'r in {R} must outlive 'min
227
+ /// Given a set of regions `R`, expands to the function:
171
228
///
172
- /// Put another way, the subject value is known to outlive some
173
- /// region in {R}, so if all of those outlives 'min, then the bound
174
- /// is met.
229
+ /// fn(min) -> bool {
230
+ /// forall (r in R) { r: min }
231
+ /// }
232
+ ///
233
+ /// In other words, if all r in R outlives min, then G outlives
234
+ /// min. This is used when G is known to outlive some region in
235
+ /// R, but we don't know which.
175
236
AllRegions ( Vec < Region < ' tcx > > ) ,
176
237
177
- /// B = exists {B} --> 'min must meet some bound b in {B}
238
+ /// Given a set of bounds `B`, expands to the function:
239
+ ///
240
+ /// fn(min) -> bool {
241
+ /// exists (b in B) { b(min) }
242
+ /// }
178
243
AnyBound ( Vec < VerifyBound < ' tcx > > ) ,
179
244
180
- /// B = forall {B} --> 'min must meet all bounds b in {B}
245
+ /// Given a set of bounds `B`, expands to the function:
246
+ ///
247
+ /// fn(min) -> bool {
248
+ /// forall (b in B) { b(min) }
249
+ /// }
181
250
AllBounds ( Vec < VerifyBound < ' tcx > > ) ,
182
251
}
183
252
@@ -884,19 +953,21 @@ impl<'a, 'gcx, 'tcx> GenericKind<'tcx> {
884
953
impl < ' a , ' gcx , ' tcx > VerifyBound < ' tcx > {
885
954
pub fn must_hold ( & self ) -> bool {
886
955
match self {
887
- & VerifyBound :: AnyRegion ( ref bs) => bs. contains ( & & ty:: ReStatic ) ,
888
- & VerifyBound :: AllRegions ( ref bs) => bs. is_empty ( ) ,
889
- & VerifyBound :: AnyBound ( ref bs) => bs. iter ( ) . any ( |b| b. must_hold ( ) ) ,
890
- & VerifyBound :: AllBounds ( ref bs) => bs. iter ( ) . all ( |b| b. must_hold ( ) ) ,
956
+ VerifyBound :: IfEq ( ..) => false ,
957
+ VerifyBound :: AnyRegion ( bs) => bs. contains ( & & ty:: ReStatic ) ,
958
+ VerifyBound :: AllRegions ( bs) => bs. is_empty ( ) ,
959
+ VerifyBound :: AnyBound ( bs) => bs. iter ( ) . any ( |b| b. must_hold ( ) ) ,
960
+ VerifyBound :: AllBounds ( bs) => bs. iter ( ) . all ( |b| b. must_hold ( ) ) ,
891
961
}
892
962
}
893
963
894
964
pub fn cannot_hold ( & self ) -> bool {
895
965
match self {
896
- & VerifyBound :: AnyRegion ( ref bs) => bs. is_empty ( ) ,
897
- & VerifyBound :: AllRegions ( ref bs) => bs. contains ( & & ty:: ReEmpty ) ,
898
- & VerifyBound :: AnyBound ( ref bs) => bs. iter ( ) . all ( |b| b. cannot_hold ( ) ) ,
899
- & VerifyBound :: AllBounds ( ref bs) => bs. iter ( ) . any ( |b| b. cannot_hold ( ) ) ,
966
+ VerifyBound :: IfEq ( _, b) => b. cannot_hold ( ) ,
967
+ VerifyBound :: AnyRegion ( bs) => bs. is_empty ( ) ,
968
+ VerifyBound :: AllRegions ( bs) => bs. contains ( & & ty:: ReEmpty ) ,
969
+ VerifyBound :: AnyBound ( bs) => bs. iter ( ) . all ( |b| b. cannot_hold ( ) ) ,
970
+ VerifyBound :: AllBounds ( bs) => bs. iter ( ) . any ( |b| b. cannot_hold ( ) ) ,
900
971
}
901
972
}
902
973
0 commit comments