Skip to content

Commit a43e486

Browse files
Add MIR phase and query for drop elaboration
1 parent f5370fa commit a43e486

File tree

3 files changed

+48
-10
lines changed

3 files changed

+48
-10
lines changed

src/librustc_middle/mir/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ pub enum MirPhase {
7676
Build = 0,
7777
Const = 1,
7878
Validated = 2,
79-
Optimized = 3,
79+
DropElab = 3,
80+
Optimized = 4,
8081
}
8182

8283
impl MirPhase {

src/librustc_middle/query/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,12 @@ rustc_queries! {
190190
no_hash
191191
}
192192

193+
query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> Steal<mir::Body<'tcx>> {
194+
storage(ArenaCacheSelector<'tcx>)
195+
no_hash
196+
desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.to_def_id()) }
197+
}
198+
193199
query mir_validated(key: LocalDefId) ->
194200
(
195201
Steal<mir::Body<'tcx>>,

src/librustc_mir/transform/mod.rs

+40-9
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub(crate) fn provide(providers: &mut Providers<'_>) {
4949
mir_const,
5050
mir_const_qualif,
5151
mir_validated,
52+
mir_drops_elaborated_and_const_checked,
5253
optimized_mir,
5354
is_mir_available,
5455
promoted_mir,
@@ -294,12 +295,31 @@ fn mir_validated(
294295
(tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
295296
}
296297

297-
fn run_optimization_passes<'tcx>(
298+
fn mir_drops_elaborated_and_const_checked<'tcx>(
299+
tcx: TyCtxt<'tcx>,
300+
def_id: LocalDefId,
301+
) -> Steal<Body<'tcx>> {
302+
// (Mir-)Borrowck uses `mir_validated`, so we have to force it to
303+
// execute before we can steal.
304+
tcx.ensure().mir_borrowck(def_id);
305+
306+
let (body, _) = tcx.mir_validated(def_id);
307+
let mut body = body.steal();
308+
309+
run_post_borrowck_cleanup_passes(tcx, &mut body, def_id, None);
310+
check_consts::post_drop_elaboration::check_live_drops(tcx, def_id, &body);
311+
tcx.alloc_steal_mir(body)
312+
}
313+
314+
/// After this series of passes, no lifetime analysis based on borrowing can be done.
315+
fn run_post_borrowck_cleanup_passes<'tcx>(
298316
tcx: TyCtxt<'tcx>,
299317
body: &mut Body<'tcx>,
300318
def_id: LocalDefId,
301319
promoted: Option<Promoted>,
302320
) {
321+
debug!("post_borrowck_cleanup({:?})", def_id);
322+
303323
let post_borrowck_cleanup: &[&dyn MirPass<'tcx>] = &[
304324
// Remove all things only needed by analysis
305325
&no_landing_pads::NoLandingPads::new(tcx),
@@ -318,9 +338,24 @@ fn run_optimization_passes<'tcx>(
318338
// but before optimizations begin.
319339
&add_retag::AddRetag,
320340
&simplify::SimplifyCfg::new("elaborate-drops"),
321-
// No lifetime analysis based on borrowing can be done from here on out.
322341
];
323342

343+
run_passes(
344+
tcx,
345+
body,
346+
InstanceDef::Item(def_id.to_def_id()),
347+
promoted,
348+
MirPhase::DropElab,
349+
&[post_borrowck_cleanup],
350+
);
351+
}
352+
353+
fn run_optimization_passes<'tcx>(
354+
tcx: TyCtxt<'tcx>,
355+
body: &mut Body<'tcx>,
356+
def_id: LocalDefId,
357+
promoted: Option<Promoted>,
358+
) {
324359
let optimizations: &[&dyn MirPass<'tcx>] = &[
325360
&unreachable_prop::UnreachablePropagation,
326361
&uninhabited_enum_branching::UninhabitedEnumBranching,
@@ -368,14 +403,14 @@ fn run_optimization_passes<'tcx>(
368403

369404
let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level;
370405

406+
#[rustfmt::skip]
371407
run_passes(
372408
tcx,
373409
body,
374410
InstanceDef::Item(def_id.to_def_id()),
375411
promoted,
376412
MirPhase::Optimized,
377413
&[
378-
post_borrowck_cleanup,
379414
if mir_opt_level > 0 { optimizations } else { no_optimizations },
380415
pre_codegen_cleanup,
381416
],
@@ -393,12 +428,7 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
393428

394429
let def_id = def_id.expect_local();
395430

396-
// (Mir-)Borrowck uses `mir_validated`, so we have to force it to
397-
// execute before we can steal.
398-
tcx.ensure().mir_borrowck(def_id);
399-
400-
let (body, _) = tcx.mir_validated(def_id);
401-
let mut body = body.steal();
431+
let mut body = tcx.mir_drops_elaborated_and_const_checked(def_id).steal();
402432
run_optimization_passes(tcx, &mut body, def_id, None);
403433

404434
debug_assert!(!body.has_free_regions(), "Free regions in optimized MIR");
@@ -418,6 +448,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def_id: DefId) -> IndexVec<Promoted, Body<'_>>
418448
let mut promoted = promoted.steal();
419449

420450
for (p, mut body) in promoted.iter_enumerated_mut() {
451+
run_post_borrowck_cleanup_passes(tcx, &mut body, def_id, Some(p));
421452
run_optimization_passes(tcx, &mut body, def_id, Some(p));
422453
}
423454

0 commit comments

Comments
 (0)