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:
commit
c5450191f3
19 changed files with 181 additions and 87 deletions
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue