Simplify declared_generic_bounds_from_env
This commit is contained in:
parent
2a373d7dd3
commit
dd210eca43
1 changed files with 23 additions and 32 deletions
|
@ -192,7 +192,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
||||||
/// Obviously these must be approximate -- they are in fact both *over* and
|
/// Obviously these must be approximate -- they are in fact both *over* and
|
||||||
/// and *under* approximated:
|
/// 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
|
/// * 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
|
/// like `<T as Foo<fn(&u32, &u32)>>::Item` or whatever we may fail to figure out
|
||||||
/// all the subtleties.
|
/// all the subtleties.
|
||||||
|
@ -205,13 +205,14 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
||||||
erased_ty: Ty<'tcx>,
|
erased_ty: Ty<'tcx>,
|
||||||
) -> Vec<ty::PolyTypeOutlivesPredicate<'tcx>> {
|
) -> Vec<ty::PolyTypeOutlivesPredicate<'tcx>> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
|
let mut bounds = vec![];
|
||||||
|
|
||||||
// To start, collect bounds from user environment. Note that
|
// To start, collect bounds from user environment. Note that
|
||||||
// parameter environments are already elaborated, so we don't
|
// parameter environments are already elaborated, so we don't
|
||||||
// have to worry about that.
|
// 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)
|
super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty)
|
||||||
});
|
}));
|
||||||
|
|
||||||
// Next, collect regions we scraped from the well-formedness
|
// Next, collect regions we scraped from the well-formedness
|
||||||
// constraints in the fn signature. To do that, we walk the list
|
// constraints in the fn signature. To do that, we walk the list
|
||||||
|
@ -224,37 +225,27 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
||||||
// The problem is that the type of `x` is `&'a A`. To be
|
// 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
|
// well-formed, then, A must outlive `'a`, but we don't know that
|
||||||
// this holds from first principles.
|
// this holds from first principles.
|
||||||
let from_region_bound_pairs =
|
bounds.extend(self.region_bound_pairs.iter().filter_map(|&OutlivesPredicate(p, r)| {
|
||||||
self.region_bound_pairs.iter().filter_map(|&OutlivesPredicate(p, r)| {
|
debug!(
|
||||||
debug!(
|
"declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}",
|
||||||
"declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}",
|
(r, p)
|
||||||
(r, p)
|
);
|
||||||
);
|
// Fast path for the common case.
|
||||||
// Fast path for the common case.
|
match (&p, erased_ty.kind()) {
|
||||||
match (&p, erased_ty.kind()) {
|
// In outlive routines, all types are expected to be fully normalized.
|
||||||
// In outlive routines, all types are expected to be fully normalized.
|
// And therefore we can safely use structural equality for alias types.
|
||||||
// And therefore we can safely use structural equality for alias types.
|
(GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {}
|
||||||
(GenericKind::Param(p1), ty::Param(p2)) if p1 == p2 => {}
|
(GenericKind::Placeholder(p1), ty::Placeholder(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 => {}
|
||||||
(GenericKind::Alias(a1), ty::Alias(_, a2)) if a1.def_id == a2.def_id => {}
|
_ => return None,
|
||||||
_ => return None,
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let p_ty = p.to_ty(tcx);
|
let p_ty = p.to_ty(tcx);
|
||||||
let erased_p_ty = self.tcx.erase_regions(p_ty);
|
let erased_p_ty = self.tcx.erase_regions(p_ty);
|
||||||
(erased_p_ty == erased_ty)
|
(erased_p_ty == erased_ty).then_some(ty::Binder::dummy(ty::OutlivesPredicate(p_ty, r)))
|
||||||
.then_some(ty::Binder::dummy(ty::OutlivesPredicate(p_ty, r)))
|
}));
|
||||||
});
|
|
||||||
|
|
||||||
param_bounds
|
bounds
|
||||||
.chain(from_region_bound_pairs)
|
|
||||||
.inspect(|bound| {
|
|
||||||
debug!(
|
|
||||||
"declared_generic_bounds_from_env_for_erased_ty: result predicate = {:?}",
|
|
||||||
bound
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a projection like `<T as Foo<'x>>::Bar`, returns any bounds
|
/// Given a projection like `<T as Foo<'x>>::Bar`, returns any bounds
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue