MirPhase in rustc_middle::mir - Rust
Description: Represents the “flavors” of MIR.

Skip to main content

## MirPhase

# Enum MirPhase

Source

    pub enum MirPhase {
        Built,
        Analysis(AnalysisPhase),
        Runtime(RuntimePhase),
    }

Expand description

Represents the “flavors” of MIR.

The MIR pipeline is structured into a few major dialects, with one or more phases within each dialect. A MIR flavor is identified by a dialect-phase pair. A single `MirPhase` value specifies such a pair. All flavors of MIR use the same data structure to represent the program.

Different MIR dialects have different semantics. (The differences between dialects are small, but they do exist.) The progression from one MIR dialect to the next is technically a lowering from one IR to another. In other words, a single well-formed `Body` might have different semantic meaning and different behavior at runtime in the different dialects. The specific differences between dialects are described on the variants below.

Phases exist only to place restrictions on what language constructs are permitted in well-formed MIR, and subsequent phases mostly increase those restrictions. I.e. to convert MIR from one phase to the next might require removing/replacing certain MIR constructs.

When adding dialects or phases, remember to update `MirPhase::index`.

## Variants§

§

### Built

The “built MIR” dialect, as generated by MIR building.

The only things that operate on this dialect are unsafeck, the various MIR lints, and const qualifs.

This dialect has just the one (implicit) phase, which places few restrictions on what MIR constructs are allowed.

§

### Analysis(AnalysisPhase)

The “analysis MIR” dialect, used for borrowck and friends.

The only semantic difference between built MIR and analysis MIR relates to constant promotion. In built MIR, sequences of statements that would generally be subject to constant promotion are semantically constants, while in analysis MIR all constants are explicit.

The result of const promotion is available from the `mir_promoted` and `promoted_mir` queries.

The phases of this dialect are described in `AnalysisPhase`.

§

### Runtime(RuntimePhase)

The “runtime MIR” dialect, used for CTFE, optimizations, and codegen.

The semantic differences between analysis MIR and runtime MIR are as follows.

