# Enum stable_mir::mir::body::ProjectionElem

source ·

    pub enum ProjectionElem {
        Deref,
        Field(FieldIdx, Ty),
        Index(Local),
        ConstantIndex {
            offset: u64,
            min_length: u64,
            from_end: bool,
        },
        Subslice {
            from: u64,
            to: u64,
            from_end: bool,
        },
        Downcast(VariantIdx),
        OpaqueCast(Ty),
        Subtype(Ty),
    }

## Variants§

§

### Deref

Dereference projections (e.g. `*_1`) project to the address referenced by the base place.

§

### Field(FieldIdx, Ty)

A field projection (e.g., `f` in `_1.f`) project to a field in the base place. The field is referenced by source-order index rather than the name of the field. The fields type is also given.

§

### Index(Local)

Index into a slice/array. The value of the index is computed at runtime using the `V` argument.

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

Index into a slice/array given by offsets.

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. For arrays this is always the exact length.

§`from_end: bool`

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

§

### Subslice

Projects a slice from the base place.

These indices are generated by slice patterns. If `from_end` is true, this represents `slice[from..slice.len() - to]`. Otherwise it represents `array[from..to]`.

#### Fields

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

Whether `to` counts from the start or end of the array/slice.

§

### Downcast(VariantIdx)

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

§

### OpaqueCast(Ty)

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

§

### Subtype(Ty)

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.

## Implementations§

source§

### impl ProjectionElem

source

#### pub fn ty(&self, place_ty: Ty) -> Result<Ty, Error>

Get the expected type after applying this projection to a given place type.

source

#### fn index_ty(ty: Ty) -> Result<Ty, Error>

source

#### fn subslice_ty( ty: Ty, from: &u64, to: &u64, from_end: &bool ) -> Result<Ty, Error>

source

#### fn deref_ty(ty: Ty) -> Result<Ty, Error>

## Trait Implementations§

source§

### impl Clone for ProjectionElem

source§

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

Returns a copy 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 ProjectionElem

source§

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

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

### impl PartialEq for ProjectionElem

source§

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

This method tests for `self` and `other` values to be equal, and is used by `==`.
1.0.0 · source§

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

This method tests for `!=`. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

### impl Eq for ProjectionElem

source§

### impl StructuralPartialEq for ProjectionElem

## Auto Trait Implementations§

§

### impl Freeze for ProjectionElem

§

### impl RefUnwindSafe for ProjectionElem

§

### impl Send for ProjectionElem

§

### impl Sync for ProjectionElem

§

### impl Unpin for ProjectionElem

§

### impl UnwindSafe for ProjectionElem

## 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> 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,

§

#### 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>,

§

#### 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>,

§

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

## 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: 24 bytes

Size for each variant:

- `Deref`: 0 bytes
- `Field`: 23 bytes
- `Index`: 15 bytes
- `ConstantIndex`: 23 bytes
- `Subslice`: 23 bytes
- `Downcast`: 15 bytes
- `OpaqueCast`: 15 bytes
- `Subtype`: 15 bytes