Auto merge of #115759 - oli-obk:open_drop_from_non-ADT, r=lcnr

Reveal opaque types before drop elaboration

fixes https://github.com/rust-lang/rust/issues/113594

r? `@cjgillot`

cc `@JakobDegen`

This pass was introduced in https://github.com/rust-lang/rust/pull/110714

I moved it before drop elaboration (which only cares about the hidden types of things, not the opaque TAIT or RPIT type) and set it to run unconditionally (instead of depending on the optimization level and whether the inliner is active)
This commit is contained in:
bors 2023-09-29 11:59:51 +00:00
commit c5450191f3
19 changed files with 181 additions and 87 deletions

View file

@ -170,6 +170,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> {
self.ctxt.param_env()
}
#[instrument(level = "debug", skip(self), ret)]
fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle {
let ((maybe_live, maybe_dead), multipart) = match mode {
DropFlagMode::Shallow => (self.ctxt.init_data.maybe_live_dead(path), false),

View file

@ -480,6 +480,7 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let passes: &[&dyn MirPass<'tcx>] = &[
// These next passes must be executed together
&add_call_guards::CriticalCallEdges,
&reveal_all::RevealAll, // has to be done before drop elaboration, since we need to drop opaque types, too.
&elaborate_drops::ElaborateDrops,
// This will remove extraneous landing pads which are no longer
// necessary as well as well as forcing any call in a non-unwinding
@ -526,7 +527,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
body,
&[
&check_alignment::CheckAlignment,
&reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode.
&lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first
&unreachable_prop::UnreachablePropagation,
&uninhabited_enum_branching::UninhabitedEnumBranching,

View file

@ -8,16 +8,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
pub struct RevealAll;
impl<'tcx> MirPass<'tcx> for RevealAll {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 3 || super::inline::Inline.is_enabled(sess)
}
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// Do not apply this transformation to generators.
if body.generator.is_some() {
return;
}
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body);
}
@ -34,6 +25,29 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
self.tcx
}
#[inline]
fn visit_place(
&mut self,
place: &mut Place<'tcx>,
_context: PlaceContext,
_location: Location,
) {
// Performance optimization: don't reintern if there is no `OpaqueCast` to remove.
if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) {
return;
}
// `OpaqueCast` projections are only needed if there are opaque types on which projections are performed.
// After the `RevealAll` pass, all opaque types are replaced with their hidden types, so we don't need these
// projections anymore.
place.projection = self.tcx.mk_place_elems(
&place
.projection
.into_iter()
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
.collect::<Vec<_>>(),
);
}
#[inline]
fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, _: Location) {
// We have to use `try_normalize_erasing_regions` here, since it's