@@ -155,29 +155,98 @@ pub enum GenericKind<'tcx> {
155155 Projection ( ty:: ProjectionTy < ' tcx > ) ,
156156}
157157
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.
161182#[ derive( Debug , Clone ) ]
162183pub 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
164209 ///
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.
168225 AnyRegion ( Vec < Region < ' tcx > > ) ,
169226
170- /// B = forall {R} --> all 'r in {R} must outlive 'min
227+ /// Given a set of regions `R`, expands to the function:
171228 ///
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.
175236 AllRegions ( Vec < Region < ' tcx > > ) ,
176237
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+ /// }
178243 AnyBound ( Vec < VerifyBound < ' tcx > > ) ,
179244
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+ /// }
181250 AllBounds ( Vec < VerifyBound < ' tcx > > ) ,
182251}
183252
@@ -884,19 +953,21 @@ impl<'a, 'gcx, 'tcx> GenericKind<'tcx> {
884953impl < ' a , ' gcx , ' tcx > VerifyBound < ' tcx > {
885954 pub fn must_hold ( & self ) -> bool {
886955 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 ( ) ) ,
891961 }
892962 }
893963
894964 pub fn cannot_hold ( & self ) -> bool {
895965 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 ( ) ) ,
900971 }
901972 }
902973
0 commit comments