- Drops: In analysis MIR, `Drop` terminators represent conditional drops; roughly speaking, if dataflow analysis determines that the place being dropped is uninitialized, the drop will not be executed. The exact semantics of this aren’t written down anywhere, which means they are essentially “what drop elaboration does.” In runtime MIR, the drops are unconditional; when a `Drop` terminator is reached, if the type has drop glue that drop glue is always executed. This may be UB if the underlying place is not initialized.
- Packed drops: Places might in general be misaligned - in most cases this is UB, the exception is fields of packed structs. In analysis MIR, `Drop(P)` for a `P` that might be misaligned for this reason implicitly moves `P` to a temporary before dropping. Runtime MIR has no such rules, and dropping a misaligned place is simply UB.
- Async drops: after drop elaboration some drops may become async (`drop`, `async_fut` fields). StateTransform pass will expand those async drops or reset to sync.
- Unwinding: in analysis MIR, unwinding from a function which may not unwind aborts. In runtime MIR, this is UB.
- Retags: If `-Zmir-emit-retag` is enabled, analysis MIR has “implicit” retags in the same way 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}`).
- 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 e.g. may be aliased in surprising ways. Runtime MIR has no such special 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 transformations that can suppress such errors should not run on analysis MIR.

The phases of this dialect are described in `RuntimePhase`.

## Implementations§

Source§

### impl MirPhase

Source

#### pub fn name(&self) -> &'static str

Source

#### pub fn index(&self) -> (usize, usize)

Gets the (dialect, phase) index of the current `MirPhase`. Both numbers are 1-indexed.

## Trait Implementations§

Source§

### impl Clone for MirPhase

Source§

#### fn clone(&self) -> MirPhase

Returns a duplicate of the value. Read more
1.0.0 · Source§

#### fn clone_from(&mut self, source: &Self)

Performs copy-assignment from `source`. Read more
Source§

### impl Debug for MirPhase

Source§

#### fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

### impl<'tcx, __D: TyDecoder<'tcx>> Decodable<__D> for MirPhase

Source§

#### fn decode(__decoder: &mut __D) -> Self

Source§

### impl<'tcx, __E: TyEncoder<'tcx>> Encodable<__E> for MirPhase

Source§

#### fn encode(&self, __encoder: &mut __E)

Source§

### impl<'__ctx> HashStable<StableHashingContext<'__ctx>> for MirPhase

Source§

#### fn hash_stable( &self, __hcx: &mut StableHashingContext<'__ctx>, __hasher: &mut StableHasher, )

Source§

### impl Ord for MirPhase

Source§

#### fn cmp(&self, other: &MirPhase) -> Ordering

This method returns an `Ordering` between `self` and `other`. Read more
1.21.0 · Source§

#### fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

#### fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

#### fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

### impl PartialEq for MirPhase

Source§

#### fn eq(&self, other: &MirPhase) -> bool

Tests for `self` and `other` values to be equal, and is used by `==`.
1.0.0 · Source§

#### fn ne(&self, other: &Rhs) -> bool

Tests for `!=`. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

### impl PartialOrd for MirPhase

Source§

#### fn partial_cmp(&self, other: &MirPhase) -> Option<Ordering>

This method returns an ordering between `self` and `other` values if one exists. Read more
1.0.0 · Source§

#### fn lt(&self, other: &Rhs) -> bool

Tests less than (for `self` and `other`) and is used by the `<` operator. Read more
1.0.0 · Source§

#### fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for `self` and `other`) and is used by the `<=` operator. Read more
1.0.0 · Source§

#### fn gt(&self, other: &Rhs) -> bool

Tests greater than (for `self` and `other`) and is used by the `>` operator. Read more
1.0.0 · Source§

#### fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for `self` and `other`) and is used by the `>=` operator. Read more
Source§

### impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for MirPhase

Source§

#### fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( self, _: &mut F, ) -> Result<Self, F::Error>

The entry point for folding. To fold a value `t` with a folder `f` call: `t.try_fold_with(f)`. Read more
Source§

#### fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, _: &mut F) -> Self

The entry point for folding. To fold a value `t` with a folder `f` call: `t.fold_with(f)`. Read more
Source§

### impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for MirPhase

Source§

#### fn visit_with<F: TypeVisitor<TyCtxt<'tcx>>>(&self, _: &mut F) -> F::Result

The entry point for visiting. To visit a value `t` with a visitor `v` call: `t.visit_with(v)`. Read more
Source§

### impl Copy for MirPhase

Source§

### impl Eq for MirPhase

Source§

### impl StructuralPartialEq for MirPhase

## Auto Trait Implementations§

§

### impl DynSend for MirPhase

§

### impl DynSync for MirPhase

§

### impl Freeze for MirPhase

§

### impl RefUnwindSafe for MirPhase

§

### impl Send for MirPhase

§

### impl Sync for MirPhase

§

### impl Unpin for MirPhase

§

### impl UnsafeUnpin for MirPhase

§

### impl UnwindSafe for MirPhase

## Blanket Implementations§

Source§

### impl<T> Aligned for T

Source§

#### const ALIGN: Alignment

Alignment of `Self`.
Source§

### impl<T> Any for T
where T: 'static + ?Sized,

Source§

#### fn type_id(&self) -> TypeId

Gets the `TypeId` of `self`. Read more
Source§

### impl<T> AnyEq for T
where T: Any + PartialEq,

Source§

#### fn equals(&self, other: &(dyn Any + 'static)) -> bool

Source§

#### fn as_any(&self) -> &(dyn Any + 'static)

Source§

### impl<'tcx, T> ArenaAllocatable<'tcx, IsCopy> for T
where T: Copy,

Source§

#### fn allocate_on(self, arena: &'tcx Arena<'tcx>) -> &'tcx mut T

Source§

#### fn allocate_from_iter( arena: &'tcx Arena<'tcx>, iter: impl IntoIterator<Item = T>, ) -> &'tcx mut [T]

Source§

### impl<'tcx, T> ArenaAllocatable<'tcx, IsCopy> for T
where T: Copy,

Source§

#### fn allocate_on(self, arena: &'tcx Arena<'tcx>) -> &'tcx mut T

Source§

#### fn allocate_from_iter( arena: &'tcx Arena<'tcx>, iter: impl IntoIterator<Item = T>, ) -> &'tcx mut [T]

Source§

### impl<T> Borrow<T> for T
where T: ?Sized,

Source§

#### fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

### impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

#### fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

### impl<T> CloneToUninit for T
where T: Clone,

Source§

#### unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (`clone_to_uninit`)
Performs copy-assignment from `self` to `dest`. Read more
Source§

### impl<T, R> CollectAndApply<T, R> for T

Source§

#### fn collect_and_apply<I, F>(iter: I, f: F) -> R
where I: Iterator<Item = T>, F: FnOnce(&[T]) -> R,

Equivalent to `f(&iter.collect::<Vec<_>>())`.

Source§

#### type Output = R

Source§

### impl<Q, K> Comparable<K> for Q
where Q: Ord + ?Sized, K: Borrow<Q> + ?Sized,

Source§

#### fn compare(&self, key: &K) -> Ordering

Compare self to `key` and return their ordering.
Source§

### impl<'tcx, T> DepNodeKey<'tcx> for T
where T: for<'a> HashStable<StableHashingContext<'a>> + Debug,

Source§

#### default fn key_fingerprint_style() -> KeyFingerprintStyle

Source§

#### default fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint

This method turns a query key into an opaque `Fingerprint` to be used in `DepNode`.
Source§

#### default fn try_recover_key(_: TyCtxt<'tcx>, _: &DepNode) -> Option<T>

This method tries to recover the query key from the given `DepNode`, something which is needed when forcing `DepNode`s during red-green evaluation. The query system will only call this method if `fingerprint_style()` is not `FingerprintStyle::Opaque`. It is always valid to return `None` here, in which case incremental compilation will treat the query as having changed instead of forcing it.
Source§

### impl<T> DynClone for T
where T: Clone,

Source§

#### fn __clone_box(&self, _: Private) -> *mut ()

Source§

### impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

#### fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

### impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

#### fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

### impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

#### fn equivalent(&self, key: &K) -> bool

Compare self to `key` and return `true` if they are equal.
Source§

### impl<T> From<T> for T

Source§

#### fn from(t: T) -> T

Returns the argument unchanged.

Source§

### impl<T> Instrument for T

Source§

#### fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided `Span`, returning an `Instrumented` wrapper. Read more
Source§

#### fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current `Span`, returning an `Instrumented` wrapper. Read more
Source§

### impl<T, U> Into<U> for T
where U: From<T>,

Source§

#### fn into(self) -> U

Calls `U::from(self)`.

That is, this conversion is whatever the implementation of `From<T> for U` chooses to do.

Source§

### impl<T> IntoEither for T

Source§

#### fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts `self` into a `Left` variant of `Either<Self, Self>` if `into_left` is `true`. Converts `self` into a `Right` variant of `Either<Self, Self>` otherwise. Read more
Source§

#### fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts `self` into a `Left` variant of `Either<Self, Self>` if `into_left(&self)` returns `true`. Converts `self` into a `Right` variant of `Either<Self, Self>` otherwise. Read more
Source§

### impl<K> IntoQueryKey<K> for K

Source§

#### fn into_query_key(self) -> K

Argument conversion from `Self` to `K`. This should always be a very cheap conversion, e.g. `LocalDefId::to_def_id`.
Source§

### impl<'tcx, T> IsSuggestable<'tcx> for T
where T: TypeVisitable<TyCtxt<'tcx>> + TypeFoldable<TyCtxt<'tcx>>,

Source§

#### fn is_suggestable(self, tcx: TyCtxt<'tcx>, infer_suggestable: bool) -> bool

Whether this makes sense to suggest in a diagnostic. Read more
Source§

#### fn make_suggestable( self, tcx: TyCtxt<'tcx>, infer_suggestable: bool, placeholder: Option<Ty<'tcx>>, ) -> Option<T>

Source§

### impl<T> MaybeResult<T> for T

Source§

#### type Error = !

Source§

#### fn from(_: Result<T, <T as MaybeResult<T>>::Error>) -> T

Source§

#### fn to_result(self) -> Result<T, <T as MaybeResult<T>>::Error>

Source§

### impl<T> Pointable for T

Source§

#### const ALIGN: usize

The alignment of pointer.
Source§

#### type Init = T

The type for initializers.
Source§

#### unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

#### unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

#### unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

#### unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

### impl<T> Same for T

Source§

#### type Output = T

Should always be `Self`
Source§

### impl<T> ToOwned for T
where T: Clone,

Source§

#### type Owned = T

The resulting type after obtaining ownership.
Source§

#### fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

#### fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

### impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

#### type Error = Infallible

The type returned in the event of a conversion error.
Source§

#### fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

### impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

#### type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

#### fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

### impl<I, T> TypeVisitableExt<I> for T
where I: Interner, T: TypeVisitable<I>,

Source§

#### fn has_type_flags(&self, flags: TypeFlags) -> bool

Source§

#### fn has_vars_bound_at_or_above(&self, binder: DebruijnIndex) -> bool

Returns `true` if `self` has any late-bound regions that are either bound by `binder` or bound by some binder outside of `binder`. If `binder` is `ty::INNERMOST`, this indicates whether there are any late-bound regions that appear free.
Source§

#### fn error_reported(&self) -> Result<(), <I as Interner>::ErrorGuaranteed>

Source§

#### fn non_region_error_reported( &self, ) -> Result<(), <I as Interner>::ErrorGuaranteed>

Source§

#### fn has_vars_bound_above(&self, binder: DebruijnIndex) -> bool

Returns `true` if this type has any regions that escape `binder` (and hence are not bound by it).
Source§

#### fn has_escaping_bound_vars(&self) -> bool

Return `true` if this type has regions that are not a part of the type. For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)` would return `true`. The latter can occur when traversing through the former. Read more
Source§

