Skip to content

Commit c545019

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

+1-1
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

-8
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

+3-1
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

+3-1
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

+8
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

+1
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

+3-4
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

+1
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

+1-1
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

+23-9
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

tests/incremental/hashes/function_interfaces.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ pub fn return_impl_trait() -> i32 {
302302
}
303303

304304
#[cfg(not(any(cfail1,cfail4)))]
305-
#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")]
305+
#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig")]
306306
#[rustc_clean(cfg = "cfail3")]
307307
#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")]
308308
#[rustc_clean(cfg = "cfail6")]

tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir

+46-40
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
/* generator_layout = GeneratorLayout {
33
field_tys: {
44
_0: GeneratorSavedTy {
5-
ty: Alias(
6-
Opaque,
7-
AliasTy {
8-
args: [
9-
],
10-
def_id: DefId(0:7 ~ async_await[ccf8]::a::{opaque#0}),
11-
},
5+
ty: Generator(
6+
DefId(0:4 ~ async_await[ccf8]::a::{closure#0}),
7+
[
8+
std::future::ResumeTy,
9+
(),
10+
(),
11+
GeneratorWitness(DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), []),
12+
(),
13+
],
14+
Static,
1215
),
1316
source_info: SourceInfo {
1417
span: $DIR/async_await.rs:15:9: 15:14 (#8),
@@ -17,13 +20,16 @@
1720
ignore_for_traits: false,
1821
},
1922
_1: GeneratorSavedTy {
20-
ty: Alias(
21-
Opaque,
22-
AliasTy {
23-
args: [
24-
],
25-
def_id: DefId(0:7 ~ async_await[ccf8]::a::{opaque#0}),
26-
},
23+
ty: Generator(
24+
DefId(0:4 ~ async_await[ccf8]::a::{closure#0}),
25+
[
26+
std::future::ResumeTy,
27+
(),
28+
(),
29+
GeneratorWitness(DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), []),
30+
(),
31+
],
32+
Static,
2733
),
2834
source_info: SourceInfo {
2935
span: $DIR/async_await.rs:16:9: 16:14 (#10),
@@ -49,30 +55,30 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
4955
debug _task_context => _38;
5056
let mut _0: std::task::Poll<()>;
5157
let _3: ();
52-
let mut _4: impl std::future::Future<Output = ()>;
53-
let mut _5: impl std::future::Future<Output = ()>;
54-
let mut _6: impl std::future::Future<Output = ()>;
58+
let mut _4: {async fn body@$DIR/async_await.rs:11:14: 11:16};
59+
let mut _5: {async fn body@$DIR/async_await.rs:11:14: 11:16};
60+
let mut _6: {async fn body@$DIR/async_await.rs:11:14: 11:16};
5561
let mut _7: ();
5662
let _8: ();
5763
let mut _9: std::task::Poll<()>;
58-
let mut _10: std::pin::Pin<&mut impl std::future::Future<Output = ()>>;
59-
let mut _11: &mut impl std::future::Future<Output = ()>;
60-
let mut _12: &mut impl std::future::Future<Output = ()>;
64+
let mut _10: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>;
65+
let mut _11: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
66+
let mut _12: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
6167
let mut _13: &mut std::task::Context<'_>;
6268
let mut _14: &mut std::task::Context<'_>;
6369
let mut _15: &mut std::task::Context<'_>;
6470
let mut _16: isize;
6571
let mut _18: !;
6672
let mut _19: &mut std::task::Context<'_>;
6773
let mut _20: ();
68-
let mut _21: impl std::future::Future<Output = ()>;
69-
let mut _22: impl std::future::Future<Output = ()>;
70-
let mut _23: impl std::future::Future<Output = ()>;
74+
let mut _21: {async fn body@$DIR/async_await.rs:11:14: 11:16};
75+
let mut _22: {async fn body@$DIR/async_await.rs:11:14: 11:16};
76+
let mut _23: {async fn body@$DIR/async_await.rs:11:14: 11:16};
7177
let _24: ();
7278
let mut _25: std::task::Poll<()>;
73-
let mut _26: std::pin::Pin<&mut impl std::future::Future<Output = ()>>;
74-
let mut _27: &mut impl std::future::Future<Output = ()>;
75-
let mut _28: &mut impl std::future::Future<Output = ()>;
79+
let mut _26: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>;
80+
let mut _27: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
81+
let mut _28: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
7682
let mut _29: &mut std::task::Context<'_>;
7783
let mut _30: &mut std::task::Context<'_>;
7884
let mut _31: &mut std::task::Context<'_>;
@@ -84,7 +90,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
8490
let mut _38: &mut std::task::Context<'_>;
8591
let mut _39: u32;
8692
scope 1 {
87-
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future<Output = ()>);
93+
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
8894
let _17: ();
8995
scope 2 {
9096
}
@@ -93,7 +99,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
9399
}
94100
}
95101
scope 4 {
96-
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future<Output = ()>);
102+
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
97103
let _33: ();
98104
scope 5 {
99105
}
@@ -116,13 +122,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
116122
}
117123

118124
bb2: {
119-
_4 = <impl Future<Output = ()> as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable];
125+
_4 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable];
120126
}
121127

122128
bb3: {
123129
StorageDead(_5);
124130
nop;
125-
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future<Output = ()>) = move _4;
131+
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _4;
126132
goto -> bb4;
127133
}
128134

@@ -132,9 +138,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
132138
StorageLive(_10);
133139
StorageLive(_11);
134140
StorageLive(_12);
135-
_12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future<Output = ()>);
141+
_12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
136142
_11 = &mut (*_12);
137-
_10 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _11) -> [return: bb5, unwind unreachable];
143+
_10 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable];
138144
}
139145

140146
bb5: {
@@ -150,7 +156,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
150156
bb6: {
151157
_13 = &mut (*_14);
152158
StorageDead(_15);
153-
_9 = <impl Future<Output = ()> as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable];
159+
_9 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable];
154160
}
155161

156162
bb7: {
@@ -187,7 +193,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
187193
StorageDead(_12);
188194
StorageDead(_9);
189195
StorageDead(_8);
190-
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future<Output = ()>)) -> [return: bb12, unwind unreachable];
196+
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb12, unwind unreachable];
191197
}
192198

193199
bb11: {
@@ -212,13 +218,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
212218
}
213219

214220
bb14: {
215-
_21 = <impl Future<Output = ()> as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable];
221+
_21 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable];
216222
}
217223

218224
bb15: {
219225
StorageDead(_22);
220226
nop;
221-
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future<Output = ()>) = move _21;
227+
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _21;
222228
goto -> bb16;
223229
}
224230

@@ -228,9 +234,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
228234
StorageLive(_26);
229235
StorageLive(_27);
230236
StorageLive(_28);
231-
_28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future<Output = ()>);
237+
_28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
232238
_27 = &mut (*_28);
233-
_26 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _27) -> [return: bb17, unwind unreachable];
239+
_26 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable];
234240
}
235241

236242
bb17: {
@@ -246,7 +252,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
246252
bb18: {
247253
_29 = &mut (*_30);
248254
StorageDead(_31);
249-
_25 = <impl Future<Output = ()> as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable];
255+
_25 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable];
250256
}
251257

252258
bb19: {
@@ -279,7 +285,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
279285
StorageDead(_28);
280286
StorageDead(_25);
281287
StorageDead(_24);
282-
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future<Output = ()>)) -> [return: bb23, unwind unreachable];
288+
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb23, unwind unreachable];
283289
}
284290

285291
bb22: {

0 commit comments

Comments
 (0)