Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit c545019

Browse files
committed
Auto merge of rust-lang#115759 - oli-obk:open_drop_from_non-ADT, r=lcnr
Reveal opaque types before drop elaboration fixes rust-lang#113594 r? `@cjgillot` cc `@JakobDegen` This pass was introduced in rust-lang#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)
2 parents a66e334 + 0031cf7 commit c545019

File tree

19 files changed

+177
-83
lines changed

19 files changed

+177
-83
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,7 @@ pub(crate) fn codegen_place<'tcx>(
875875
PlaceElem::Deref => {
876876
cplace = cplace.place_deref(fx);
877877
}
878-
PlaceElem::OpaqueCast(ty) => cplace = cplace.place_opaque_cast(fx, ty),
878+
PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"),
879879
PlaceElem::Field(field, _ty) => {
880880
cplace = cplace.place_field(fx, field);
881881
}

compiler/rustc_codegen_cranelift/src/value_and_place.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -674,14 +674,6 @@ impl<'tcx> CPlace<'tcx> {
674674
}
675675
}
676676

677-
pub(crate) fn place_opaque_cast(
678-
self,
679-
fx: &mut FunctionCx<'_, '_, 'tcx>,
680-
ty: Ty<'tcx>,
681-
) -> CPlace<'tcx> {
682-
CPlace { inner: self.inner, layout: fx.layout_of(ty) }
683-
}
684-
685677
pub(crate) fn place_field(
686678
self,
687679
fx: &mut FunctionCx<'_, '_, 'tcx>,

compiler/rustc_codegen_ssa/src/mir/place.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
463463
mir::ProjectionElem::Field(ref field, _) => {
464464
cg_base.project_field(bx, field.index())
465465
}
466-
mir::ProjectionElem::OpaqueCast(ty) => cg_base.project_type(bx, ty),
466+
mir::ProjectionElem::OpaqueCast(ty) => {
467+
bug!("encountered OpaqueCast({ty}) in codegen")
468+
}
467469
mir::ProjectionElem::Index(index) => {
468470
let index = &mir::Operand::Copy(mir::Place::from(index));
469471
let index = self.codegen_operand(bx, index);

compiler/rustc_const_eval/src/interpret/projection.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,9 @@ where
316316
{
317317
use rustc_middle::mir::ProjectionElem::*;
318318
Ok(match proj_elem {
319-
OpaqueCast(ty) => base.transmute(self.layout_of(ty)?, self)?,
319+
OpaqueCast(ty) => {
320+
span_bug!(self.cur_span(), "OpaqueCast({ty}) encountered after borrowck")
321+
}
320322
Field(field, _) => self.project_field(base, field.index())?,
321323
Downcast(_, variant) => self.project_downcast(base, variant)?,
322324
Deref => self.deref_pointer(&base.to_op(self)?)?.into(),

compiler/rustc_const_eval/src/transform/validate.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
633633
location: Location,
634634
) {
635635
match elem {
636+
ProjectionElem::OpaqueCast(ty)
637+
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) =>
638+
{
639+
self.fail(
640+
location,
641+
format!("explicit opaque type cast to `{ty}` after `RevealAll`"),
642+
)
643+
}
636644
ProjectionElem::Index(index) => {
637645
let index_ty = self.body.local_decls[index].ty;
638646
if index_ty != self.tcx.types.usize {

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ pub enum RuntimePhase {
139139
/// * [`TerminatorKind::Yield`]
140140
/// * [`TerminatorKind::GeneratorDrop`]
141141
/// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
142+
/// * [`PlaceElem::OpaqueCast`]
142143
///
143144
/// And the following variants are allowed:
144145
/// * [`StatementKind::Retag`]

compiler/rustc_mir_dataflow/src/elaborate_drops.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ where
194194
D: DropElaborator<'b, 'tcx>,
195195
'tcx: 'b,
196196
{
197+
#[instrument(level = "trace", skip(self), ret)]
197198
fn place_ty(&self, place: Place<'tcx>) -> Ty<'tcx> {
198199
place.ty(self.elaborator.body(), self.tcx()).ty
199200
}
@@ -220,11 +221,9 @@ where
220221
//
221222
// FIXME: I think we should just control the flags externally,
222223
// and then we do not need this machinery.
224+
#[instrument(level = "debug")]
223225
pub fn elaborate_drop(&mut self, bb: BasicBlock) {
224-
debug!("elaborate_drop({:?}, {:?})", bb, self);
225-
let style = self.elaborator.drop_style(self.path, DropFlagMode::Deep);
226-
debug!("elaborate_drop({:?}, {:?}): live - {:?}", bb, self, style);
227-
match style {
226+
match self.elaborator.drop_style(self.path, DropFlagMode::Deep) {
228227
DropStyle::Dead => {
229228
self.elaborator
230229
.patch()

compiler/rustc_mir_transform/src/elaborate_drops.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> {
170170
self.ctxt.param_env()
171171
}
172172

173+
#[instrument(level = "debug", skip(self), ret)]
173174
fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle {
174175
let ((maybe_live, maybe_dead), multipart) = match mode {
175176
DropFlagMode::Shallow => (self.ctxt.init_data.maybe_live_dead(path), false),

compiler/rustc_mir_transform/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
480480
let passes: &[&dyn MirPass<'tcx>] = &[
481481
// These next passes must be executed together
482482
&add_call_guards::CriticalCallEdges,
483+
&reveal_all::RevealAll, // has to be done before drop elaboration, since we need to drop opaque types, too.
483484
&elaborate_drops::ElaborateDrops,
484485
// This will remove extraneous landing pads which are no longer
485486
// 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>) {
526527
body,
527528
&[
528529
&check_alignment::CheckAlignment,
529-
&reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode.
530530
&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
531531
&unreachable_prop::UnreachablePropagation,
532532
&uninhabited_enum_branching::UninhabitedEnumBranching,

compiler/rustc_mir_transform/src/reveal_all.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
88
pub struct RevealAll;
99

1010
impl<'tcx> MirPass<'tcx> for RevealAll {
11-
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
12-
sess.mir_opt_level() >= 3 || super::inline::Inline.is_enabled(sess)
13-
}
14-
1511
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
16-
// Do not apply this transformation to generators.
17-
if body.generator.is_some() {
18-
return;
19-
}
20-
2112
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
2213
RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body);
2314
}
@@ -34,6 +25,29 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
3425
self.tcx
3526
}
3627

28+
#[inline]
29+
fn visit_place(
30+
&mut self,
31+
place: &mut Place<'tcx>,
32+
_context: PlaceContext,
33+
_location: Location,
34+
) {
35+
// Performance optimization: don't reintern if there is no `OpaqueCast` to remove.
36+
if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) {
37+
return;
38+
}
39+
// `OpaqueCast` projections are only needed if there are opaque types on which projections are performed.
40+
// After the `RevealAll` pass, all opaque types are replaced with their hidden types, so we don't need these
41+
// projections anymore.
42+
place.projection = self.tcx.mk_place_elems(
43+
&place
44+
.projection
45+
.into_iter()
46+
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
47+
.collect::<Vec<_>>(),
48+
);
49+
}
50+
3751
#[inline]
3852
fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, _: Location) {
3953
// We have to use `try_normalize_erasing_regions` here, since it's

0 commit comments

Comments
 (0)