flowistry_pdg::rustc::mir

Enum ProjectionElem

Source
pub enum ProjectionElem<V, T> {
    Deref,
    Field(FieldIdx, T),
    Index(V),
    ConstantIndex {
        offset: u64,
        min_length: u64,
        from_end: bool,
    },
    Subslice {
        from: u64,
        to: u64,
        from_end: bool,
    },
    Downcast(Option<Symbol>, VariantIdx),
    OpaqueCast(T),
    Subtype(T),
}

Variants§

§

Deref

§

Field(FieldIdx, T)

A field (e.g., f in _1.f) is one variant of ProjectionElem. Conceptually, rustc can identify that a field projection refers to either two different regions of memory or the same one between the base and the ‘projection element’. Read more about projections in the rustc-dev-guide

§

Index(V)

Index into a slice/array.

Note that this does not also dereference, and so it does not exactly correspond to slice indexing in Rust. In other words, in the below Rust code:

let x = &[1, 2, 3, 4];
let i = 2;
x[i];

The x[i] is turned into a Deref followed by an Index, not just an Index. The same thing is true of the ConstantIndex and Subslice projections below.

§

ConstantIndex

These indices are generated by slice patterns. Easiest to explain by example:

[X, _, .._, _, _] => { offset: 0, min_length: 4, from_end: false },
[_, X, .._, _, _] => { offset: 1, min_length: 4, from_end: false },
[_, _, .._, X, _] => { offset: 2, min_length: 4, from_end: true },
[_, _, .._, _, X] => { offset: 1, min_length: 4, from_end: true },

Fields

§offset: u64

index or -index (in Python terms), depending on from_end

§min_length: u64

The thing being indexed must be at least this long – otherwise, the projection is UB.

For arrays this is always the exact length.

§from_end: bool

Counting backwards from end? This is always false when indexing an array.

§

Subslice

These indices are generated by slice patterns.

If from_end is true slice[from..slice.len() - to]. Otherwise array[from..to].

Fields

§from: u64
§to: u64
§from_end: bool

Whether to counts from the start or end of the array/slice. For PlaceElems this is true if and only if the base is a slice. For ProjectionKind, this can also be true for arrays.

§

Downcast(Option<Symbol>, VariantIdx)

“Downcast” to a variant of an enum or a coroutine.

The included Symbol is the name of the variant, used for printing MIR.

This operation itself is never UB, all it does is change the type of the place.

§

OpaqueCast(T)

Like an explicit cast from an opaque type to a concrete type, but without requiring an intermediate variable.

§

Subtype(T)

A Subtype(T) projection is applied to any StatementKind::Assign where type of lvalue doesn’t match the type of rvalue, the primary goal is making subtyping explicit during optimizations and codegen.

This projection doesn’t impact the runtime behavior of the program except for potentially changing some type metadata of the interpreter or codegen backend.

This goal is achieved with mir_transform pass Subtyper, which runs right after borrowchecker, as we only care about subtyping that can affect trait selection and TypeId.

Auto Trait Implementations§

§

impl<V, T> Freeze for ProjectionElem<V, T>
where T: Freeze, V: Freeze,

§

impl<V, T> RefUnwindSafe for ProjectionElem<V, T>

§

impl<V, T> Send for ProjectionElem<V, T>
where T: Send, V: Send,

§

impl<V, T> Sync for ProjectionElem<V, T>
where T: Sync, V: Sync,

§

impl<V, T> Unpin for ProjectionElem<V, T>
where T: Unpin, V: Unpin,

§

impl<V, T> UnwindSafe for ProjectionElem<V, T>
where T: UnwindSafe, V: UnwindSafe,

Blanket Implementations§

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> 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, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> 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.