#### fn has_aliases(&self) -> bool

Source§

#### fn has_opaque_types(&self) -> bool

Source§

#### fn has_coroutines(&self) -> bool

Source§

#### fn references_error(&self) -> bool

Source§

#### fn has_non_region_param(&self) -> bool

Source§

#### fn has_infer_regions(&self) -> bool

Source§

#### fn has_infer_types(&self) -> bool

Source§

#### fn has_non_region_infer(&self) -> bool

Source§

#### fn has_infer(&self) -> bool

Source§

#### fn has_placeholders(&self) -> bool

Source§

#### fn has_non_region_placeholders(&self) -> bool

Source§

#### fn has_param(&self) -> bool

Source§

#### fn has_free_regions(&self) -> bool

“Free” regions in this context means that it has any region that is not (a) erased or (b) late-bound.
Source§

#### fn has_erased_regions(&self) -> bool

Source§

#### fn has_erasable_regions(&self) -> bool

True if there are any un-erased free regions.
Source§

#### fn is_global(&self) -> bool

Indicates whether this value references only ‘global’ generic parameters that are the same regardless of what fn we are in. This is used for caching.
Source§

#### fn has_bound_regions(&self) -> bool

True if there are any late-bound regions
Source§

#### fn has_non_region_bound_vars(&self) -> bool

True if there are any late-bound non-region variables
Source§

#### fn has_bound_vars(&self) -> bool

True if there are any bound variables
Source§

#### fn still_further_specializable(&self) -> bool

Indicates whether this value still has parameters/placeholders/inference variables which could be replaced later, in a way that would change the results of `impl` specialization.
Source§

#### fn has_non_region_error(&self) -> bool

True if a type or const error is reachable
Source§

### impl<I, T, U> Upcast<I, U> for T
where U: UpcastFrom<I, T>,

Source§

#### fn upcast(self, interner: I) -> U

Source§

### impl<I, T> UpcastFrom<I, T> for T

Source§

#### fn upcast_from(from: T, _tcx: I) -> T

Source§

### impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

#### fn vzip(self) -> V

Source§

### impl<T> WithSubscriber for T

Source§

#### fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided `Subscriber` to this type, returning a `WithDispatch` wrapper. Read more
Source§

#### fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default `Subscriber` to this type, returning a `WithDispatch` wrapper. Read more
Source§

### impl<T> ErasedDestructor for T
where T: 'static,

## Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain `repr(...)` attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 2 bytes

Size for each variant:

- `Built`: 0 bytes
- `Analysis`: 1 byte
- `Runtime`: 1 byte