Skip to content

Commit

Permalink
Simplify declared_generic_bounds_from_env
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jan 2, 2025
1 parent 2a373d7 commit dd210ec
Showing 1 changed file with 23 additions and 32 deletions.
55 changes: 23 additions & 32 deletions compiler/rustc_infer/src/infer/outlives/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
/// Obviously these must be approximate -- they are in fact both *over* and
/// and *under* approximated:
///
/// * Over-approximated because we erase regions, so
/// * Over-approximated because we don't consider equality of regions.
/// * Under-approximated because we look for syntactic equality and so for complex types
/// like `<T as Foo<fn(&u32, &u32)>>::Item` or whatever we may fail to figure out
/// all the subtleties.
Expand All @@ -205,13 +205,14 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
erased_ty: Ty<'tcx>,
) -> Vec<ty::PolyTypeOutlivesPredicate<'tcx>> {
let tcx = self.tcx;
let mut bounds = vec![];

// To start, collect bounds from user environment. Note that
// parameter environments are already elaborated, so we don't
// have to worry about that.
let param_bounds = self.caller_bounds.iter().copied().filter(move |outlives_predicate| {
bounds.extend(self.caller_bounds.iter().copied().filter(move |outlives_predicate| {
super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty)
});
}));

// Next, collect regions we scraped from the well-formedness
// constraints in the fn signature. To do that, we walk the list
Expand All @@ -224,37 +225,27 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
// The problem is that the type of `x` is `&'a A`. To be
// well-formed, then, A must outlive `'a`, but we don't know that
// this holds from first principles.
let from_region_bound_pairs =
self.region_bound_pairs.iter().filter_map(|&OutlivesPredicate(p, r)| {
debug!(
"declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}",
(r, p)
);
// Fast path for the common case.
match (&p, erased_ty.kind()) {
// In outlive routines, all types are expected to be fully normalized.
// And therefore we can safely use structural equality for alias types.
(GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {}
(GenericKind::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => {}
(GenericKind::Alias(a1), ty::Alias(_, a2)) if a1.def_id == a2.def_id => {}
_ => return None,
}
bounds.extend(self.region_bound_pairs.iter().filter_map(|&OutlivesPredicate(p, r)| {
debug!(
"declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}",
(r, p)
);
// Fast path for the common case.
match (&p, erased_ty.kind()) {
// In outlive routines, all types are expected to be fully normalized.
// And therefore we can safely use structural equality for alias types.
(GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {}
(GenericKind::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => {}
(GenericKind::Alias(a1), ty::Alias(_, a2)) if a1.def_id == a2.def_id => {}
_ => return None,
}

let p_ty = p.to_ty(tcx);
let erased_p_ty = self.tcx.erase_regions(p_ty);
(erased_p_ty == erased_ty)
.then_some(ty::Binder::dummy(ty::OutlivesPredicate(p_ty, r)))
});
let p_ty = p.to_ty(tcx);
let erased_p_ty = self.tcx.erase_regions(p_ty);
(erased_p_ty == erased_ty).then_some(ty::Binder::dummy(ty::OutlivesPredicate(p_ty, r)))
}));

param_bounds
.chain(from_region_bound_pairs)
.inspect(|bound| {
debug!(
"declared_generic_bounds_from_env_for_erased_ty: result predicate = {:?}",
bound
)
})
.collect()
bounds
}

/// Given a projection like `<T as Foo<'x>>::Bar`, returns any bounds
Expand Down

0 comments on commit dd210ec

Please sign in to comment.