@@ -127,12 +127,24 @@ pub trait MirPass<'tcx> {
127
127
/// The various "big phases" that MIR goes through.
128
128
///
129
129
/// These phases all describe dialects of MIR. Since all MIR uses the same datastructures, the
130
- /// dialects forbid certain variants or values in certain phases.
130
+ /// dialects forbid certain variants or values in certain phases. The sections below summarize the
131
+ /// changes, but do not document them thoroughly. The full documentation is found in the appropriate
132
+ /// documentation for the thing the change is affecting.
131
133
///
132
134
/// Warning: ordering of variants is significant.
133
135
#[ derive( Copy , Clone , TyEncodable , TyDecodable , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
134
136
#[ derive( HashStable ) ]
135
137
pub enum MirPhase {
138
+ /// The dialect of MIR used during all phases before `DropsLowered` is the same. This is also
139
+ /// the MIR that analysis such as borrowck uses.
140
+ ///
141
+ /// One important thing to remember about the behavior of this section of MIR is that drop terminators
142
+ /// (including drop and replace) are *conditional*. The elaborate drops pass will then replace each
143
+ /// instance of a drop terminator with a nop, an unconditional drop, or a drop conditioned on a drop
144
+ /// flag. Of course, this means that it is important that the drop elaboration can accurately recognize
145
+ /// when things are initialized and when things are de-initialized. That means any code running on this
146
+ /// version of MIR must be sure to produce output that drop elaboration can reason about. See the
147
+ /// section on the drop terminatorss for more details.
136
148
Built = 0 ,
137
149
// FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query).
138
150
// We used to have this for pre-miri MIR based const eval.
@@ -162,6 +174,16 @@ pub enum MirPhase {
162
174
/// And the following variant is allowed:
163
175
/// * [`StatementKind::SetDiscriminant`]
164
176
Deaggregated = 4 ,
177
+ /// Before this phase, generators are in the "source code" form, featuring `yield` statements
178
+ /// and such. With this phase change, they are transformed into a proper state machine. Running
179
+ /// optimizations before this change can be potentially dangerous because the source code is to
180
+ /// some extent a "lie." In particular, `yield` terminators effectively make the value of all
181
+ /// locals visible to the caller. This means that dead store elimination before them, or code
182
+ /// motion across them, is not correct in general. This is also exasperated by type checking
183
+ /// having pre-computed a list of the types that it thinks are ok to be live across a yield
184
+ /// point - this is necessary to decide eg whether autotraits are implemented. Introducing new
185
+ /// types across a yield point will lead to ICEs becaues of this.
186
+ ///
165
187
/// Beginning with this phase, the following variants are disallowed:
166
188
/// * [`TerminatorKind::Yield`](terminator::TerminatorKind::Yield)
167
189
/// * [`TerminatorKind::GeneratorDrop](terminator::TerminatorKind::GeneratorDrop)
0 commit comments