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