• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! This defines the syntax of MIR, i.e., the set of available MIR operations, and other definitions
2 //! closely related to MIR semantics.
3 //! This is in a dedicated file so that changes to this file can be reviewed more carefully.
4 //! The intention is that this file only contains datatype declarations, no code.
5 
6 use super::{BasicBlock, Constant, Local, SwitchTargets, UserTypeProjection};
7 
8 use crate::mir::coverage::{CodeRegion, CoverageKind};
9 use crate::traits::Reveal;
10 use crate::ty::adjustment::PointerCoercion;
11 use crate::ty::subst::SubstsRef;
12 use crate::ty::{self, List, Ty};
13 use crate::ty::{Region, UserTypeAnnotationIndex};
14 
15 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
16 use rustc_hir::def_id::DefId;
17 use rustc_hir::{self as hir};
18 use rustc_hir::{self, GeneratorKind};
19 use rustc_index::IndexVec;
20 use rustc_target::abi::{FieldIdx, VariantIdx};
21 
22 use rustc_ast::Mutability;
23 use rustc_span::def_id::LocalDefId;
24 use rustc_span::symbol::Symbol;
25 use rustc_span::Span;
26 use rustc_target::asm::InlineAsmRegOrRegClass;
27 
28 /// Represents the "flavors" of MIR.
29 ///
30 /// All flavors of MIR use the same data structure, but there are some important differences. These
31 /// differences come in two forms: Dialects and phases.
32 ///
33 /// Dialects represent a stronger distinction than phases. This is because the transitions between
34 /// dialects are semantic changes, and therefore technically *lowerings* between distinct IRs. In
35 /// other words, the same [`Body`](crate::mir::Body) might be well-formed for multiple dialects, but
36 /// have different semantic meaning and different behavior at runtime.
37 ///
38 /// Each dialect additionally has a number of phases. However, phase changes never involve semantic
39 /// changes. If some MIR is well-formed both before and after a phase change, it is also guaranteed
40 /// that it has the same semantic meaning. In this sense, phase changes can only add additional
41 /// restrictions on what MIR is well-formed.
42 ///
43 /// When adding phases, remember to update [`MirPhase::phase_index`].
44 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
45 #[derive(HashStable)]
46 pub enum MirPhase {
47     /// The MIR that is generated by MIR building.
48     ///
49     /// The only things that operate on this dialect are unsafeck, the various MIR lints, and const
50     /// qualifs.
51     ///
52     /// This has no distinct phases.
53     Built,
54     /// The MIR used for most analysis.
55     ///
56     /// The only semantic change between analysis and built MIR is constant promotion. In built MIR,
57     /// sequences of statements that would generally be subject to constant promotion are
58     /// semantically constants, while in analysis MIR all constants are explicit.
59     ///
60     /// The result of const promotion is available from the `mir_promoted` and `promoted_mir` queries.
61     ///
62     /// This is the version of MIR used by borrowck and friends.
63     Analysis(AnalysisPhase),
64     /// The MIR used for CTFE, optimizations, and codegen.
65     ///
66     /// The semantic changes that occur in the lowering from analysis to runtime MIR are as follows:
67     ///
68     ///  - Drops: In analysis MIR, `Drop` terminators represent *conditional* drops; roughly speaking,
69     ///    if dataflow analysis determines that the place being dropped is uninitialized, the drop will
70     ///    not be executed. The exact semantics of this aren't written down anywhere, which means they
71     ///    are essentially "what drop elaboration does." In runtime MIR, the drops are unconditional;
72     ///    when a `Drop` terminator is reached, if the type has drop glue that drop glue is always
73     ///    executed. This may be UB if the underlying place is not initialized.
74     ///  - Packed drops: Places might in general be misaligned - in most cases this is UB, the exception
75     ///    is fields of packed structs. In analysis MIR, `Drop(P)` for a `P` that might be misaligned
76     ///    for this reason implicitly moves `P` to a temporary before dropping. Runtime MIR has no such
77     ///    rules, and dropping a misaligned place is simply UB.
78     ///  - Unwinding: in analysis MIR, unwinding from a function which may not unwind aborts. In runtime
79     ///    MIR, this is UB.
80     ///  - Retags: If `-Zmir-emit-retag` is enabled, analysis MIR has "implicit" retags in the same way
81     ///    that Rust itself has them. Where exactly these are is generally subject to change, and so we
82     ///    don't document this here. Runtime MIR has most retags explicit (though implicit retags
83     ///    can still occur at `Rvalue::{Ref,AddrOf}`).
84     ///  - Generator bodies: In analysis MIR, locals may actually be behind a pointer that user code has
85     ///    access to. This occurs in generator bodies. Such locals do not behave like other locals,
86     ///    because they eg may be aliased in surprising ways. Runtime MIR has no such special locals -
87     ///    all generator bodies are lowered and so all places that look like locals really are locals.
88     ///
89     /// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part
90     /// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that
91     /// transformations which may suppress such errors should not run on analysis MIR.
92     Runtime(RuntimePhase),
93 }
94 
95 impl MirPhase {
name(&self) -> &'static str96     pub fn name(&self) -> &'static str {
97         match *self {
98             MirPhase::Built => "built",
99             MirPhase::Analysis(AnalysisPhase::Initial) => "analysis",
100             MirPhase::Analysis(AnalysisPhase::PostCleanup) => "analysis-post-cleanup",
101             MirPhase::Runtime(RuntimePhase::Initial) => "runtime",
102             MirPhase::Runtime(RuntimePhase::PostCleanup) => "runtime-post-cleanup",
103             MirPhase::Runtime(RuntimePhase::Optimized) => "runtime-optimized",
104         }
105     }
106 
reveal(&self) -> Reveal107     pub fn reveal(&self) -> Reveal {
108         match *self {
109             MirPhase::Built | MirPhase::Analysis(_) => Reveal::UserFacing,
110             MirPhase::Runtime(_) => Reveal::All,
111         }
112     }
113 }
114 
115 /// See [`MirPhase::Analysis`].
116 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
117 #[derive(HashStable)]
118 pub enum AnalysisPhase {
119     Initial = 0,
120     /// Beginning in this phase, the following variants are disallowed:
121     /// * [`TerminatorKind::FalseUnwind`]
122     /// * [`TerminatorKind::FalseEdge`]
123     /// * [`StatementKind::FakeRead`]
124     /// * [`StatementKind::AscribeUserType`]
125     /// * [`Rvalue::Ref`] with `BorrowKind::Shallow`
126     ///
127     /// Furthermore, `Deref` projections must be the first projection within any place (if they
128     /// appear at all)
129     PostCleanup = 1,
130 }
131 
132 /// See [`MirPhase::Runtime`].
133 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
134 #[derive(HashStable)]
135 pub enum RuntimePhase {
136     /// In addition to the semantic changes, beginning with this phase, the following variants are
137     /// disallowed:
138     /// * [`TerminatorKind::Yield`]
139     /// * [`TerminatorKind::GeneratorDrop`]
140     /// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
141     ///
142     /// And the following variants are allowed:
143     /// * [`StatementKind::Retag`]
144     /// * [`StatementKind::SetDiscriminant`]
145     /// * [`StatementKind::Deinit`]
146     ///
147     /// Furthermore, `Copy` operands are allowed for non-`Copy` types.
148     Initial = 0,
149     /// Beginning with this phase, the following variant is disallowed:
150     /// * [`ProjectionElem::Deref`] of `Box`
151     PostCleanup = 1,
152     Optimized = 2,
153 }
154 
155 ///////////////////////////////////////////////////////////////////////////
156 // Borrow kinds
157 
158 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)]
159 #[derive(Hash, HashStable)]
160 pub enum BorrowKind {
161     /// Data must be immutable and is aliasable.
162     Shared,
163 
164     /// The immediately borrowed place must be immutable, but projections from
165     /// it don't need to be. For example, a shallow borrow of `a.b` doesn't
166     /// conflict with a mutable borrow of `a.b.c`.
167     ///
168     /// This is used when lowering matches: when matching on a place we want to
169     /// ensure that place have the same value from the start of the match until
170     /// an arm is selected. This prevents this code from compiling:
171     /// ```compile_fail,E0510
172     /// let mut x = &Some(0);
173     /// match *x {
174     ///     None => (),
175     ///     Some(_) if { x = &None; false } => (),
176     ///     Some(_) => (),
177     /// }
178     /// ```
179     /// This can't be a shared borrow because mutably borrowing (*x as Some).0
180     /// should not prevent `if let None = x { ... }`, for example, because the
181     /// mutating `(*x as Some).0` can't affect the discriminant of `x`.
182     /// We can also report errors with this kind of borrow differently.
183     Shallow,
184 
185     /// Data is mutable and not aliasable.
186     Mut { kind: MutBorrowKind },
187 }
188 
189 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)]
190 #[derive(Hash, HashStable)]
191 pub enum MutBorrowKind {
192     Default,
193     /// This borrow arose from method-call auto-ref. (i.e., `adjustment::Adjust::Borrow`)
194     TwoPhaseBorrow,
195     /// Data must be immutable but not aliasable. This kind of borrow
196     /// cannot currently be expressed by the user and is used only in
197     /// implicit closure bindings. It is needed when the closure is
198     /// borrowing or mutating a mutable referent, e.g.:
199     /// ```
200     /// let mut z = 3;
201     /// let x: &mut isize = &mut z;
202     /// let y = || *x += 5;
203     /// ```
204     /// If we were to try to translate this closure into a more explicit
205     /// form, we'd encounter an error with the code as written:
206     /// ```compile_fail,E0594
207     /// struct Env<'a> { x: &'a &'a mut isize }
208     /// let mut z = 3;
209     /// let x: &mut isize = &mut z;
210     /// let y = (&mut Env { x: &x }, fn_ptr);  // Closure is pair of env and fn
211     /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
212     /// ```
213     /// This is then illegal because you cannot mutate an `&mut` found
214     /// in an aliasable location. To solve, you'd have to translate with
215     /// an `&mut` borrow:
216     /// ```compile_fail,E0596
217     /// struct Env<'a> { x: &'a mut &'a mut isize }
218     /// let mut z = 3;
219     /// let x: &mut isize = &mut z;
220     /// let y = (&mut Env { x: &mut x }, fn_ptr); // changed from &x to &mut x
221     /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
222     /// ```
223     /// Now the assignment to `**env.x` is legal, but creating a
224     /// mutable pointer to `x` is not because `x` is not mutable. We
225     /// could fix this by declaring `x` as `let mut x`. This is ok in
226     /// user code, if awkward, but extra weird for closures, since the
227     /// borrow is hidden.
228     ///
229     /// So we introduce a `ClosureCapture` borrow -- user will not have to mark the variable
230     /// containing the mutable reference as `mut`, as they didn't ever
231     /// intend to mutate the mutable reference itself. We still mutable capture it in order to
232     /// mutate the pointed value through it (but not mutating the reference itself).
233     ///
234     /// This solves the problem. For simplicity, we don't give users the way to express this
235     /// borrow, it's just used when translating closures.
236     ClosureCapture,
237 }
238 
239 ///////////////////////////////////////////////////////////////////////////
240 // Statements
241 
242 /// The various kinds of statements that can appear in MIR.
243 ///
244 /// Not all of these are allowed at every [`MirPhase`]. Check the documentation there to see which
245 /// ones you do not have to worry about. The MIR validator will generally enforce such restrictions,
246 /// causing an ICE if they are violated.
247 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
248 #[derive(TypeFoldable, TypeVisitable)]
249 pub enum StatementKind<'tcx> {
250     /// Assign statements roughly correspond to an assignment in Rust proper (`x = ...`) except
251     /// without the possibility of dropping the previous value (that must be done separately, if at
252     /// all). The *exact* way this works is undecided. It probably does something like evaluating
253     /// the LHS to a place and the RHS to a value, and then storing the value to the place. Various
254     /// parts of this may do type specific things that are more complicated than simply copying
255     /// bytes.
256     ///
257     /// **Needs clarification**: The implication of the above idea would be that assignment implies
258     /// that the resulting value is initialized. I believe we could commit to this separately from
259     /// committing to whatever part of the memory model we would need to decide on to make the above
260     /// paragraph precise. Do we want to?
261     ///
262     /// Assignments in which the types of the place and rvalue differ are not well-formed.
263     ///
264     /// **Needs clarification**: Do we ever want to worry about non-free (in the body) lifetimes for
265     /// the typing requirement in post drop-elaboration MIR? I think probably not - I'm not sure we
266     /// could meaningfully require this anyway. How about free lifetimes? Is ignoring this
267     /// interesting for optimizations? Do we want to allow such optimizations?
268     ///
269     /// **Needs clarification**: We currently require that the LHS place not overlap with any place
270     /// read as part of computation of the RHS for some rvalues (generally those not producing
271     /// primitives). This requirement is under discussion in [#68364]. As a part of this discussion,
272     /// it is also unclear in what order the components are evaluated.
273     ///
274     /// [#68364]: https://github.com/rust-lang/rust/issues/68364
275     ///
276     /// See [`Rvalue`] documentation for details on each of those.
277     Assign(Box<(Place<'tcx>, Rvalue<'tcx>)>),
278 
279     /// This represents all the reading that a pattern match may do (e.g., inspecting constants and
280     /// discriminant values), and the kind of pattern it comes from. This is in order to adapt
281     /// potential error messages to these specific patterns.
282     ///
283     /// Note that this also is emitted for regular `let` bindings to ensure that locals that are
284     /// never accessed still get some sanity checks for, e.g., `let x: ! = ..;`
285     ///
286     /// When executed at runtime this is a nop.
287     ///
288     /// Disallowed after drop elaboration.
289     FakeRead(Box<(FakeReadCause, Place<'tcx>)>),
290 
291     /// Write the discriminant for a variant to the enum Place.
292     ///
293     /// This is permitted for both generators and ADTs. This does not necessarily write to the
294     /// entire place; instead, it writes to the minimum set of bytes as required by the layout for
295     /// the type.
296     SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
297 
298     /// Deinitializes the place.
299     ///
300     /// This writes `uninit` bytes to the entire place.
301     Deinit(Box<Place<'tcx>>),
302 
303     /// `StorageLive` and `StorageDead` statements mark the live range of a local.
304     ///
305     /// At any point during the execution of a function, each local is either allocated or
306     /// unallocated. Except as noted below, all locals except function parameters are initially
307     /// unallocated. `StorageLive` statements cause memory to be allocated for the local while
308     /// `StorageDead` statements cause the memory to be freed. Using a local in any way (not only
309     /// reading/writing from it) while it is unallocated is UB.
310     ///
311     /// Some locals have no `StorageLive` or `StorageDead` statements within the entire MIR body.
312     /// These locals are implicitly allocated for the full duration of the function. There is a
313     /// convenience method at `rustc_mir_dataflow::storage::always_storage_live_locals` for
314     /// computing these locals.
315     ///
316     /// If the local is already allocated, calling `StorageLive` again is UB. However, for an
317     /// unallocated local an additional `StorageDead` all is simply a nop.
318     StorageLive(Local),
319 
320     /// See `StorageLive` above.
321     StorageDead(Local),
322 
323     /// Retag references in the given place, ensuring they got fresh tags.
324     ///
325     /// This is part of the Stacked Borrows model. These statements are currently only interpreted
326     /// by miri and only generated when `-Z mir-emit-retag` is passed. See
327     /// <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/> for
328     /// more details.
329     ///
330     /// For code that is not specific to stacked borrows, you should consider retags to read and
331     /// modify the place in an opaque way.
332     ///
333     /// Only `RetagKind::Default` and `RetagKind::FnEntry` are permitted.
334     Retag(RetagKind, Box<Place<'tcx>>),
335 
336     /// This statement exists to preserve a trace of a scrutinee matched against a wildcard binding.
337     /// This is especially useful for `let _ = PLACE;` bindings that desugar to a single
338     /// `PlaceMention(PLACE)`.
339     ///
340     /// When executed at runtime, this computes the given place, but then discards
341     /// it without doing a load. It is UB if the place is not pointing to live memory.
342     PlaceMention(Box<Place<'tcx>>),
343 
344     /// Encodes a user's type ascription. These need to be preserved
345     /// intact so that NLL can respect them. For example:
346     /// ```ignore (illustrative)
347     /// let a: T = y;
348     /// ```
349     /// The effect of this annotation is to relate the type `T_y` of the place `y`
350     /// to the user-given type `T`. The effect depends on the specified variance:
351     ///
352     /// - `Covariant` -- requires that `T_y <: T`
353     /// - `Contravariant` -- requires that `T_y :> T`
354     /// - `Invariant` -- requires that `T_y == T`
355     /// - `Bivariant` -- no effect
356     ///
357     /// When executed at runtime this is a nop.
358     ///
359     /// Disallowed after drop elaboration.
360     AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance),
361 
362     /// Marks the start of a "coverage region", injected with '-Cinstrument-coverage'. A
363     /// `Coverage` statement carries metadata about the coverage region, used to inject a coverage
364     /// map into the binary. If `Coverage::kind` is a `Counter`, the statement also generates
365     /// executable code, to increment a counter variable at runtime, each time the code region is
366     /// executed.
367     Coverage(Box<Coverage>),
368 
369     /// Denotes a call to an intrinsic that does not require an unwind path and always returns.
370     /// This avoids adding a new block and a terminator for simple intrinsics.
371     Intrinsic(Box<NonDivergingIntrinsic<'tcx>>),
372 
373     /// Instructs the const eval interpreter to increment a counter; this counter is used to track
374     /// how many steps the interpreter has taken. It is used to prevent the user from writing const
375     /// code that runs for too long or infinitely. Other than in the const eval interpreter, this
376     /// is a no-op.
377     ConstEvalCounter,
378 
379     /// No-op. Useful for deleting instructions without affecting statement indices.
380     Nop,
381 }
382 
383 #[derive(
384     Clone,
385     TyEncodable,
386     TyDecodable,
387     Debug,
388     PartialEq,
389     Hash,
390     HashStable,
391     TypeFoldable,
392     TypeVisitable
393 )]
394 pub enum NonDivergingIntrinsic<'tcx> {
395     /// Denotes a call to the intrinsic function `assume`.
396     ///
397     /// The operand must be a boolean. Optimizers may use the value of the boolean to backtrack its
398     /// computation to infer information about other variables. So if the boolean came from a
399     /// `x < y` operation, subsequent operations on `x` and `y` could elide various bound checks.
400     /// If the argument is `false`, this operation is equivalent to `TerminatorKind::Unreachable`.
401     Assume(Operand<'tcx>),
402 
403     /// Denotes a call to the intrinsic function `copy_nonoverlapping`.
404     ///
405     /// First, all three operands are evaluated. `src` and `dest` must each be a reference, pointer,
406     /// or `Box` pointing to the same type `T`. `count` must evaluate to a `usize`. Then, `src` and
407     /// `dest` are dereferenced, and `count * size_of::<T>()` bytes beginning with the first byte of
408     /// the `src` place are copied to the contiguous range of bytes beginning with the first byte
409     /// of `dest`.
410     ///
411     /// **Needs clarification**: In what order are operands computed and dereferenced? It should
412     /// probably match the order for assignment, but that is also undecided.
413     ///
414     /// **Needs clarification**: Is this typed or not, ie is there a typed load and store involved?
415     /// I vaguely remember Ralf saying somewhere that he thought it should not be.
416     CopyNonOverlapping(CopyNonOverlapping<'tcx>),
417 }
418 
419 impl std::fmt::Display for NonDivergingIntrinsic<'_> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result420     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
421         match self {
422             Self::Assume(op) => write!(f, "assume({op:?})"),
423             Self::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => {
424                 write!(f, "copy_nonoverlapping(dst = {dst:?}, src = {src:?}, count = {count:?})")
425             }
426         }
427     }
428 }
429 
430 /// Describes what kind of retag is to be performed.
431 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, Hash, HashStable)]
432 #[rustc_pass_by_value]
433 pub enum RetagKind {
434     /// The initial retag of arguments when entering a function.
435     FnEntry,
436     /// Retag preparing for a two-phase borrow.
437     TwoPhase,
438     /// Retagging raw pointers.
439     Raw,
440     /// A "normal" retag.
441     Default,
442 }
443 
444 /// The `FakeReadCause` describes the type of pattern why a FakeRead statement exists.
445 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, Hash, HashStable, PartialEq)]
446 pub enum FakeReadCause {
447     /// Inject a fake read of the borrowed input at the end of each guards
448     /// code.
449     ///
450     /// This should ensure that you cannot change the variant for an enum while
451     /// you are in the midst of matching on it.
452     ForMatchGuard,
453 
454     /// `let x: !; match x {}` doesn't generate any read of x so we need to
455     /// generate a read of x to check that it is initialized and safe.
456     ///
457     /// If a closure pattern matches a Place starting with an Upvar, then we introduce a
458     /// FakeRead for that Place outside the closure, in such a case this option would be
459     /// Some(closure_def_id).
460     /// Otherwise, the value of the optional LocalDefId will be None.
461     //
462     // We can use LocalDefId here since fake read statements are removed
463     // before codegen in the `CleanupNonCodegenStatements` pass.
464     ForMatchedPlace(Option<LocalDefId>),
465 
466     /// A fake read of the RefWithinGuard version of a bind-by-value variable
467     /// in a match guard to ensure that its value hasn't change by the time
468     /// we create the OutsideGuard version.
469     ForGuardBinding,
470 
471     /// Officially, the semantics of
472     ///
473     /// `let pattern = <expr>;`
474     ///
475     /// is that `<expr>` is evaluated into a temporary and then this temporary is
476     /// into the pattern.
477     ///
478     /// However, if we see the simple pattern `let var = <expr>`, we optimize this to
479     /// evaluate `<expr>` directly into the variable `var`. This is mostly unobservable,
480     /// but in some cases it can affect the borrow checker, as in #53695.
481     /// Therefore, we insert a "fake read" here to ensure that we get
482     /// appropriate errors.
483     ///
484     /// If a closure pattern matches a Place starting with an Upvar, then we introduce a
485     /// FakeRead for that Place outside the closure, in such a case this option would be
486     /// Some(closure_def_id).
487     /// Otherwise, the value of the optional DefId will be None.
488     ForLet(Option<LocalDefId>),
489 
490     /// If we have an index expression like
491     ///
492     /// (*x)[1][{ x = y; 4}]
493     ///
494     /// then the first bounds check is invalidated when we evaluate the second
495     /// index expression. Thus we create a fake borrow of `x` across the second
496     /// indexer, which will cause a borrow check error.
497     ForIndex,
498 }
499 
500 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
501 #[derive(TypeFoldable, TypeVisitable)]
502 pub struct Coverage {
503     pub kind: CoverageKind,
504     pub code_region: Option<CodeRegion>,
505 }
506 
507 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
508 #[derive(TypeFoldable, TypeVisitable)]
509 pub struct CopyNonOverlapping<'tcx> {
510     pub src: Operand<'tcx>,
511     pub dst: Operand<'tcx>,
512     /// Number of elements to copy from src to dest, not bytes.
513     pub count: Operand<'tcx>,
514 }
515 
516 /// Represents how a `TerminatorKind::Call` was constructed, used for diagnostics
517 #[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, Hash, HashStable)]
518 #[derive(TypeFoldable, TypeVisitable)]
519 pub enum CallSource {
520     /// This came from something such as `a > b` or `a + b`. In THIR, if `from_hir_call`
521     /// is false then this is the desugaring.
522     OverloadedOperator,
523     /// This was from comparison generated by a match, used by const-eval for better errors
524     /// when the comparison cannot be done in compile time.
525     ///
526     /// (see <https://github.com/rust-lang/rust/issues/90237>)
527     MatchCmp,
528     /// Other types of desugaring that did not come from the HIR, but we don't care about
529     /// for diagnostics (yet).
530     Misc,
531     /// Normal function call, no special source
532     Normal,
533 }
534 
535 impl CallSource {
from_hir_call(self) -> bool536     pub fn from_hir_call(self) -> bool {
537         matches!(self, CallSource::Normal)
538     }
539 }
540 
541 ///////////////////////////////////////////////////////////////////////////
542 // Terminators
543 
544 /// The various kinds of terminators, representing ways of exiting from a basic block.
545 ///
546 /// A note on unwinding: Panics may occur during the execution of some terminators. Depending on the
547 /// `-C panic` flag, this may either cause the program to abort or the call stack to unwind. Such
548 /// terminators have a `unwind: UnwindAction` field on them. If stack unwinding occurs, then
549 /// once the current function is reached, an action will be taken based on the `unwind` field.
550 /// If the action is `Cleanup`, then the execution continues at the given basic block. If the
551 /// action is `Continue` then no cleanup is performed, and the stack continues unwinding.
552 ///
553 /// The basic block pointed to by a `Cleanup` unwind action must have its `cleanup` flag set.
554 /// `cleanup` basic blocks have a couple restrictions:
555 ///  1. All `unwind` fields in them must be `UnwindAction::Terminate` or `UnwindAction::Unreachable`.
556 ///  2. `Return` terminators are not allowed in them. `Terminate` and `Resume` terminators are.
557 ///  3. All other basic blocks (in the current body) that are reachable from `cleanup` basic blocks
558 ///     must also be `cleanup`. This is a part of the type system and checked statically, so it is
559 ///     still an error to have such an edge in the CFG even if it's known that it won't be taken at
560 ///     runtime.
561 ///  4. The control flow between cleanup blocks must look like an upside down tree. Roughly
562 ///     speaking, this means that control flow that looks like a V is allowed, while control flow
563 ///     that looks like a W is not. This is necessary to ensure that landing pad information can be
564 ///     correctly codegened on MSVC. More precisely:
565 ///
566 ///     Begin with the standard control flow graph `G`. Modify `G` as follows: for any two cleanup
567 ///     vertices `u` and `v` such that `u` dominates `v`, contract `u` and `v` into a single vertex,
568 ///     deleting self edges and duplicate edges in the process. Now remove all vertices from `G`
569 ///     that are not cleanup vertices or are not reachable. The resulting graph must be an inverted
570 ///     tree, that is each vertex may have at most one successor and there may be no cycles.
571 #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
572 pub enum TerminatorKind<'tcx> {
573     /// Block has one successor; we continue execution there.
574     Goto { target: BasicBlock },
575 
576     /// Switches based on the computed value.
577     ///
578     /// First, evaluates the `discr` operand. The type of the operand must be a signed or unsigned
579     /// integer, char, or bool, and must match the given type. Then, if the list of switch targets
580     /// contains the computed value, continues execution at the associated basic block. Otherwise,
581     /// continues execution at the "otherwise" basic block.
582     ///
583     /// Target values may not appear more than once.
584     SwitchInt {
585         /// The discriminant value being tested.
586         discr: Operand<'tcx>,
587         targets: SwitchTargets,
588     },
589 
590     /// Indicates that the landing pad is finished and that the process should continue unwinding.
591     ///
592     /// Like a return, this marks the end of this invocation of the function.
593     ///
594     /// Only permitted in cleanup blocks. `Resume` is not permitted with `-C unwind=abort` after
595     /// deaggregation runs.
596     Resume,
597 
598     /// Indicates that the landing pad is finished and that the process should terminate.
599     ///
600     /// Used to prevent unwinding for foreign items or with `-C unwind=abort`. Only permitted in
601     /// cleanup blocks.
602     Terminate,
603 
604     /// Returns from the function.
605     ///
606     /// Like function calls, the exact semantics of returns in Rust are unclear. Returning very
607     /// likely at least assigns the value currently in the return place (`_0`) to the place
608     /// specified in the associated `Call` terminator in the calling function, as if assigned via
609     /// `dest = move _0`. It might additionally do other things, like have side-effects in the
610     /// aliasing model.
611     ///
612     /// If the body is a generator body, this has slightly different semantics; it instead causes a
613     /// `GeneratorState::Returned(_0)` to be created (as if by an `Aggregate` rvalue) and assigned
614     /// to the return place.
615     Return,
616 
617     /// Indicates a terminator that can never be reached.
618     ///
619     /// Executing this terminator is UB.
620     Unreachable,
621 
622     /// The behavior of this statement differs significantly before and after drop elaboration.
623     ///
624     /// After drop elaboration: `Drop` terminators are a complete nop for types that have no drop
625     /// glue. For other types, `Drop` terminators behave exactly like a call to
626     /// `core::mem::drop_in_place` with a pointer to the given place.
627     ///
628     /// `Drop` before drop elaboration is a *conditional* execution of the drop glue. Specifically,
629     /// the `Drop` will be executed if...
630     ///
631     /// **Needs clarification**: End of that sentence. This in effect should document the exact
632     /// behavior of drop elaboration. The following sounds vaguely right, but I'm not quite sure:
633     ///
634     /// > The drop glue is executed if, among all statements executed within this `Body`, an assignment to
635     /// > the place or one of its "parents" occurred more recently than a move out of it. This does not
636     /// > consider indirect assignments.
637     ///
638     /// The `replace` flag indicates whether this terminator was created as part of an assignment.
639     /// This should only be used for diagnostic purposes, and does not have any operational
640     /// meaning.
641     Drop { place: Place<'tcx>, target: BasicBlock, unwind: UnwindAction, replace: bool },
642 
643     /// Roughly speaking, evaluates the `func` operand and the arguments, and starts execution of
644     /// the referred to function. The operand types must match the argument types of the function.
645     /// The return place type must match the return type. The type of the `func` operand must be
646     /// callable, meaning either a function pointer, a function type, or a closure type.
647     ///
648     /// **Needs clarification**: The exact semantics of this. Current backends rely on `move`
649     /// operands not aliasing the return place. It is unclear how this is justified in MIR, see
650     /// [#71117].
651     ///
652     /// [#71117]: https://github.com/rust-lang/rust/issues/71117
653     Call {
654         /// The function that’s being called.
655         func: Operand<'tcx>,
656         /// Arguments the function is called with.
657         /// These are owned by the callee, which is free to modify them.
658         /// This allows the memory occupied by "by-value" arguments to be
659         /// reused across function calls without duplicating the contents.
660         args: Vec<Operand<'tcx>>,
661         /// Where the returned value will be written
662         destination: Place<'tcx>,
663         /// Where to go after this call returns. If none, the call necessarily diverges.
664         target: Option<BasicBlock>,
665         /// Action to be taken if the call unwinds.
666         unwind: UnwindAction,
667         /// Where this call came from in HIR/THIR.
668         call_source: CallSource,
669         /// This `Span` is the span of the function, without the dot and receiver
670         /// e.g. `foo(a, b)` in `x.foo(a, b)`
671         fn_span: Span,
672     },
673 
674     /// Evaluates the operand, which must have type `bool`. If it is not equal to `expected`,
675     /// initiates a panic. Initiating a panic corresponds to a `Call` terminator with some
676     /// unspecified constant as the function to call, all the operands stored in the `AssertMessage`
677     /// as parameters, and `None` for the destination. Keep in mind that the `cleanup` path is not
678     /// necessarily executed even in the case of a panic, for example in `-C panic=abort`. If the
679     /// assertion does not fail, execution continues at the specified basic block.
680     ///
681     /// When overflow checking is disabled and this is run-time MIR (as opposed to compile-time MIR
682     /// that is used for CTFE), the following variants of this terminator behave as `goto target`:
683     /// - `OverflowNeg(..)`,
684     /// - `Overflow(op, ..)` if op is add, sub, mul, shl, shr, but NOT div or rem.
685     Assert {
686         cond: Operand<'tcx>,
687         expected: bool,
688         msg: Box<AssertMessage<'tcx>>,
689         target: BasicBlock,
690         unwind: UnwindAction,
691     },
692 
693     /// Marks a suspend point.
694     ///
695     /// Like `Return` terminators in generator bodies, this computes `value` and then a
696     /// `GeneratorState::Yielded(value)` as if by `Aggregate` rvalue. That value is then assigned to
697     /// the return place of the function calling this one, and execution continues in the calling
698     /// function. When next invoked with the same first argument, execution of this function
699     /// continues at the `resume` basic block, with the second argument written to the `resume_arg`
700     /// place. If the generator is dropped before then, the `drop` basic block is invoked.
701     ///
702     /// Not permitted in bodies that are not generator bodies, or after generator lowering.
703     ///
704     /// **Needs clarification**: What about the evaluation order of the `resume_arg` and `value`?
705     Yield {
706         /// The value to return.
707         value: Operand<'tcx>,
708         /// Where to resume to.
709         resume: BasicBlock,
710         /// The place to store the resume argument in.
711         resume_arg: Place<'tcx>,
712         /// Cleanup to be done if the generator is dropped at this suspend point.
713         drop: Option<BasicBlock>,
714     },
715 
716     /// Indicates the end of dropping a generator.
717     ///
718     /// Semantically just a `return` (from the generators drop glue). Only permitted in the same situations
719     /// as `yield`.
720     ///
721     /// **Needs clarification**: Is that even correct? The generator drop code is always confusing
722     /// to me, because it's not even really in the current body.
723     ///
724     /// **Needs clarification**: Are there type system constraints on these terminators? Should
725     /// there be a "block type" like `cleanup` blocks for them?
726     GeneratorDrop,
727 
728     /// A block where control flow only ever takes one real path, but borrowck needs to be more
729     /// conservative.
730     ///
731     /// At runtime this is semantically just a goto.
732     ///
733     /// Disallowed after drop elaboration.
734     FalseEdge {
735         /// The target normal control flow will take.
736         real_target: BasicBlock,
737         /// A block control flow could conceptually jump to, but won't in
738         /// practice.
739         imaginary_target: BasicBlock,
740     },
741 
742     /// A terminator for blocks that only take one path in reality, but where we reserve the right
743     /// to unwind in borrowck, even if it won't happen in practice. This can arise in infinite loops
744     /// with no function calls for example.
745     ///
746     /// At runtime this is semantically just a goto.
747     ///
748     /// Disallowed after drop elaboration.
749     FalseUnwind {
750         /// The target normal control flow will take.
751         real_target: BasicBlock,
752         /// The imaginary cleanup block link. This particular path will never be taken
753         /// in practice, but in order to avoid fragility we want to always
754         /// consider it in borrowck. We don't want to accept programs which
755         /// pass borrowck only when `panic=abort` or some assertions are disabled
756         /// due to release vs. debug mode builds.
757         unwind: UnwindAction,
758     },
759 
760     /// Block ends with an inline assembly block. This is a terminator since
761     /// inline assembly is allowed to diverge.
762     InlineAsm {
763         /// The template for the inline assembly, with placeholders.
764         template: &'tcx [InlineAsmTemplatePiece],
765 
766         /// The operands for the inline assembly, as `Operand`s or `Place`s.
767         operands: Vec<InlineAsmOperand<'tcx>>,
768 
769         /// Miscellaneous options for the inline assembly.
770         options: InlineAsmOptions,
771 
772         /// Source spans for each line of the inline assembly code. These are
773         /// used to map assembler errors back to the line in the source code.
774         line_spans: &'tcx [Span],
775 
776         /// Destination block after the inline assembly returns, unless it is
777         /// diverging (InlineAsmOptions::NORETURN).
778         destination: Option<BasicBlock>,
779 
780         /// Action to be taken if the inline assembly unwinds. This is present
781         /// if and only if InlineAsmOptions::MAY_UNWIND is set.
782         unwind: UnwindAction,
783     },
784 }
785 
786 impl TerminatorKind<'_> {
787     /// Returns a simple string representation of a `TerminatorKind` variant, independent of any
788     /// values it might hold (e.g. `TerminatorKind::Call` always returns `"Call"`).
name(&self) -> &'static str789     pub const fn name(&self) -> &'static str {
790         match self {
791             TerminatorKind::Goto { .. } => "Goto",
792             TerminatorKind::SwitchInt { .. } => "SwitchInt",
793             TerminatorKind::Resume => "Resume",
794             TerminatorKind::Terminate => "Terminate",
795             TerminatorKind::Return => "Return",
796             TerminatorKind::Unreachable => "Unreachable",
797             TerminatorKind::Drop { .. } => "Drop",
798             TerminatorKind::Call { .. } => "Call",
799             TerminatorKind::Assert { .. } => "Assert",
800             TerminatorKind::Yield { .. } => "Yield",
801             TerminatorKind::GeneratorDrop => "GeneratorDrop",
802             TerminatorKind::FalseEdge { .. } => "FalseEdge",
803             TerminatorKind::FalseUnwind { .. } => "FalseUnwind",
804             TerminatorKind::InlineAsm { .. } => "InlineAsm",
805         }
806     }
807 }
808 
809 /// Action to be taken when a stack unwind happens.
810 #[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
811 #[derive(TypeFoldable, TypeVisitable)]
812 pub enum UnwindAction {
813     /// No action is to be taken. Continue unwinding.
814     ///
815     /// This is similar to `Cleanup(bb)` where `bb` does nothing but `Resume`, but they are not
816     /// equivalent, as presence of `Cleanup(_)` will make a frame non-POF.
817     Continue,
818     /// Triggers undefined behavior if unwind happens.
819     Unreachable,
820     /// Terminates the execution if unwind happens.
821     ///
822     /// Depending on the platform and situation this may cause a non-unwindable panic or abort.
823     Terminate,
824     /// Cleanups to be done.
825     Cleanup(BasicBlock),
826 }
827 
828 /// Information about an assertion failure.
829 #[derive(Clone, Hash, HashStable, PartialEq, Debug)]
830 #[derive(TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)]
831 pub enum AssertKind<O> {
832     BoundsCheck { len: O, index: O },
833     Overflow(BinOp, O, O),
834     OverflowNeg(O),
835     DivisionByZero(O),
836     RemainderByZero(O),
837     ResumedAfterReturn(GeneratorKind),
838     ResumedAfterPanic(GeneratorKind),
839     MisalignedPointerDereference { required: O, found: O },
840 }
841 
842 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
843 #[derive(TypeFoldable, TypeVisitable)]
844 pub enum InlineAsmOperand<'tcx> {
845     In {
846         reg: InlineAsmRegOrRegClass,
847         value: Operand<'tcx>,
848     },
849     Out {
850         reg: InlineAsmRegOrRegClass,
851         late: bool,
852         place: Option<Place<'tcx>>,
853     },
854     InOut {
855         reg: InlineAsmRegOrRegClass,
856         late: bool,
857         in_value: Operand<'tcx>,
858         out_place: Option<Place<'tcx>>,
859     },
860     Const {
861         value: Box<Constant<'tcx>>,
862     },
863     SymFn {
864         value: Box<Constant<'tcx>>,
865     },
866     SymStatic {
867         def_id: DefId,
868     },
869 }
870 
871 /// Type for MIR `Assert` terminator error messages.
872 pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
873 
874 ///////////////////////////////////////////////////////////////////////////
875 // Places
876 
877 /// Places roughly correspond to a "location in memory." Places in MIR are the same mathematical
878 /// object as places in Rust. This of course means that what exactly they are is undecided and part
879 /// of the Rust memory model. However, they will likely contain at least the following pieces of
880 /// information in some form:
881 ///
882 ///  1. The address in memory that the place refers to.
883 ///  2. The provenance with which the place is being accessed.
884 ///  3. The type of the place and an optional variant index. See [`PlaceTy`][super::tcx::PlaceTy].
885 ///  4. Optionally, some metadata. This exists if and only if the type of the place is not `Sized`.
886 ///
887 /// We'll give a description below of how all pieces of the place except for the provenance are
888 /// calculated. We cannot give a description of the provenance, because that is part of the
889 /// undecided aliasing model - we only include it here at all to acknowledge its existence.
890 ///
891 /// Each local naturally corresponds to the place `Place { local, projection: [] }`. This place has
892 /// the address of the local's allocation and the type of the local.
893 ///
894 /// **Needs clarification:** Unsized locals seem to present a bit of an issue. Their allocation
895 /// can't actually be created on `StorageLive`, because it's unclear how big to make the allocation.
896 /// Furthermore, MIR produces assignments to unsized locals, although that is not permitted under
897 /// `#![feature(unsized_locals)]` in Rust. Besides just putting "unsized locals are special and
898 /// different" in a bunch of places, I (JakobDegen) don't know how to incorporate this behavior into
899 /// the current MIR semantics in a clean way - possibly this needs some design work first.
900 ///
901 /// For places that are not locals, ie they have a non-empty list of projections, we define the
902 /// values as a function of the parent place, that is the place with its last [`ProjectionElem`]
903 /// stripped. The way this is computed of course depends on the kind of that last projection
904 /// element:
905 ///
906 ///  - [`Downcast`](ProjectionElem::Downcast): This projection sets the place's variant index to the
907 ///    given one, and makes no other changes. A `Downcast` projection on a place with its variant
908 ///    index already set is not well-formed.
909 ///  - [`Field`](ProjectionElem::Field): `Field` projections take their parent place and create a
910 ///    place referring to one of the fields of the type. The resulting address is the parent
911 ///    address, plus the offset of the field. The type becomes the type of the field. If the parent
912 ///    was unsized and so had metadata associated with it, then the metadata is retained if the
913 ///    field is unsized and thrown out if it is sized.
914 ///
915 ///    These projections are only legal for tuples, ADTs, closures, and generators. If the ADT or
916 ///    generator has more than one variant, the parent place's variant index must be set, indicating
917 ///    which variant is being used. If it has just one variant, the variant index may or may not be
918 ///    included - the single possible variant is inferred if it is not included.
919 ///  - [`OpaqueCast`](ProjectionElem::OpaqueCast): This projection changes the place's type to the
920 ///    given one, and makes no other changes. A `OpaqueCast` projection on any type other than an
921 ///    opaque type from the current crate is not well-formed.
922 ///  - [`ConstantIndex`](ProjectionElem::ConstantIndex): Computes an offset in units of `T` into the
923 ///    place as described in the documentation for the `ProjectionElem`. The resulting address is
924 ///    the parent's address plus that offset, and the type is `T`. This is only legal if the parent
925 ///    place has type `[T;  N]` or `[T]` (*not* `&[T]`). Since such a `T` is always sized, any
926 ///    resulting metadata is thrown out.
927 ///  - [`Subslice`](ProjectionElem::Subslice): This projection calculates an offset and a new
928 ///    address in a similar manner as `ConstantIndex`. It is also only legal on `[T; N]` and `[T]`.
929 ///    However, this yields a `Place` of type `[T]`, and additionally sets the metadata to be the
930 ///    length of the subslice.
931 ///  - [`Index`](ProjectionElem::Index): Like `ConstantIndex`, only legal on `[T; N]` or `[T]`.
932 ///    However, `Index` additionally takes a local from which the value of the index is computed at
933 ///    runtime. Computing the value of the index involves interpreting the `Local` as a
934 ///    `Place { local, projection: [] }`, and then computing its value as if done via
935 ///    [`Operand::Copy`]. The array/slice is then indexed with the resulting value. The local must
936 ///    have type `usize`.
937 ///  - [`Deref`](ProjectionElem::Deref): Derefs are the last type of projection, and the most
938 ///    complicated. They are only legal on parent places that are references, pointers, or `Box`. A
939 ///    `Deref` projection begins by loading a value from the parent place, as if by
940 ///    [`Operand::Copy`]. It then dereferences the resulting pointer, creating a place of the
941 ///    pointee's type. The resulting address is the address that was stored in the pointer. If the
942 ///    pointee type is unsized, the pointer additionally stored the value of the metadata.
943 ///
944 /// Computing a place may cause UB. One possibility is that the pointer used for a `Deref` may not
945 /// be suitably aligned. Another possibility is that the place is not in bounds, meaning it does not
946 /// point to an actual allocation.
947 ///
948 /// However, if this is actually UB and when the UB kicks in is undecided. This is being discussed
949 /// in [UCG#319]. The options include that every place must obey those rules, that only some places
950 /// must obey them, or that places impose no rules of their own.
951 ///
952 /// [UCG#319]: https://github.com/rust-lang/unsafe-code-guidelines/issues/319
953 ///
954 /// Rust currently requires that every place obey those two rules. This is checked by MIRI and taken
955 /// advantage of by codegen (via `gep inbounds`). That is possibly subject to change.
956 #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable, TypeFoldable, TypeVisitable)]
957 pub struct Place<'tcx> {
958     pub local: Local,
959 
960     /// projection out of a place (access a field, deref a pointer, etc)
961     pub projection: &'tcx List<PlaceElem<'tcx>>,
962 }
963 
964 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
965 #[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
966 pub enum ProjectionElem<V, T> {
967     Deref,
968 
969     /// A field (e.g., `f` in `_1.f`) is one variant of [`ProjectionElem`]. Conceptually,
970     /// rustc can identify that a field projection refers to either two different regions of memory
971     /// or the same one between the base and the 'projection element'.
972     /// Read more about projections in the [rustc-dev-guide][mir-datatypes]
973     ///
974     /// [mir-datatypes]: https://rustc-dev-guide.rust-lang.org/mir/index.html#mir-data-types
975     Field(FieldIdx, T),
976 
977     /// Index into a slice/array.
978     ///
979     /// Note that this does not also dereference, and so it does not exactly correspond to slice
980     /// indexing in Rust. In other words, in the below Rust code:
981     ///
982     /// ```rust
983     /// let x = &[1, 2, 3, 4];
984     /// let i = 2;
985     /// x[i];
986     /// ```
987     ///
988     /// The `x[i]` is turned into a `Deref` followed by an `Index`, not just an `Index`. The same
989     /// thing is true of the `ConstantIndex` and `Subslice` projections below.
990     Index(V),
991 
992     /// These indices are generated by slice patterns. Easiest to explain
993     /// by example:
994     ///
995     /// ```ignore (illustrative)
996     /// [X, _, .._, _, _] => { offset: 0, min_length: 4, from_end: false },
997     /// [_, X, .._, _, _] => { offset: 1, min_length: 4, from_end: false },
998     /// [_, _, .._, X, _] => { offset: 2, min_length: 4, from_end: true },
999     /// [_, _, .._, _, X] => { offset: 1, min_length: 4, from_end: true },
1000     /// ```
1001     ConstantIndex {
1002         /// index or -index (in Python terms), depending on from_end
1003         offset: u64,
1004         /// The thing being indexed must be at least this long. For arrays this
1005         /// is always the exact length.
1006         min_length: u64,
1007         /// Counting backwards from end? This is always false when indexing an
1008         /// array.
1009         from_end: bool,
1010     },
1011 
1012     /// These indices are generated by slice patterns.
1013     ///
1014     /// If `from_end` is true `slice[from..slice.len() - to]`.
1015     /// Otherwise `array[from..to]`.
1016     Subslice {
1017         from: u64,
1018         to: u64,
1019         /// Whether `to` counts from the start or end of the array/slice.
1020         /// For `PlaceElem`s this is `true` if and only if the base is a slice.
1021         /// For `ProjectionKind`, this can also be `true` for arrays.
1022         from_end: bool,
1023     },
1024 
1025     /// "Downcast" to a variant of an enum or a generator.
1026     ///
1027     /// The included Symbol is the name of the variant, used for printing MIR.
1028     Downcast(Option<Symbol>, VariantIdx),
1029 
1030     /// Like an explicit cast from an opaque type to a concrete type, but without
1031     /// requiring an intermediate variable.
1032     OpaqueCast(T),
1033 }
1034 
1035 /// Alias for projections as they appear in places, where the base is a place
1036 /// and the index is a local.
1037 pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
1038 
1039 ///////////////////////////////////////////////////////////////////////////
1040 // Operands
1041 
1042 /// An operand in MIR represents a "value" in Rust, the definition of which is undecided and part of
1043 /// the memory model. One proposal for a definition of values can be found [on UCG][value-def].
1044 ///
1045 /// [value-def]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/value-domain.md
1046 ///
1047 /// The most common way to create values is via loading a place. Loading a place is an operation
1048 /// which reads the memory of the place and converts it to a value. This is a fundamentally *typed*
1049 /// operation. The nature of the value produced depends on the type of the conversion. Furthermore,
1050 /// there may be other effects: if the type has a validity constraint loading the place might be UB
1051 /// if the validity constraint is not met.
1052 ///
1053 /// **Needs clarification:** Ralf proposes that loading a place not have side-effects.
1054 /// This is what is implemented in miri today. Are these the semantics we want for MIR? Is this
1055 /// something we can even decide without knowing more about Rust's memory model?
1056 ///
1057 /// **Needs clarification:** Is loading a place that has its variant index set well-formed? Miri
1058 /// currently implements it, but it seems like this may be something to check against in the
1059 /// validator.
1060 #[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
1061 pub enum Operand<'tcx> {
1062     /// Creates a value by loading the given place.
1063     ///
1064     /// Before drop elaboration, the type of the place must be `Copy`. After drop elaboration there
1065     /// is no such requirement.
1066     Copy(Place<'tcx>),
1067 
1068     /// Creates a value by performing loading the place, just like the `Copy` operand.
1069     ///
1070     /// This *may* additionally overwrite the place with `uninit` bytes, depending on how we decide
1071     /// in [UCG#188]. You should not emit MIR that may attempt a subsequent second load of this
1072     /// place without first re-initializing it.
1073     ///
1074     /// [UCG#188]: https://github.com/rust-lang/unsafe-code-guidelines/issues/188
1075     Move(Place<'tcx>),
1076 
1077     /// Constants are already semantically values, and remain unchanged.
1078     Constant(Box<Constant<'tcx>>),
1079 }
1080 
1081 ///////////////////////////////////////////////////////////////////////////
1082 // Rvalues
1083 
1084 /// The various kinds of rvalues that can appear in MIR.
1085 ///
1086 /// Not all of these are allowed at every [`MirPhase`] - when this is the case, it's stated below.
1087 ///
1088 /// Computing any rvalue begins by evaluating the places and operands in some order (**Needs
1089 /// clarification**: Which order?). These are then used to produce a "value" - the same kind of
1090 /// value that an [`Operand`] produces.
1091 #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)]
1092 pub enum Rvalue<'tcx> {
1093     /// Yields the operand unchanged
1094     Use(Operand<'tcx>),
1095 
1096     /// Creates an array where each element is the value of the operand.
1097     ///
1098     /// This is the cause of a bug in the case where the repetition count is zero because the value
1099     /// is not dropped, see [#74836].
1100     ///
1101     /// Corresponds to source code like `[x; 32]`.
1102     ///
1103     /// [#74836]: https://github.com/rust-lang/rust/issues/74836
1104     Repeat(Operand<'tcx>, ty::Const<'tcx>),
1105 
1106     /// Creates a reference of the indicated kind to the place.
1107     ///
1108     /// There is not much to document here, because besides the obvious parts the semantics of this
1109     /// are essentially entirely a part of the aliasing model. There are many UCG issues discussing
1110     /// exactly what the behavior of this operation should be.
1111     ///
1112     /// `Shallow` borrows are disallowed after drop lowering.
1113     Ref(Region<'tcx>, BorrowKind, Place<'tcx>),
1114 
1115     /// Creates a pointer/reference to the given thread local.
1116     ///
1117     /// The yielded type is a `*mut T` if the static is mutable, otherwise if the static is extern a
1118     /// `*const T`, and if neither of those apply a `&T`.
1119     ///
1120     /// **Note:** This is a runtime operation that actually executes code and is in this sense more
1121     /// like a function call. Also, eliminating dead stores of this rvalue causes `fn main() {}` to
1122     /// SIGILL for some reason that I (JakobDegen) never got a chance to look into.
1123     ///
1124     /// **Needs clarification**: Are there weird additional semantics here related to the runtime
1125     /// nature of this operation?
1126     ThreadLocalRef(DefId),
1127 
1128     /// Creates a pointer with the indicated mutability to the place.
1129     ///
1130     /// This is generated by pointer casts like `&v as *const _` or raw address of expressions like
1131     /// `&raw v` or `addr_of!(v)`.
1132     ///
1133     /// Like with references, the semantics of this operation are heavily dependent on the aliasing
1134     /// model.
1135     AddressOf(Mutability, Place<'tcx>),
1136 
1137     /// Yields the length of the place, as a `usize`.
1138     ///
1139     /// If the type of the place is an array, this is the array length. For slices (`[T]`, not
1140     /// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is
1141     /// ill-formed for places of other types.
1142     Len(Place<'tcx>),
1143 
1144     /// Performs essentially all of the casts that can be performed via `as`.
1145     ///
1146     /// This allows for casts from/to a variety of types.
1147     ///
1148     /// **FIXME**: Document exactly which `CastKind`s allow which types of casts. Figure out why
1149     /// `ArrayToPointer` and `MutToConstPointer` are special.
1150     Cast(CastKind, Operand<'tcx>, Ty<'tcx>),
1151 
1152     /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
1153     ///   parameter may be a `usize` as well.
1154     /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
1155     ///   raw pointers, or function pointers and return a `bool`. The types of the operands must be
1156     ///   matching, up to the usual caveat of the lifetimes in function pointers.
1157     /// * Left and right shift operations accept signed or unsigned integers not necessarily of the
1158     ///   same type and return a value of the same type as their LHS. Like in Rust, the RHS is
1159     ///   truncated as needed.
1160     /// * The `Bit*` operations accept signed integers, unsigned integers, or bools with matching
1161     ///   types and return a value of that type.
1162     /// * The remaining operations accept signed integers, unsigned integers, or floats with
1163     ///   matching types and return a value of that type.
1164     BinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
1165 
1166     /// Same as `BinaryOp`, but yields `(T, bool)` with a `bool` indicating an error condition.
1167     ///
1168     /// For addition, subtraction, and multiplication on integers the error condition is set when
1169     /// the infinite precision result would not be equal to the actual result.
1170     ///
1171     /// Other combinations of types and operators are unsupported.
1172     CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
1173 
1174     /// Computes a value as described by the operation.
1175     NullaryOp(NullOp<'tcx>, Ty<'tcx>),
1176 
1177     /// Exactly like `BinaryOp`, but less operands.
1178     ///
1179     /// Also does two's-complement arithmetic. Negation requires a signed integer or a float;
1180     /// bitwise not requires a signed integer, unsigned integer, or bool. Both operation kinds
1181     /// return a value with the same type as their operand.
1182     UnaryOp(UnOp, Operand<'tcx>),
1183 
1184     /// Computes the discriminant of the place, returning it as an integer of type
1185     /// [`discriminant_ty`]. Returns zero for types without discriminant.
1186     ///
1187     /// The validity requirements for the underlying value are undecided for this rvalue, see
1188     /// [#91095]. Note too that the value of the discriminant is not the same thing as the
1189     /// variant index; use [`discriminant_for_variant`] to convert.
1190     ///
1191     /// [`discriminant_ty`]: crate::ty::Ty::discriminant_ty
1192     /// [#91095]: https://github.com/rust-lang/rust/issues/91095
1193     /// [`discriminant_for_variant`]: crate::ty::Ty::discriminant_for_variant
1194     Discriminant(Place<'tcx>),
1195 
1196     /// Creates an aggregate value, like a tuple or struct.
1197     ///
1198     /// This is needed because dataflow analysis needs to distinguish
1199     /// `dest = Foo { x: ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case that `Foo`
1200     /// has a destructor.
1201     ///
1202     /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
1203     /// generator lowering, `Generator` aggregate kinds are disallowed too.
1204     Aggregate(Box<AggregateKind<'tcx>>, IndexVec<FieldIdx, Operand<'tcx>>),
1205 
1206     /// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
1207     ///
1208     /// This is different from a normal transmute because dataflow analysis will treat the box as
1209     /// initialized but its content as uninitialized. Like other pointer casts, this in general
1210     /// affects alias analysis.
1211     ShallowInitBox(Operand<'tcx>, Ty<'tcx>),
1212 
1213     /// A CopyForDeref is equivalent to a read from a place at the
1214     /// codegen level, but is treated specially by drop elaboration. When such a read happens, it
1215     /// is guaranteed (via nature of the mir_opt `Derefer` in rustc_mir_transform/src/deref_separator)
1216     /// that the only use of the returned value is a deref operation, immediately
1217     /// followed by one or more projections. Drop elaboration treats this rvalue as if the
1218     /// read never happened and just projects further. This allows simplifying various MIR
1219     /// optimizations and codegen backends that previously had to handle deref operations anywhere
1220     /// in a place.
1221     CopyForDeref(Place<'tcx>),
1222 }
1223 
1224 #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
1225 pub enum CastKind {
1226     /// An exposing pointer to address cast. A cast between a pointer and an integer type, or
1227     /// between a function pointer and an integer type.
1228     /// See the docs on `expose_addr` for more details.
1229     PointerExposeAddress,
1230     /// An address-to-pointer cast that picks up an exposed provenance.
1231     /// See the docs on `from_exposed_addr` for more details.
1232     PointerFromExposedAddress,
1233     /// Pointer related casts that are done by coercions. Note that reference-to-raw-ptr casts are
1234     /// translated into `&raw mut/const *r`, i.e., they are not actually casts.
1235     PointerCoercion(PointerCoercion),
1236     /// Cast into a dyn* object.
1237     DynStar,
1238     IntToInt,
1239     FloatToInt,
1240     FloatToFloat,
1241     IntToFloat,
1242     PtrToPtr,
1243     FnPtrToPtr,
1244     /// Reinterpret the bits of the input as a different type.
1245     ///
1246     /// MIR is well-formed if the input and output types have different sizes,
1247     /// but running a transmute between differently-sized types is UB.
1248     ///
1249     /// Allowed only in [`MirPhase::Runtime`]; Earlier it's a [`TerminatorKind::Call`].
1250     Transmute,
1251 }
1252 
1253 #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
1254 #[derive(TypeFoldable, TypeVisitable)]
1255 pub enum AggregateKind<'tcx> {
1256     /// The type is of the element
1257     Array(Ty<'tcx>),
1258     Tuple,
1259 
1260     /// The second field is the variant index. It's equal to 0 for struct
1261     /// and union expressions. The last field is the
1262     /// active field number and is present only for union expressions
1263     /// -- e.g., for a union expression `SomeUnion { c: .. }`, the
1264     /// active field index would identity the field `c`
1265     Adt(DefId, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
1266 
1267     Closure(DefId, SubstsRef<'tcx>),
1268     Generator(DefId, SubstsRef<'tcx>, hir::Movability),
1269 }
1270 
1271 #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
1272 pub enum NullOp<'tcx> {
1273     /// Returns the size of a value of that type
1274     SizeOf,
1275     /// Returns the minimum alignment of a type
1276     AlignOf,
1277     /// Returns the offset of a field
1278     OffsetOf(&'tcx List<FieldIdx>),
1279 }
1280 
1281 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1282 #[derive(HashStable, TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)]
1283 pub enum UnOp {
1284     /// The `!` operator for logical inversion
1285     Not,
1286     /// The `-` operator for negation
1287     Neg,
1288 }
1289 
1290 #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
1291 #[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
1292 pub enum BinOp {
1293     /// The `+` operator (addition)
1294     Add,
1295     /// Like `Add`, but with UB on overflow.  (Integers only.)
1296     AddUnchecked,
1297     /// The `-` operator (subtraction)
1298     Sub,
1299     /// Like `Sub`, but with UB on overflow.  (Integers only.)
1300     SubUnchecked,
1301     /// The `*` operator (multiplication)
1302     Mul,
1303     /// Like `Mul`, but with UB on overflow.  (Integers only.)
1304     MulUnchecked,
1305     /// The `/` operator (division)
1306     ///
1307     /// For integer types, division by zero is UB, as is `MIN / -1` for signed.
1308     /// The compiler should have inserted checks prior to this.
1309     ///
1310     /// Floating-point division by zero is safe, and does not need guards.
1311     Div,
1312     /// The `%` operator (modulus)
1313     ///
1314     /// For integer types, using zero as the modulus (second operand) is UB,
1315     /// as is `MIN % -1` for signed.
1316     /// The compiler should have inserted checks prior to this.
1317     ///
1318     /// Floating-point remainder by zero is safe, and does not need guards.
1319     Rem,
1320     /// The `^` operator (bitwise xor)
1321     BitXor,
1322     /// The `&` operator (bitwise and)
1323     BitAnd,
1324     /// The `|` operator (bitwise or)
1325     BitOr,
1326     /// The `<<` operator (shift left)
1327     ///
1328     /// The offset is truncated to the size of the first operand before shifting.
1329     Shl,
1330     /// Like `Shl`, but is UB if the RHS >= LHS::BITS
1331     ShlUnchecked,
1332     /// The `>>` operator (shift right)
1333     ///
1334     /// The offset is truncated to the size of the first operand before shifting.
1335     ///
1336     /// This is an arithmetic shift if the LHS is signed
1337     /// and a logical shift if the LHS is unsigned.
1338     Shr,
1339     /// Like `Shl`, but is UB if the RHS >= LHS::BITS
1340     ShrUnchecked,
1341     /// The `==` operator (equality)
1342     Eq,
1343     /// The `<` operator (less than)
1344     Lt,
1345     /// The `<=` operator (less than or equal to)
1346     Le,
1347     /// The `!=` operator (not equal to)
1348     Ne,
1349     /// The `>=` operator (greater than or equal to)
1350     Ge,
1351     /// The `>` operator (greater than)
1352     Gt,
1353     /// The `ptr.offset` operator
1354     Offset,
1355 }
1356 
1357 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
1358 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
1359 mod size_asserts {
1360     use super::*;
1361     // tidy-alphabetical-start
1362     static_assert_size!(AggregateKind<'_>, 32);
1363     static_assert_size!(Operand<'_>, 24);
1364     static_assert_size!(Place<'_>, 16);
1365     static_assert_size!(PlaceElem<'_>, 24);
1366     static_assert_size!(Rvalue<'_>, 40);
1367     // tidy-alphabetical-end
1368 }
1369