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