@@ -123,14 +123,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
123
123
) -> Vec < ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
124
124
let projection_ty = GenericKind :: Projection ( projection_ty) . to_ty ( self . tcx ) ;
125
125
let erased_projection_ty = self . tcx . erase_regions ( projection_ty) ;
126
- self . declared_generic_bounds_from_env_with_compare_fn ( |ty| {
127
- if let ty:: Projection ( ..) = ty. kind ( ) {
128
- let erased_ty = self . tcx . erase_regions ( ty) ;
129
- erased_ty == erased_projection_ty
130
- } else {
131
- false
132
- }
133
- } )
126
+ self . declared_generic_bounds_from_env_for_erased_ty ( erased_projection_ty)
134
127
}
135
128
136
129
/// Searches the where-clauses in scope for regions that
@@ -219,12 +212,23 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
219
212
param_ty : ty:: ParamTy ,
220
213
) -> Vec < ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
221
214
let generic_ty = param_ty. to_ty ( self . tcx ) ;
222
- self . declared_generic_bounds_from_env_with_compare_fn ( |ty| ty == generic_ty)
215
+ self . declared_generic_bounds_from_env_for_erased_ty ( generic_ty)
223
216
}
224
217
225
- fn declared_generic_bounds_from_env_with_compare_fn (
218
+ /// Searches the environment to find all bounds that apply to `erased_ty`.
219
+ /// Obviously these must be approximate -- they are in fact both *over* and
220
+ /// and *under* approximated:
221
+ ///
222
+ /// * Over-approximated because we erase regions, so
223
+ /// * Under-approximated because we look for syntactic equality and so for complex types
224
+ /// like `<T as Foo<fn(&u32, &u32)>>::Item` or whatever we may fail to figure out
225
+ /// all the subtleties.
226
+ ///
227
+ /// In some cases, such as when `erased_ty` represents a `ty::Param`, however,
228
+ /// the result is precise.
229
+ fn declared_generic_bounds_from_env_for_erased_ty (
226
230
& self ,
227
- compare_ty : impl Fn ( Ty < ' tcx > ) -> bool ,
231
+ erased_ty : Ty < ' tcx > ,
228
232
) -> Vec < ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
229
233
let tcx = self . tcx ;
230
234
@@ -235,7 +239,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
235
239
// like `T` and `T::Item`. It may not work as well for things
236
240
// like `<T as Foo<'a>>::Item`.
237
241
let c_b = self . param_env . caller_bounds ( ) ;
238
- let param_bounds = self . collect_outlives_from_predicate_list ( & compare_ty , c_b. into_iter ( ) ) ;
242
+ let param_bounds = self . collect_outlives_from_predicate_list ( erased_ty , c_b. into_iter ( ) ) ;
239
243
240
244
// Next, collect regions we scraped from the well-formedness
241
245
// constraints in the fn signature. To do that, we walk the list
@@ -250,18 +254,19 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
250
254
// don't know that this holds from first principles.
251
255
let from_region_bound_pairs = self . region_bound_pairs . iter ( ) . filter_map ( |& ( r, p) | {
252
256
debug ! (
253
- "declared_generic_bounds_from_env_with_compare_fn : region_bound_pair = {:?}" ,
257
+ "declared_generic_bounds_from_env_for_erased_ty : region_bound_pair = {:?}" ,
254
258
( r, p)
255
259
) ;
256
260
let p_ty = p. to_ty ( tcx) ;
257
- compare_ty ( p_ty) . then_some ( ty:: OutlivesPredicate ( p_ty, r) )
261
+ let erased_p_ty = self . tcx . erase_regions ( p_ty) ;
262
+ ( erased_p_ty == erased_ty) . then_some ( ty:: OutlivesPredicate ( p. to_ty ( tcx) , r) )
258
263
} ) ;
259
264
260
265
param_bounds
261
266
. chain ( from_region_bound_pairs)
262
267
. inspect ( |bound| {
263
268
debug ! (
264
- "declared_generic_bounds_from_env_with_compare_fn : result predicate = {:?}" ,
269
+ "declared_generic_bounds_from_env_for_erased_ty : result predicate = {:?}" ,
265
270
bound
266
271
)
267
272
} )
@@ -341,12 +346,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
341
346
/// otherwise want a precise match.
342
347
fn collect_outlives_from_predicate_list (
343
348
& self ,
344
- compare_ty : impl Fn ( Ty < ' tcx > ) -> bool ,
349
+ erased_ty : Ty < ' tcx > ,
345
350
predicates : impl Iterator < Item = ty:: Predicate < ' tcx > > ,
346
351
) -> impl Iterator < Item = ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
352
+ let tcx = self . tcx ;
347
353
predicates
348
354
. filter_map ( |p| p. to_opt_type_outlives ( ) )
349
355
. filter_map ( |p| p. no_bound_vars ( ) )
350
- . filter ( move |p| compare_ty ( p. 0 ) )
356
+ . filter ( move |p| tcx . erase_regions ( p. 0 ) == erased_ty )
351
357
}
352
358
}
0 commit comments