Skip to content

Commit ca63c4d

Browse files
committed
Auto merge of #164077 - adwinwhite:phase-hack, r=<try>
replace `TypingEnv::post_analysis()` with `mir::Body::typing_env()`
2 parents 2d20b42 + 3958cd2 commit ca63c4d

9 files changed

Lines changed: 83 additions & 43 deletions

File tree

‎compiler/rustc_middle/src/mir/mod.rs‎

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,21 @@ pub enum MentionedItem<'tcx> {
200200
Closure(Ty<'tcx>),
201201
}
202202

203+
/// Track what typing mode a MIR body should use at current stage.
204+
/// A MIR body usually starts with `PostTypeckThroughBorrowck`. After borrowck is done, it's set
205+
/// to `PostBorrowck`. In `PostAnalysisNormalize` pass, we reveal all opaques types and set the
206+
/// typing mode to `PostAnalysis`.
207+
///
208+
/// We can't directly use `ty::TypingMode` since it's not `TyEncodable/TyDecodable`.
209+
/// Previously we use MIR phase to derive this but it's inaccurate.
210+
#[derive(Copy, Clone, PartialEq, Debug)]
211+
#[derive(TyEncodable, TyDecodable, StableHash, TypeFoldable, TypeVisitable)]
212+
pub enum BodyTypingMode {
213+
PostTypeckThroughBorrowck,
214+
PostBorrowck,
215+
PostAnalysis,
216+
}
217+
203218
/// The lowered representation of a single function.
204219
#[derive(Clone, TyEncodable, TyDecodable, Debug, StableHash, TypeFoldable, TypeVisitable)]
205220
pub struct Body<'tcx> {
@@ -214,6 +229,9 @@ pub struct Body<'tcx> {
214229
/// us to see the difference and forego optimization on the inlined promoted items.
215230
pub phase: MirPhase,
216231

232+
/// See [`BodyTypingMode`] for more info.
233+
pub typing_mode: BodyTypingMode,
234+
217235
/// How many passes we have executed since starting the current phase. Used for debug output.
218236
pub pass_count: usize,
219237

