@@ -23,68 +23,77 @@ 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+ /// The MIR pipeline is structured into a few major dialects, with one or more phases within each
27+ /// dialect. A MIR flavor is identified by a dialect-phase pair. A single `MirPhase` value
28+ /// specifies such a pair. All flavors of MIR use the same data structure to represent the program.
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+ /// Phases exist only to place restrictions on what language constructs are permitted in
37+ /// well-formed MIR, and subsequent phases mostly increase those restrictions. I.e. to convert MIR
38+ /// from one phase to the next might require removing/replacing certain MIR constructs.
3839///
39- /// When adding phases, remember to update [`MirPhase::phase_index `].
40+ /// When adding dialects or phases, remember to update [`MirPhase::index `].
4041#[ derive( Copy , Clone , TyEncodable , TyDecodable , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
4142#[ derive( HashStable ) ]
4243pub enum MirPhase {
43- /// The MIR that is generated by MIR building.
44+ /// The "built MIR" dialect, as generated by MIR building.
4445 ///
4546 /// The only things that operate on this dialect are unsafeck, the various MIR lints, and const
4647 /// qualifs.
4748 ///
48- /// This has no distinct phases.
49+ /// This dialect has just the one (implicit) phase, which places few restrictions on what MIR
50+ /// constructs are allowed.
4951 Built ,
50- /// The MIR used for most analysis.
52+
53+ /// The "analysis MIR" dialect, used for borrowck and friends.
5154 ///
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.
55+ /// The only semantic difference between built MIR and analysis MIR relates to constant
56+ /// promotion. In built MIR, sequences of statements that would generally be subject to
57+ /// constant promotion are semantically constants, while in analysis MIR all constants are
58+ /// explicit.
5559 ///
56- /// The result of const promotion is available from the `mir_promoted` and `promoted_mir` queries.
60+ /// The result of const promotion is available from the `mir_promoted` and `promoted_mir`
61+ /// queries.
5762 ///
58- /// This is the version of MIR used by borrowck and friends .
63+ /// The phases of this dialect are described in `AnalysisPhase` .
5964 Analysis ( AnalysisPhase ) ,
60- /// The MIR used for CTFE, optimizations, and codegen.
61- ///
62- /// The semantic changes that occur in the lowering from analysis to runtime MIR are as follows:
63- ///
64- /// - Drops: In analysis MIR, `Drop` terminators represent *conditional* drops; roughly speaking,
65- /// if dataflow analysis determines that the place being dropped is uninitialized, the drop will
66- /// not be executed. The exact semantics of this aren't written down anywhere, which means they
67- /// are essentially "what drop elaboration does." In runtime MIR, the drops are unconditional;
68- /// when a `Drop` terminator is reached, if the type has drop glue that drop glue is always
69- /// executed. This may be UB if the underlying place is not initialized.
70- /// - Packed drops: Places might in general be misaligned - in most cases this is UB, the exception
71- /// is fields of packed structs. In analysis MIR, `Drop(P)` for a `P` that might be misaligned
72- /// for this reason implicitly moves `P` to a temporary before dropping. Runtime MIR has no such
73- /// rules, and dropping a misaligned place is simply UB.
74- /// - Unwinding: in analysis MIR, unwinding from a function which may not unwind aborts. In runtime
75- /// MIR, this is UB.
76- /// - Retags: If `-Zmir-emit-retag` is enabled, analysis MIR has "implicit" retags in the same way
77- /// that Rust itself has them. Where exactly these are is generally subject to change, and so we
78- /// don't document this here. Runtime MIR has most retags explicit (though implicit retags
79- /// can still occur at `Rvalue::{Ref,AddrOf}`).
80- /// - Coroutine bodies: In analysis MIR, locals may actually be behind a pointer that user code has
81- /// access to. This occurs in coroutine bodies. Such locals do not behave like other locals,
82- /// because they eg may be aliased in surprising ways. Runtime MIR has no such special locals -
83- /// all coroutine bodies are lowered and so all places that look like locals really are locals.
65+
66+ /// The "runtime MIR" dialect, used for CTFE, optimizations, and codegen.
67+ ///
68+ /// The semantic differences between analysis MIR and runtime MIR are as follows.
69+ ///
70+ /// - Drops: In analysis MIR, `Drop` terminators represent *conditional* drops; roughly
71+ /// speaking, if dataflow analysis determines that the place being dropped is uninitialized,
72+ /// the drop will not be executed. The exact semantics of this aren't written down anywhere,
73+ /// which means they are essentially "what drop elaboration does." In runtime MIR, the drops
74+ /// are unconditional; when a `Drop` terminator is reached, if the type has drop glue that
75+ /// drop glue is always executed. This may be UB if the underlying place is not initialized.
76+ /// - Packed drops: Places might in general be misaligned - in most cases this is UB, the
77+ /// exception is fields of packed structs. In analysis MIR, `Drop(P)` for a `P` that might be
78+ /// misaligned for this reason implicitly moves `P` to a temporary before dropping. Runtime
79+ /// MIR has no such rules, and dropping a misaligned place is simply UB.
80+ /// - Unwinding: in analysis MIR, unwinding from a function which may not unwind aborts. In
81+ /// runtime MIR, this is UB.
82+ /// - Retags: If `-Zmir-emit-retag` is enabled, analysis MIR has "implicit" retags in the same
83+ /// way that Rust itself has them. Where exactly these are is generally subject to change,
84+ /// and so we don't document this here. Runtime MIR has most retags explicit (though implicit
85+ /// retags can still occur at `Rvalue::{Ref,AddrOf}`).
86+ /// - Coroutine bodies: In analysis MIR, locals may actually be behind a pointer that user code
87+ /// has access to. This occurs in coroutine bodies. Such locals do not behave like other
88+ /// locals, because they e.g. may be aliased in surprising ways. Runtime MIR has no such
89+ /// special locals. All coroutine bodies are lowered and so all places that look like locals
90+ /// really are locals.
8491 ///
8592 /// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part
8693 /// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that
87- /// transformations which may suppress such errors should not run on analysis MIR.
94+ /// transformations that can suppress such errors should not run on analysis MIR.
95+ ///
96+ /// The phases of this dialect are described in `RuntimePhase`.
8897 Runtime ( RuntimePhase ) ,
8998}
9099
@@ -111,7 +120,8 @@ pub enum AnalysisPhase {
111120 /// * [`TerminatorKind::FalseEdge`]
112121 /// * [`StatementKind::FakeRead`]
113122 /// * [`StatementKind::AscribeUserType`]
114- /// * [`StatementKind::Coverage`] with [`CoverageKind::BlockMarker`] or [`CoverageKind::SpanMarker`]
123+ /// * [`StatementKind::Coverage`] with [`CoverageKind::BlockMarker`] or
124+ /// [`CoverageKind::SpanMarker`]
115125 /// * [`Rvalue::Ref`] with `BorrowKind::Fake`
116126 /// * [`CastKind::PointerCoercion`] with any of the following:
117127 /// * [`PointerCoercion::ArrayToPointer`]
0 commit comments