summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/mir/syntax.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /compiler/rustc_middle/src/mir/syntax.rs
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_middle/src/mir/syntax.rs')
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs93
1 files changed, 47 insertions, 46 deletions
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 0b95fdfa1..7b0f27f9b 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -5,7 +5,7 @@
use super::{BasicBlock, Const, Local, UserTypeProjection};
-use crate::mir::coverage::{CodeRegion, CoverageKind};
+use crate::mir::coverage::CoverageKind;
use crate::traits::Reveal;
use crate::ty::adjustment::PointerCoercion;
use crate::ty::GenericArgsRef;
@@ -15,7 +15,7 @@ use crate::ty::{Region, UserTypeAnnotationIndex};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir};
-use rustc_hir::{self, GeneratorKind};
+use rustc_hir::{self, CoroutineKind};
use rustc_index::IndexVec;
use rustc_target::abi::{FieldIdx, VariantIdx};
@@ -82,10 +82,10 @@ pub enum MirPhase {
/// that Rust itself has them. Where exactly these are is generally subject to change, and so we
/// don't document this here. Runtime MIR has most retags explicit (though implicit retags
/// can still occur at `Rvalue::{Ref,AddrOf}`).
- /// - Generator bodies: In analysis MIR, locals may actually be behind a pointer that user code has
- /// access to. This occurs in generator bodies. Such locals do not behave like other locals,
+ /// - Coroutine bodies: In analysis MIR, locals may actually be behind a pointer that user code has
+ /// access to. This occurs in coroutine bodies. Such locals do not behave like other locals,
/// because they eg may be aliased in surprising ways. Runtime MIR has no such special locals -
- /// all generator bodies are lowered and so all places that look like locals really are locals.
+ /// all coroutine bodies are lowered and so all places that look like locals really are locals.
///
/// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part
/// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that
@@ -137,7 +137,7 @@ pub enum RuntimePhase {
/// In addition to the semantic changes, beginning with this phase, the following variants are
/// disallowed:
/// * [`TerminatorKind::Yield`]
- /// * [`TerminatorKind::GeneratorDrop`]
+ /// * [`TerminatorKind::CoroutineDrop`]
/// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
/// * [`PlaceElem::OpaqueCast`]
///
@@ -292,7 +292,7 @@ pub enum StatementKind<'tcx> {
/// Write the discriminant for a variant to the enum Place.
///
- /// This is permitted for both generators and ADTs. This does not necessarily write to the
+ /// This is permitted for both coroutines and ADTs. This does not necessarily write to the
/// entire place; instead, it writes to the minimum set of bytes as required by the layout for
/// the type.
SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
@@ -361,11 +361,16 @@ pub enum StatementKind<'tcx> {
/// Disallowed after drop elaboration.
AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance),
- /// Marks the start of a "coverage region", injected with '-Cinstrument-coverage'. A
- /// `Coverage` statement carries metadata about the coverage region, used to inject a coverage
- /// map into the binary. If `Coverage::kind` is a `Counter`, the statement also generates
- /// executable code, to increment a counter variable at runtime, each time the code region is
- /// executed.
+ /// Carries control-flow-sensitive information injected by `-Cinstrument-coverage`,
+ /// such as where to generate physical coverage-counter-increments during codegen.
+ ///
+ /// Coverage statements are used in conjunction with the coverage mappings and other
+ /// information stored in the function's
+ /// [`mir::Body::function_coverage_info`](crate::mir::Body::function_coverage_info).
+ /// (For inlined MIR, take care to look up the *original function's* coverage info.)
+ ///
+ /// Interpreters and codegen backends that don't support coverage instrumentation
+ /// can usually treat this as a no-op.
Coverage(Box<Coverage>),
/// Denotes a call to an intrinsic that does not require an unwind path and always returns.
@@ -514,7 +519,6 @@ pub enum FakeReadCause {
#[derive(TypeFoldable, TypeVisitable)]
pub struct Coverage {
pub kind: CoverageKind,
- pub code_region: Option<CodeRegion>,
}
#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
@@ -622,8 +626,8 @@ pub enum TerminatorKind<'tcx> {
/// `dest = move _0`. It might additionally do other things, like have side-effects in the
/// aliasing model.
///
- /// If the body is a generator body, this has slightly different semantics; it instead causes a
- /// `GeneratorState::Returned(_0)` to be created (as if by an `Aggregate` rvalue) and assigned
+ /// If the body is a coroutine body, this has slightly different semantics; it instead causes a
+ /// `CoroutineState::Returned(_0)` to be created (as if by an `Aggregate` rvalue) and assigned
/// to the return place.
Return,
@@ -705,14 +709,14 @@ pub enum TerminatorKind<'tcx> {
/// Marks a suspend point.
///
- /// Like `Return` terminators in generator bodies, this computes `value` and then a
- /// `GeneratorState::Yielded(value)` as if by `Aggregate` rvalue. That value is then assigned to
+ /// Like `Return` terminators in coroutine bodies, this computes `value` and then a
+ /// `CoroutineState::Yielded(value)` as if by `Aggregate` rvalue. That value is then assigned to
/// the return place of the function calling this one, and execution continues in the calling
/// function. When next invoked with the same first argument, execution of this function
/// continues at the `resume` basic block, with the second argument written to the `resume_arg`
- /// place. If the generator is dropped before then, the `drop` basic block is invoked.
+ /// place. If the coroutine is dropped before then, the `drop` basic block is invoked.
///
- /// Not permitted in bodies that are not generator bodies, or after generator lowering.
+ /// Not permitted in bodies that are not coroutine bodies, or after coroutine lowering.
///
/// **Needs clarification**: What about the evaluation order of the `resume_arg` and `value`?
Yield {
@@ -722,21 +726,21 @@ pub enum TerminatorKind<'tcx> {
resume: BasicBlock,
/// The place to store the resume argument in.
resume_arg: Place<'tcx>,
- /// Cleanup to be done if the generator is dropped at this suspend point.
+ /// Cleanup to be done if the coroutine is dropped at this suspend point.
drop: Option<BasicBlock>,
},
- /// Indicates the end of dropping a generator.
+ /// Indicates the end of dropping a coroutine.
///
- /// Semantically just a `return` (from the generators drop glue). Only permitted in the same situations
+ /// Semantically just a `return` (from the coroutines drop glue). Only permitted in the same situations
/// as `yield`.
///
- /// **Needs clarification**: Is that even correct? The generator drop code is always confusing
+ /// **Needs clarification**: Is that even correct? The coroutine drop code is always confusing
/// to me, because it's not even really in the current body.
///
/// **Needs clarification**: Are there type system constraints on these terminators? Should
/// there be a "block type" like `cleanup` blocks for them?
- GeneratorDrop,
+ CoroutineDrop,
/// A block where control flow only ever takes one real path, but borrowck needs to be more
/// conservative.
@@ -811,7 +815,7 @@ impl TerminatorKind<'_> {
TerminatorKind::Call { .. } => "Call",
TerminatorKind::Assert { .. } => "Assert",
TerminatorKind::Yield { .. } => "Yield",
- TerminatorKind::GeneratorDrop => "GeneratorDrop",
+ TerminatorKind::CoroutineDrop => "CoroutineDrop",
TerminatorKind::FalseEdge { .. } => "FalseEdge",
TerminatorKind::FalseUnwind { .. } => "FalseUnwind",
TerminatorKind::InlineAsm { .. } => "InlineAsm",
@@ -879,8 +883,8 @@ pub enum AssertKind<O> {
OverflowNeg(O),
DivisionByZero(O),
RemainderByZero(O),
- ResumedAfterReturn(GeneratorKind),
- ResumedAfterPanic(GeneratorKind),
+ ResumedAfterReturn(CoroutineKind),
+ ResumedAfterPanic(CoroutineKind),
MisalignedPointerDereference { required: O, found: O },
}
@@ -957,8 +961,8 @@ pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
/// was unsized and so had metadata associated with it, then the metadata is retained if the
/// field is unsized and thrown out if it is sized.
///
-/// These projections are only legal for tuples, ADTs, closures, and generators. If the ADT or
-/// generator has more than one variant, the parent place's variant index must be set, indicating
+/// These projections are only legal for tuples, ADTs, closures, and coroutines. If the ADT or
+/// coroutine has more than one variant, the parent place's variant index must be set, indicating
/// which variant is being used. If it has just one variant, the variant index may or may not be
/// included - the single possible variant is inferred if it is not included.
/// - [`OpaqueCast`](ProjectionElem::OpaqueCast): This projection changes the place's type to the
@@ -986,18 +990,15 @@ pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
/// pointee's type. The resulting address is the address that was stored in the pointer. If the
/// pointee type is unsized, the pointer additionally stored the value of the metadata.
///
-/// Computing a place may cause UB. One possibility is that the pointer used for a `Deref` may not
-/// be suitably aligned. Another possibility is that the place is not in bounds, meaning it does not
-/// point to an actual allocation.
-///
-/// However, if this is actually UB and when the UB kicks in is undecided. This is being discussed
-/// in [UCG#319]. The options include that every place must obey those rules, that only some places
-/// must obey them, or that places impose no rules of their own.
-///
-/// [UCG#319]: https://github.com/rust-lang/unsafe-code-guidelines/issues/319
-///
-/// Rust currently requires that every place obey those two rules. This is checked by MIRI and taken
-/// advantage of by codegen (via `gep inbounds`). That is possibly subject to change.
+/// The "validity invariant" of places is the same as that of raw pointers, meaning that e.g.
+/// `*ptr` on a dangling or unaligned pointer is never UB. (Later doing a load/store on that place
+/// or turning it into a reference can be UB though!) The only ways for a place computation can
+/// cause UB are:
+/// - On a `Deref` projection, we do an actual load of the inner place, with all the usual
+/// consequences (the inner place must be based on an aligned pointer, it must point to allocated
+/// memory, the aliasig model must allow reads, this must not be a data race).
+/// - For the projections that perform pointer arithmetic, the offset must in-bounds of an
+/// allocation (i.e., the preconditions of `ptr::offset` must be met).
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable, TypeFoldable, TypeVisitable)]
pub struct Place<'tcx> {
pub local: Local,
@@ -1067,7 +1068,7 @@ pub enum ProjectionElem<V, T> {
from_end: bool,
},
- /// "Downcast" to a variant of an enum or a generator.
+ /// "Downcast" to a variant of an enum or a coroutine.
///
/// The included Symbol is the name of the variant, used for printing MIR.
Downcast(Option<Symbol>, VariantIdx),
@@ -1277,8 +1278,8 @@ pub enum Rvalue<'tcx> {
/// `dest = Foo { x: ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case that `Foo`
/// has a destructor.
///
- /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
- /// generator lowering, `Generator` aggregate kinds are disallowed too.
+ /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Coroutine`. After
+ /// coroutine lowering, `Coroutine` aggregate kinds are disallowed too.
Aggregate(Box<AggregateKind<'tcx>>, IndexVec<FieldIdx, Operand<'tcx>>),
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
@@ -1343,7 +1344,7 @@ pub enum AggregateKind<'tcx> {
Adt(DefId, VariantIdx, GenericArgsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
Closure(DefId, GenericArgsRef<'tcx>),
- Generator(DefId, GenericArgsRef<'tcx>, hir::Movability),
+ Coroutine(DefId, GenericArgsRef<'tcx>, hir::Movability),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
@@ -1353,7 +1354,7 @@ pub enum NullOp<'tcx> {
/// Returns the minimum alignment of a type
AlignOf,
/// Returns the offset of a field
- OffsetOf(&'tcx List<FieldIdx>),
+ OffsetOf(&'tcx List<(VariantIdx, FieldIdx)>),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]