Auto merge of #95474 - oli-obk:tait_ub, r=jackh726
Neither require nor imply lifetime bounds on opaque type for well formedness The actual hidden type can live arbitrarily longer than any individual lifetime and arbitrarily shorter than all but one of the lifetimes. fixes #86218 fixes #84305 This is a **breaking change** but it is a necessary soundness fix
This commit is contained in:
commit
f5193a9fcc
34 changed files with 696 additions and 153 deletions
|
@ -265,6 +265,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
|||
self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, previous))]
|
||||
fn cat_expr_adjusted_with<F>(
|
||||
&self,
|
||||
expr: &hir::Expr<'_>,
|
||||
|
@ -274,7 +275,6 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
|||
where
|
||||
F: FnOnce() -> McResult<PlaceWithHirId<'tcx>>,
|
||||
{
|
||||
debug!("cat_expr_adjusted_with({:?}): {:?}", adjustment, expr);
|
||||
let target = self.resolve_vars_if_possible(adjustment.target);
|
||||
match adjustment.kind {
|
||||
adjustment::Adjust::Deref(overloaded) => {
|
||||
|
@ -299,6 +299,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub(crate) fn cat_expr_unadjusted(
|
||||
&self,
|
||||
expr: &hir::Expr<'_>,
|
||||
|
@ -387,6 +388,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, span))]
|
||||
pub(crate) fn cat_res(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
|
@ -394,8 +396,6 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
|||
expr_ty: Ty<'tcx>,
|
||||
res: Res,
|
||||
) -> McResult<PlaceWithHirId<'tcx>> {
|
||||
debug!("cat_res: id={:?} expr={:?} def={:?}", hir_id, expr_ty, res);
|
||||
|
||||
match res {
|
||||
Res::Def(
|
||||
DefKind::Ctor(..)
|
||||
|
@ -475,13 +475,12 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
|||
ret
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn cat_overloaded_place(
|
||||
&self,
|
||||
expr: &hir::Expr<'_>,
|
||||
base: &hir::Expr<'_>,
|
||||
) -> McResult<PlaceWithHirId<'tcx>> {
|
||||
debug!("cat_overloaded_place(expr={:?}, base={:?})", expr, base);
|
||||
|
||||
// Reconstruct the output assuming it's a reference with the
|
||||
// same region and mutability as the receiver. This holds for
|
||||
// `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
|
||||
|
@ -497,13 +496,12 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
|||
self.cat_deref(expr, base)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, node))]
|
||||
fn cat_deref(
|
||||
&self,
|
||||
node: &impl HirNode,
|
||||
base_place: PlaceWithHirId<'tcx>,
|
||||
) -> McResult<PlaceWithHirId<'tcx>> {
|
||||
debug!("cat_deref: base_place={:?}", base_place);
|
||||
|
||||
let base_curr_ty = base_place.place.ty();
|
||||
let deref_ty = match base_curr_ty.builtin_deref(true) {
|
||||
Some(mt) => mt.ty,
|
||||
|
|
|
@ -96,6 +96,23 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
|
|||
.or_insert(span);
|
||||
}
|
||||
|
||||
Component::Opaque(def_id, substs) => {
|
||||
// This would arise from something like:
|
||||
//
|
||||
// ```rust
|
||||
// type Opaque<T> = impl Sized;
|
||||
// fn defining<T>() -> Opaque<T> {}
|
||||
// struct Ss<'a, T>(&'a Opaque<T>);
|
||||
// ```
|
||||
//
|
||||
// Here we want to have an implied bound `Opaque<T>: 'a`
|
||||
|
||||
let ty = tcx.mk_opaque(def_id, substs);
|
||||
required_predicates
|
||||
.entry(ty::OutlivesPredicate(ty.into(), outlived_region))
|
||||
.or_insert(span);
|
||||
}
|
||||
|
||||
Component::EscapingProjection(_) => {
|
||||
// As above, but the projection involves
|
||||
// late-bound regions. Therefore, the WF
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue