@@ -51,10 +51,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
51
51
52
52
// Start with anything like `T: 'a` we can scrape from the
53
53
// environment
54
- let param_bounds = self
55
- . declared_generic_bounds_from_env ( GenericKind :: Param ( param_ty) )
56
- . into_iter ( )
57
- . map ( |outlives| outlives. 1 ) ;
54
+ let param_bounds =
55
+ self . declared_generic_bounds_from_env ( param_ty) . map ( |outlives| outlives. 1 ) ;
58
56
59
57
// Add in the default bound of fn body that applies to all in
60
58
// scope type parameters:
@@ -79,12 +77,15 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
79
77
pub fn projection_approx_declared_bounds_from_env (
80
78
& self ,
81
79
projection_ty : ty:: ProjectionTy < ' tcx > ,
82
- ) -> Vec < ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
83
- let projection_ty = GenericKind :: Projection ( projection_ty) . to_ty ( self . tcx ) ;
84
- let erased_projection_ty = self . tcx . erase_regions ( & projection_ty) ;
85
- self . declared_generic_bounds_from_env_with_compare_fn ( |ty| {
80
+ ) -> impl Iterator < Item = ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > + ' cx + Captures < ' tcx >
81
+ {
82
+ let tcx = self . tcx ;
83
+
84
+ let projection_ty = GenericKind :: Projection ( projection_ty) . to_ty ( tcx) ;
85
+ let erased_projection_ty = tcx. erase_regions ( & projection_ty) ;
86
+ self . declared_generic_bounds_from_env_with_compare_fn ( move |ty| {
86
87
if let ty:: Projection ( ..) = ty. kind {
87
- let erased_ty = self . tcx . erase_regions ( & ty) ;
88
+ let erased_ty = tcx. erase_regions ( & ty) ;
88
89
erased_ty == erased_projection_ty
89
90
} else {
90
91
false
@@ -95,10 +96,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
95
96
/// Searches the where-clauses in scope for regions that
96
97
/// `projection_ty` is known to outlive. Currently requires an
97
98
/// exact match.
98
- pub fn projection_declared_bounds_from_trait (
99
- & self ,
99
+ pub fn projection_declared_bounds_from_trait < ' a > (
100
+ & ' a self ,
100
101
projection_ty : ty:: ProjectionTy < ' tcx > ,
101
- ) -> impl Iterator < Item = ty:: Region < ' tcx > > + ' cx + Captures < ' tcx > {
102
+ ) -> impl Iterator < Item = ty:: Region < ' tcx > > + ' cx + Captures < ' tcx > + ' a
103
+ where
104
+ ' a : ' cx ,
105
+ {
102
106
self . declared_projection_bounds_from_trait ( projection_ty)
103
107
}
104
108
@@ -127,7 +131,6 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
127
131
// Extend with bounds that we can find from the trait.
128
132
let trait_bounds = self
129
133
. projection_declared_bounds_from_trait ( projection_ty)
130
- . into_iter ( )
131
134
. map ( |r| VerifyBound :: OutlivedBy ( r) ) ;
132
135
133
136
// see the extensive comment in projection_must_outlive
@@ -138,17 +141,18 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
138
141
}
139
142
140
143
fn recursive_type_bound ( & self , ty : Ty < ' tcx > ) -> VerifyBound < ' tcx > {
141
- let mut bounds = ty. walk_shallow ( ) . map ( |subty| self . type_bound ( subty) ) . collect :: < Vec < _ > > ( ) ;
142
-
143
- let mut regions = smallvec ! [ ] ;
144
- ty. push_regions ( & mut regions) ;
145
- regions. retain ( |r| !r. is_late_bound ( ) ) ; // ignore late-bound regions
146
- bounds. push ( VerifyBound :: AllBounds (
147
- regions. into_iter ( ) . map ( |r| VerifyBound :: OutlivedBy ( r) ) . collect ( ) ,
148
- ) ) ;
149
-
150
- // remove bounds that must hold, since they are not interesting
151
- bounds. retain ( |b| !b. must_hold ( ) ) ;
144
+ let mut bounds = ty
145
+ . walk_shallow ( )
146
+ . map ( |subty| self . type_bound ( subty) )
147
+ . chain ( Some ( VerifyBound :: AllBounds (
148
+ // ignore late-bound regions
149
+ ty. regions ( )
150
+ . filter ( |r| !r. is_late_bound ( ) )
151
+ . map ( |r| VerifyBound :: OutlivedBy ( r) )
152
+ . collect ( ) ,
153
+ ) ) )
154
+ . filter ( |b| !b. must_hold ( ) )
155
+ . collect :: < Vec < _ > > ( ) ;
152
156
153
157
if bounds. len ( ) == 1 { bounds. pop ( ) . unwrap ( ) } else { VerifyBound :: AllBounds ( bounds) }
154
158
}
@@ -161,16 +165,18 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
161
165
/// bounds, but all the bounds it returns can be relied upon.
162
166
fn declared_generic_bounds_from_env (
163
167
& self ,
164
- generic : GenericKind < ' tcx > ,
165
- ) -> Vec < ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
168
+ generic : ty:: ParamTy ,
169
+ ) -> impl Iterator < Item = ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > + ' cx + Captures < ' tcx >
170
+ {
166
171
let generic_ty = generic. to_ty ( self . tcx ) ;
167
- self . declared_generic_bounds_from_env_with_compare_fn ( |ty| ty == generic_ty)
172
+ self . declared_generic_bounds_from_env_with_compare_fn ( move |ty| ty == generic_ty)
168
173
}
169
174
170
175
fn declared_generic_bounds_from_env_with_compare_fn (
171
176
& self ,
172
- compare_ty : impl Fn ( Ty < ' tcx > ) -> bool ,
173
- ) -> Vec < ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
177
+ compare_ty : impl Fn ( Ty < ' tcx > ) -> bool + Clone + ' tcx + ' cx ,
178
+ ) -> impl Iterator < Item = ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > + ' cx + Captures < ' tcx >
179
+ {
174
180
let tcx = self . tcx ;
175
181
176
182
// To start, collect bounds from user environment. Note that
@@ -180,7 +186,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
180
186
// like `T` and `T::Item`. It may not work as well for things
181
187
// like `<T as Foo<'a>>::Item`.
182
188
let c_b = self . param_env . caller_bounds ;
183
- let param_bounds = self . collect_outlives_from_predicate_list ( & compare_ty, c_b) ;
189
+ let param_bounds = self . collect_outlives_from_predicate_list ( compare_ty. clone ( ) , c_b) ;
184
190
185
191
// Next, collect regions we scraped from the well-formedness
186
192
// constraints in the fn signature. To do that, we walk the list
@@ -193,7 +199,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
193
199
// The problem is that the type of `x` is `&'a A`. To be
194
200
// well-formed, then, A must be lower-generic by `'a`, but we
195
201
// don't know that this holds from first principles.
196
- let from_region_bound_pairs = self . region_bound_pairs . iter ( ) . filter_map ( |& ( r, p) | {
202
+ let from_region_bound_pairs = self . region_bound_pairs . iter ( ) . filter_map ( move |& ( r, p) | {
197
203
debug ! (
198
204
"declared_generic_bounds_from_env_with_compare_fn: region_bound_pair = {:?}" ,
199
205
( r, p)
@@ -202,15 +208,12 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
202
208
compare_ty ( p_ty) . then_some ( ty:: OutlivesPredicate ( p_ty, r) )
203
209
} ) ;
204
210
205
- param_bounds
206
- . chain ( from_region_bound_pairs)
207
- . inspect ( |bound| {
208
- debug ! (
209
- "declared_generic_bounds_from_env_with_compare_fn: result predicate = {:?}" ,
210
- bound
211
- )
212
- } )
213
- . collect ( )
211
+ param_bounds. chain ( from_region_bound_pairs) . inspect ( |bound| {
212
+ debug ! (
213
+ "declared_generic_bounds_from_env_with_compare_fn: result predicate = {:?}" ,
214
+ bound
215
+ )
216
+ } )
214
217
}
215
218
216
219
/// Given a projection like `<T as Foo<'x>>::Bar`, returns any bounds
@@ -225,10 +228,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
225
228
/// then this function would return `'x`. This is subject to the
226
229
/// limitations around higher-ranked bounds described in
227
230
/// `region_bounds_declared_on_associated_item`.
228
- fn declared_projection_bounds_from_trait (
229
- & self ,
231
+ fn declared_projection_bounds_from_trait < ' a > (
232
+ & ' a self ,
230
233
projection_ty : ty:: ProjectionTy < ' tcx > ,
231
- ) -> impl Iterator < Item = ty:: Region < ' tcx > > + ' cx + Captures < ' tcx > {
234
+ ) -> impl Iterator < Item = ty:: Region < ' tcx > > + ' cx + Captures < ' tcx > + ' a
235
+ where
236
+ ' a : ' cx ,
237
+ {
232
238
debug ! ( "projection_bounds(projection_ty={:?})" , projection_ty) ;
233
239
let tcx = self . tcx ;
234
240
self . region_bounds_declared_on_associated_item ( projection_ty. item_def_id )
@@ -265,10 +271,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
265
271
///
266
272
/// This is for simplicity, and because we are not really smart
267
273
/// enough to cope with such bounds anywhere.
268
- fn region_bounds_declared_on_associated_item (
269
- & self ,
274
+ fn region_bounds_declared_on_associated_item < ' a > (
275
+ & ' a self ,
270
276
assoc_item_def_id : DefId ,
271
- ) -> impl Iterator < Item = ty:: Region < ' tcx > > + ' cx + Captures < ' tcx > {
277
+ ) -> impl Iterator < Item = ty:: Region < ' tcx > > + ' cx + Captures < ' tcx > + ' a
278
+ where
279
+ ' a : ' cx ,
280
+ {
272
281
let tcx = self . tcx ;
273
282
let assoc_item = tcx. associated_item ( assoc_item_def_id) ;
274
283
let trait_def_id = assoc_item. container . assert_trait ( ) ;
@@ -291,7 +300,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
291
300
/// otherwise want a precise match.
292
301
fn collect_outlives_from_predicate_list (
293
302
& self ,
294
- compare_ty : impl Fn ( Ty < ' tcx > ) -> bool ,
303
+ compare_ty : impl Fn ( Ty < ' tcx > ) -> bool + ' tcx ,
295
304
predicates : impl IntoIterator < Item = impl AsRef < ty:: Predicate < ' tcx > > > ,
296
305
) -> impl Iterator < Item = ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
297
306
predicates
0 commit comments