@@ -123,14 +123,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
123123 ) -> Vec < ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
124124 let projection_ty = GenericKind :: Projection ( projection_ty) . to_ty ( self . tcx ) ;
125125 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)
134127 }
135128
136129 /// Searches the where-clauses in scope for regions that
@@ -219,12 +212,23 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
219212 param_ty : ty:: ParamTy ,
220213 ) -> Vec < ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
221214 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)
223216 }
224217
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 (
226230 & self ,
227- compare_ty : impl Fn ( Ty < ' tcx > ) -> bool ,
231+ erased_ty : Ty < ' tcx > ,
228232 ) -> Vec < ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
229233 let tcx = self . tcx ;
230234
@@ -235,7 +239,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
235239 // like `T` and `T::Item`. It may not work as well for things
236240 // like `<T as Foo<'a>>::Item`.
237241 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 ( ) ) ;
239243
240244 // Next, collect regions we scraped from the well-formedness
241245 // constraints in the fn signature. To do that, we walk the list
@@ -250,18 +254,19 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
250254 // don't know that this holds from first principles.
251255 let from_region_bound_pairs = self . region_bound_pairs . iter ( ) . filter_map ( |& ( r, p) | {
252256 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 = {:?}" ,
254258 ( r, p)
255259 ) ;
256260 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) )
258263 } ) ;
259264
260265 param_bounds
261266 . chain ( from_region_bound_pairs)
262267 . inspect ( |bound| {
263268 debug ! (
264- "declared_generic_bounds_from_env_with_compare_fn : result predicate = {:?}" ,
269+ "declared_generic_bounds_from_env_for_erased_ty : result predicate = {:?}" ,
265270 bound
266271 )
267272 } )
@@ -341,12 +346,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
341346 /// otherwise want a precise match.
342347 fn collect_outlives_from_predicate_list (
343348 & self ,
344- compare_ty : impl Fn ( Ty < ' tcx > ) -> bool ,
349+ erased_ty : Ty < ' tcx > ,
345350 predicates : impl Iterator < Item = ty:: Predicate < ' tcx > > ,
346351 ) -> impl Iterator < Item = ty:: OutlivesPredicate < Ty < ' tcx > , ty:: Region < ' tcx > > > {
352+ let tcx = self . tcx ;
347353 predicates
348354 . filter_map ( |p| p. to_opt_type_outlives ( ) )
349355 . 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 )
351357 }
352358}
0 commit comments