Skip to content

Commit 87c2907

Browse files
committed
remove compare-fn and use erased-ty
1 parent e260afc commit 87c2907

File tree

1 file changed

+23
-17
lines changed
  • compiler/rustc_infer/src/infer/outlives

1 file changed

+23
-17
lines changed

compiler/rustc_infer/src/infer/outlives/verify.rs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)