@@ -352,6 +370,7 @@ impl<'tcx> Body<'tcx> {
352370

353371
let mut body = Body {
354372
phase: MirPhase::Built,
373+
typing_mode: BodyTypingMode::PostTypeckThroughBorrowck,
355374
pass_count: 0,
356375
source,
357376
basic_blocks: BasicBlocks::new(basic_blocks),
@@ -383,6 +402,7 @@ impl<'tcx> Body<'tcx> {
383402
pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
384403
let mut body = Body {
385404
phase: MirPhase::Built,
405+
typing_mode: BodyTypingMode::PostTypeckThroughBorrowck,
386406
pass_count: 0,
387407
source: MirSource::item(CRATE_DEF_ID.to_def_id()),
388408
basic_blocks: BasicBlocks::new(basic_blocks),
@@ -413,38 +433,35 @@ impl<'tcx> Body<'tcx> {
413433

414434
pub fn typing_env(&self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
415435
if tcx.use_typing_mode_post_typeck_through_borrowck() {
416-
match self.phase {
417-
MirPhase::Built | MirPhase::Analysis(AnalysisPhase::Initial)
418-
if let Some(def_id) = self.source.def_id().as_local() =>
419-
{
436+
match self.typing_mode {
437+
BodyTypingMode::PostTypeckThroughBorrowck => {
438+
let local_def_id =
439+
self.source.def_id().as_local().expect("We only build MIR for local body");
420440
TypingEnv::new(
421441
tcx.param_env(self.source.def_id()),
422-
ty::TypingMode::borrowck(tcx, def_id),
442+
ty::TypingMode::borrowck(tcx, local_def_id),
423443
)
424444
}
425-
MirPhase::Analysis(AnalysisPhase::PostCleanup)
426-
if let Some(def_id) = self.source.def_id().as_local() =>
427-
{
445+
BodyTypingMode::PostBorrowck => {
446+
let local_def_id =
447+
self.source.def_id().as_local().expect("We only build MIR for local body");
428448
TypingEnv::new(
429449
tcx.param_env(self.source.def_id()),
430-
ty::TypingMode::post_borrowck_analysis(tcx, def_id),
450+
ty::TypingMode::post_borrowck_analysis(tcx, local_def_id),
431451
)
432452
}
433-
MirPhase::Built | MirPhase::Analysis(_) => {
434-
// This branch happens for drop glue and fn ptr shims.
435-
// FIXME: why do we do any of this analysis on drop glue etc?
436-
// This should ideally all be skipped.
437-
TypingEnv::post_analysis(tcx, self.source.def_id())
438-
}
439-
MirPhase::Runtime(_) => TypingEnv::post_analysis(tcx, self.source.def_id()),
453+
// We build shims like `drop_in_place` in post analysis typing mode.
454+
BodyTypingMode::PostAnalysis => TypingEnv::post_analysis(tcx, self.source.def_id()),
440455
}
441456
} else {
442-
match self.phase {
443-
MirPhase::Built | MirPhase::Analysis(_) => TypingEnv::new(
444-
tcx.param_env(self.source.def_id()),
445-
ty::TypingMode::non_body_analysis(),
446-
),
447-
MirPhase::Runtime(_) => TypingEnv::post_analysis(tcx, self.source.def_id()),
457+
match self.typing_mode {
458+
BodyTypingMode::PostTypeckThroughBorrowck | BodyTypingMode::PostBorrowck => {
459+
TypingEnv::new(
460+
tcx.param_env(self.source.def_id()),
461+
ty::TypingMode::non_body_analysis(),
462+
)
463+
}
464+
BodyTypingMode::PostAnalysis => TypingEnv::post_analysis(tcx, self.source.def_id()),
448465
}
449466
}
450467
}

‎compiler/rustc_mir_build/src/builder/custom/mod.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ pub(super) fn build_custom_mir<'tcx>(
4545
basic_blocks: BasicBlocks::new(IndexVec::new()),
4646
source: MirSource::item(did),
4747
phase: MirPhase::Built,
48+
typing_mode: BodyTypingMode::PostTypeckThroughBorrowck,
4849
source_scopes: IndexVec::new(),
4950
coroutine: None,
5051
local_decls: IndexVec::new(),
@@ -73,6 +74,9 @@ pub(super) fn build_custom_mir<'tcx>(
7374
local_data: ClearCrossCrate::Set(SourceScopeLocalData { lint_root: hir_id }),
7475
});
7576
body.injection_phase = Some(parse_attribute(dialect, phase));
77+
if let Some(MirPhase::Runtime(_)) = body.injection_phase {
78+
body.typing_mode = BodyTypingMode::PostAnalysis;
79+
}
7680

7781
let mut pctxt = ParseCtxt {
7882
tcx,

‎compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_middle::mir::*;
2-
use rustc_middle::ty::{self, TyCtxt};
2+
use rustc_middle::ty::TyCtxt;
33
use tracing::debug;
44

55
use crate::patch::MirPatch;
@@ -41,9 +41,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops {
4141
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
4242
debug!("add_moves_for_packed_drops({:?} @ {:?})", body.source, body.span);
4343
let mut patch = MirPatch::new(body);
44-
// FIXME(#132279): This is used during the phase transition from analysis
45-
// to runtime, so we have to manually specify the correct typing mode.
46-
let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id());
44+
let typing_env = body.typing_env(tcx);
4745

4846
for (bb, data) in body.basic_blocks.iter_enumerated() {
4947
let loc = Location { block: bb, statement_index: data.statements.len() };

‎compiler/rustc_mir_transform/src/elaborate_drops.rs‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
5252
#[instrument(level = "trace", skip(self, tcx, body))]
5353
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
5454
debug!("elaborate_drops({:?} @ {:?})", body.source, body.span);
55-
// FIXME(#132279): This is used during the phase transition from analysis
56-
// to runtime, so we have to manually specify the correct typing mode.
57-
let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id());
55+
let typing_env = body.typing_env(tcx);
5856
// For types that do not need dropping, the behaviour is trivial. So we only need to track
5957
// init/uninit for types that do need dropping.
6058
let move_data = MoveData::gather_moves(body, tcx, |ty| ty.needs_drop(tcx, typing_env));

‎compiler/rustc_mir_transform/src/known_panics_lint.rs‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,7 @@ impl<'tcx> ty::layout::HasTypingEnv<'tcx> for ConstPropagator<'_, 'tcx> {
181181
impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
182182
fn new(body: &'mir Body<'tcx>, tcx: TyCtxt<'tcx>) -> ConstPropagator<'mir, 'tcx> {
183183
let def_id = body.source.def_id();
184-
// FIXME(#132279): This is used during the phase transition from analysis
185-
// to runtime, so we have to manually specify the correct typing mode.
186-
let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id());
184+
let typing_env = body.typing_env(tcx);
187185
let can_const_prop = CanConstProp::check(tcx, typing_env, body);
188186
let ecx = InterpCx::new(tcx, tcx.def_span(def_id), typing_env, DummyMachine);
189187

‎compiler/rustc_mir_transform/src/lib.rs‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ use rustc_hir::def::{CtorKind, DefKind};
2020
use rustc_hir::def_id::LocalDefId;
2121
use rustc_index::IndexVec;
2222
use rustc_middle::mir::{
23-
AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs, LocalDecl,
24-
MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, START_BLOCK,
25-
SourceInfo, Statement, StatementKind, TerminatorKind, WithRetag,
23+
AnalysisPhase, Body, BodyTypingMode, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs,
24+
LocalDecl, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue,
25+
START_BLOCK, SourceInfo, Statement, StatementKind, TerminatorKind, WithRetag,
2626
};
2727
use rustc_middle::query;
2828
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
@@ -598,6 +598,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
598598
_ => {}
599599
}
600600

601+
body.typing_mode = BodyTypingMode::PostBorrowck;
601602
run_analysis_to_runtime_passes(tcx, &mut body);
602603

603604
tcx.alloc_steal_mir(body)
@@ -606,12 +607,13 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
606607
// Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
607608
// by custom rustc drivers, running all the steps by themselves. See #114628.
608609
pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
609-
assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial));
610+
assert_eq!(body.typing_mode, BodyTypingMode::PostBorrowck);
611+
assert_eq!(body.phase, MirPhase::Analysis(AnalysisPhase::Initial));
610612
let did = body.source.def_id();
611613

612614
debug!("analysis_mir_cleanup({:?})", did);
613615
run_analysis_cleanup_passes(tcx, body);
614-
assert!(body.phase == MirPhase::Analysis(AnalysisPhase::PostCleanup));
616+
assert_eq!(body.phase, MirPhase::Analysis(AnalysisPhase::PostCleanup));
615617

616618
// Do a little drop elaboration before const-checking if `const_precise_live_drops` is enabled.
617619
if check_consts::post_drop_elaboration::checking_enabled(&ConstCx::new(tcx, body)) {
@@ -629,11 +631,12 @@ pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
629631

630632
debug!("runtime_mir_lowering({:?})", did);
631633
run_runtime_lowering_passes(tcx, body);
632-
assert!(body.phase == MirPhase::Runtime(RuntimePhase::Initial));
634+
assert_eq!(body.phase, MirPhase::Runtime(RuntimePhase::Initial));
633635

634636
debug!("runtime_mir_cleanup({:?})", did);
635637
run_runtime_cleanup_passes(tcx, body);
636-
assert!(body.phase == MirPhase::Runtime(RuntimePhase::PostCleanup));
638+
assert_eq!(body.typing_mode, BodyTypingMode::PostAnalysis);
639+
assert_eq!(body.phase, MirPhase::Runtime(RuntimePhase::PostCleanup));
637640
}
638641

639642
// FIXME(JakobDegen): Can we make these lists of passes consts?
@@ -848,6 +851,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_
848851
let mut promoted = tcx.mir_promoted(def).1.steal();
849852

850853
for body in &mut promoted {
854+
body.typing_mode = BodyTypingMode::PostBorrowck;
851855
run_analysis_to_runtime_passes(tcx, body);
852856
}
853857

‎compiler/rustc_mir_transform/src/pass_manager.rs‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::sync::atomic::Ordering;
55
use rustc_attr_ir::OptimizeAttr;
66
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
77
use rustc_hir::def_id::DefId;
8-
use rustc_middle::mir::{Body, MirDumper, MirPhase, RuntimePhase};
8+
use rustc_middle::mir::{Body, BodyTypingMode, MirDumper, MirPhase, RuntimePhase};
99
use rustc_middle::ty::TyCtxt;
1010
use rustc_session::Session;
1111
use rustc_session::config::OptLevel;
@@ -388,6 +388,26 @@ fn run_passes_inner<'tcx>(
388388
panic!("Invalid MIR phase transition from {:?} to {:?}", body.phase, new_phase);
389389
}
390390

391+
// Custom MIR can skip analysis-to-runtime lowering where we update
392+
// the typing mode for normal MIR body.
393+
//
394+
// FIXME: it's ugly that we set the typing mode of custom MIR in the
395+
// runtime phase to `PostBorrowck` after borrowck and then back to
396+
// `PostAnalysis` here.
397+
if matches!(body.injection_phase, Some(MirPhase::Runtime(_)))
398+
&& matches!(new_phase, MirPhase::Runtime(_))
399+
{
400+
body.typing_mode = BodyTypingMode::PostAnalysis;
401+
}
402+
403+
// We perform type mode transitions in MIR transform. But some bodies don't actually
404+
// undergo analysis-to-runtime lowering, such as shims and sometimes custom MIR.
405+
// We try to guard against future MIR building procedures that don't go through the usual
406+
// lowering. The final validation is expected to run in `TypingMode::PostAnalysis`.
407+
if new_phase == MirPhase::Runtime(RuntimePhase::Optimized) {
408+
assert_eq!(body.typing_mode, BodyTypingMode::PostAnalysis);
409+
}
410+
391411
body.phase = new_phase;
392412
body.pass_count = 0;
393413

‎compiler/rustc_mir_transform/src/post_analysis_normalize.rs‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ pub(super) struct PostAnalysisNormalize;
1212

1313
impl<'tcx> crate::MirPass<'tcx> for PostAnalysisNormalize {
1414
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
15-
// FIXME(#132279): This is used during the phase transition from analysis
16-
// to runtime, so we have to manually specify the correct typing mode.
17-
let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id());
15+
body.typing_mode = BodyTypingMode::PostAnalysis;
16+
let typing_env = body.typing_env(tcx);
1817
PostAnalysisNormalizeVisitor { tcx, typing_env }.visit_body_preserves_cfg(body);
1918
}
2019

‎compiler/rustc_mir_transform/src/shim.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ fn new_body<'tcx>(
402402
);
403403
// Shims do not directly mention any consts.
404404
body.set_required_consts(Vec::new());
405+
// We don't do any analysis on shims.
406+
body.typing_mode = BodyTypingMode::PostAnalysis;
405407
body
406408
}
407409

0 commit comments

Comments
 (0)