Skip to content

Commit 4b1d70b

Browse files
committed
Improve MIR phase comments.
I found the dialect/phase distinction quite confusing when I first read these comments. This commit clarifies things a bit.
1 parent 6456740 commit 4b1d70b

File tree

1 file changed

+30
-22
lines changed

1 file changed

+30
-22
lines changed

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,44 +23,50 @@ use crate::ty::{self, GenericArgsRef, List, Region, Ty, UserTypeAnnotationIndex}
2323

2424
/// Represents the "flavors" of MIR.
2525
///
26-
/// All flavors of MIR use the same data structure, but there are some important differences. These
27-
/// differences come in two forms: Dialects and phases.
26+
/// All flavors of MIR use the same data structure, but there are some important differences. Each
27+
/// flavor has (a) a dialect and, (b) a phase within that dialect. A single
28+
/// `MirPhase` value specifies both a dialect and a phase.
2829
///
29-
/// Dialects represent a stronger distinction than phases. This is because the transitions between
30-
/// dialects are semantic changes, and therefore technically *lowerings* between distinct IRs. In
31-
/// other words, the same [`Body`](crate::mir::Body) might be well-formed for multiple dialects, but
32-
/// have different semantic meaning and different behavior at runtime.
30+
/// Different MIR dialects have different semantics. (The differences between dialects are small,
31+
/// but they do exist.) The progression from one MIR dialect to the next is technically a lowering
32+
/// from one IR to another. In other words, a single well-formed [`Body`](crate::mir::Body) might
33+
/// have different semantic meaning and different behavior at runtime in the different dialects.
34+
/// The specific differences between dialects are described on the variants below.
3335
///
34-
/// Each dialect additionally has a number of phases. However, phase changes never involve semantic
35-
/// changes. If some MIR is well-formed both before and after a phase change, it is also guaranteed
36-
/// that it has the same semantic meaning. In this sense, phase changes can only add additional
37-
/// restrictions on what MIR is well-formed.
36+
/// Within a dialect there are one or more phases. Phases exist only to place restrictions on what
37+
/// language constructs are permitted in well-formed MIR, and subsequent phases mostly increase
38+
/// those restrictions. I.e. to convert MIR from one phase to the next might require
39+
/// removing/replacing certain MIR constructs.
3840
///
39-
/// When adding phases, remember to update [`MirPhase::phase_index`].
41+
/// When adding dialects or phases, remember to update [`MirPhase::phase_index`].
4042
#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
4143
#[derive(HashStable)]
4244
pub enum MirPhase {
43-
/// The MIR that is generated by MIR building.
45+
/// The "built MIR" dialect, as generated by MIR building.
4446
///
4547
/// The only things that operate on this dialect are unsafeck, the various MIR lints, and const
4648
/// qualifs.
4749
///
48-
/// This has no distinct phases.
50+
/// This dialect has just the one (implicit) phase, which places few restrictions on what MIR
51+
/// constructs are allowed.
4952
Built,
50-
/// The MIR used for most analysis.
53+
54+
/// The "analysis MIR" dialect, used for borrowck and friends.
5155
///
52-
/// The only semantic change between analysis and built MIR is constant promotion. In built MIR,
53-
/// sequences of statements that would generally be subject to constant promotion are
54-
/// semantically constants, while in analysis MIR all constants are explicit.
56+
/// The only semantic difference between built MIR and analysis MIR relates to constant
57+
/// promotion. In built MIR, sequences of statements that would generally be subject to
58+
/// constant promotion are semantically constants, while in analysis MIR all constants are
59+
/// explicit.
5560
///
5661
/// The result of const promotion is available from the `mir_promoted` and `promoted_mir`
5762
/// queries.
5863
///
59-
/// This is the version of MIR used by borrowck and friends.
64+
/// The phases of this dialect are described in `AnalysisPhase`.
6065
Analysis(AnalysisPhase),
61-
/// The MIR used for CTFE, optimizations, and codegen.
66+
67+
/// The "runtime MIR" dialect, used for CTFE, optimizations, and codegen.
6268
///
63-
/// The semantic changes that occur in the lowering from analysis to runtime MIR are as follows:
69+
/// The semantic differences between analysis MIR and runtime MIR are as follows.
6470
///
6571
/// - Drops: In analysis MIR, `Drop` terminators represent *conditional* drops; roughly
6672
/// speaking, if dataflow analysis determines that the place being dropped is uninitialized,
@@ -80,13 +86,15 @@ pub enum MirPhase {
8086
/// retags can still occur at `Rvalue::{Ref,AddrOf}`).
8187
/// - Coroutine bodies: In analysis MIR, locals may actually be behind a pointer that user code
8288
/// has access to. This occurs in coroutine bodies. Such locals do not behave like other
83-
/// locals, because they eg may be aliased in surprising ways. Runtime MIR has no such
89+
/// locals, because they e.g. may be aliased in surprising ways. Runtime MIR has no such
8490
/// special locals. All coroutine bodies are lowered and so all places that look like locals
8591
/// really are locals.
8692
///
8793
/// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part
8894
/// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that
89-
/// transformations which may suppress such errors should not run on analysis MIR.
95+
/// transformations that can suppress such errors should not run on analysis MIR.
96+
///
97+
/// The phases of this dialect are described in `RuntimePhase`.
9098
Runtime(RuntimePhase),
9199
}
92100

0 commit comments

Comments
 (0)