ExprKind in rustc_middle::thir - Rust
Description: API documentation for the Rust `ExprKind` enum in crate `rustc_middle`.

Skip to main content

## ExprKind

# Enum ExprKind

Source

    pub enum ExprKind<'tcx> {
    Show 51 variants    Scope {
            region_scope: Scope,
            hir_id: HirId,
            value: ExprId,
        },
        If {
            if_then_scope: Scope,
            cond: ExprId,
            then: ExprId,
            else_opt: Option<ExprId>,
        },
        Call {
            ty: Ty<'tcx>,
            fun: ExprId,
            args: Box<[ExprId]>,
            from_hir_call: bool,
            fn_span: Span,
        },
        ByUse {
            expr: ExprId,
            span: Span,
        },
        Deref {
            arg: ExprId,
        },
        Binary {
            op: BinOp,
            lhs: ExprId,
            rhs: ExprId,
        },
        LogicalOp {
            op: LogicalOp,
            lhs: ExprId,
            rhs: ExprId,
        },
        Unary {
            op: UnOp,
            arg: ExprId,
        },
        Cast {
            source: ExprId,
        },
        Use {
            source: ExprId,
        },
        NeverToAny {
            source: ExprId,
        },
        PointerCoercion {
            cast: PointerCoercion,
            source: ExprId,
            is_from_as_cast: bool,
        },
        Loop {
            body: ExprId,
        },
        LoopMatch {
            state: ExprId,
            region_scope: Scope,
            match_data: Box<LoopMatchMatchData>,
        },
        Let {
            expr: ExprId,
            pat: Box<Pat<'tcx>>,
        },
        Match {
            scrutinee: ExprId,
            arms: Box<[ArmId]>,
            match_source: MatchSource,
        },
        Block {
            block: BlockId,
        },
        Assign {
            lhs: ExprId,
            rhs: ExprId,
        },
        AssignOp {
            op: AssignOp,
            lhs: ExprId,
            rhs: ExprId,
        },
        Field {
            lhs: ExprId,
            variant_index: VariantIdx,
            name: FieldIdx,
        },
        Index {
            lhs: ExprId,
            index: ExprId,
        },
        VarRef {
            id: LocalVarId,
        },
        UpvarRef {
            closure_def_id: DefId,
            var_hir_id: LocalVarId,
        },
        Borrow {
            borrow_kind: BorrowKind,
            arg: ExprId,
        },
        RawBorrow {
            mutability: Mutability,
            arg: ExprId,
        },
        Break {
            label: Scope,
            value: Option<ExprId>,
        },
        Continue {
            label: Scope,
        },
        ConstContinue {
            label: Scope,
            value: ExprId,
        },
        Return {
            value: Option<ExprId>,
        },
        Become {
            value: ExprId,
        },
        ConstBlock {
            did: DefId,
            args: GenericArgsRef<'tcx>,
        },
        Repeat {
            value: ExprId,
            count: Const<'tcx>,
        },
        Array {
            fields: Box<[ExprId]>,
        },
        Tuple {
            fields: Box<[ExprId]>,
        },
        Adt(Box<AdtExpr<'tcx>>),
        PlaceTypeAscription {
            source: ExprId,
            user_ty: Option<Box<CanonicalUserType<'tcx>>>,
            user_ty_span: Span,
        },
        ValueTypeAscription {
            source: ExprId,
            user_ty: Option<Box<CanonicalUserType<'tcx>>>,
            user_ty_span: Span,
        },
        PlaceUnwrapUnsafeBinder {
            source: ExprId,
        },
        ValueUnwrapUnsafeBinder {
            source: ExprId,
        },
        WrapUnsafeBinder {
            source: ExprId,
        },
        Closure(Box<ClosureExpr<'tcx>>),
        Literal {
            lit: Lit,
            neg: bool,
        },
        NonHirLiteral {
            lit: ScalarInt,
            user_ty: Option<Box<CanonicalUserType<'tcx>>>,
        },
        ZstLiteral {
            user_ty: Option<Box<CanonicalUserType<'tcx>>>,
        },
        NamedConst {
            def_id: DefId,
            args: GenericArgsRef<'tcx>,
            user_ty: Option<Box<CanonicalUserType<'tcx>>>,
        },
        ConstParam {
            param: ParamConst,
            def_id: DefId,
        },
        StaticRef {
            alloc_id: AllocId,
            ty: Ty<'tcx>,
            def_id: DefId,
        },
        InlineAsm(Box<InlineAsmExpr<'tcx>>),
        ThreadLocalRef(DefId),
        Yield {
            value: ExprId,
        },
        Reborrow {
            source: ExprId,
            mutability: Mutability,
            target: Ty<'tcx>,
        },
    }

## Variants§

§

### Scope

`Scope`s are used to explicitly mark destruction scopes, and to track the `HirId` of the expressions within the scope.

#### Fields

§`region_scope: Scope`
§`hir_id: HirId`
§`value: ExprId`
§

### If

An `if` expression.

#### Fields

§`if_then_scope: Scope`
§`cond: ExprId`
§`then: ExprId`

`then` is always `ExprKind::Block`.

§`else_opt: Option<ExprId>`

If present, the `else_opt` expr is always `ExprKind::Block` (for `else`) or `ExprKind::If` (for `else if`).

§

### Call

A function call. Method calls and overloaded operators are converted to plain function calls.

#### Fields

§`ty: Ty<'tcx>`

The type of the function. This is often a `FnDef` or a `FnPtr`.

§`fun: ExprId`

The function itself.

§`args: Box<[ExprId]>`

The arguments passed to the function.

Note: in some cases (like calling a closure), the function call `f(...args)` gets rewritten as a call to a function trait method (e.g. `FnOnce::call_once(f, (...args))`).

§`from_hir_call: bool`

Whether this is from an overloaded operator rather than a function call from HIR. `true` for overloaded function call.

§`fn_span: Span`

The span of the function, without the dot and receiver (e.g. `foo(a, b)` in `x.foo(a, b)`).

§

### ByUse

A use expression `x.use`.

#### Fields

§`expr: ExprId`

The expression on which use is applied.

§`span: Span`

The span of use, without the dot and receiver (e.g. `use` in `x.use`).

§

### Deref

A non-overloaded dereference.

#### Fields

§`arg: ExprId`
§

### Binary

A non-overloaded binary operation.

#### Fields

§`op: BinOp`
§`lhs: ExprId`
§`rhs: ExprId`
§

### LogicalOp

A logical operation. This is distinct from `BinaryOp` because the operands need to be lazily evaluated.

#### Fields

§`op: LogicalOp`
§`lhs: ExprId`
§`rhs: ExprId`
§

### Unary

A non-overloaded unary operation. Note that here the deref (`*`) operator is represented by `ExprKind::Deref`.

#### Fields

§`op: UnOp`
§`arg: ExprId`
§

### Cast

A cast: `<source> as <type>`. The type we cast to is the type of the parent expression.

#### Fields

§`source: ExprId`
§

### Use

Forces its contents to be treated as a value expression, not a place expression. This is inserted in some places where an operation would otherwise be erased completely (e.g. some no-op casts), but we still need to ensure that its operand is treated as a value and not a place.

#### Fields

§`source: ExprId`
§

### NeverToAny

A coercion from `!` to any type.

#### Fields

§`source: ExprId`
§

### PointerCoercion

A pointer coercion. More information can be found in `PointerCoercion`. Pointer casts that cannot be done by coercions are represented by `ExprKind::Cast`.

#### Fields

§`cast: PointerCoercion`
§`source: ExprId`
§`is_from_as_cast: bool`

Whether this coercion is written with an `as` cast in the source code.

§

### Loop

A `loop` expression.

#### Fields

§`body: ExprId`
§

### LoopMatch

A `#[loop_match] loop { state = 'blk: { match state { ... } } }` expression.

#### Fields

§`state: ExprId`

The state variable that is updated. The `match_data.scrutinee` is the same variable, but with a different span.

§`region_scope: Scope`
§`match_data: Box<LoopMatchMatchData>`
§

### Let

Special expression representing the `let` part of an `if let` or similar construct (including `if let` guards in match arms, and let-chains formed by `&&`).

This isn’t considered a real expression in surface Rust syntax, so it can only appear in specific situations, such as within the condition of an `if`.

(Not to be confused with `StmtKind::Let`, which is a normal `let` statement.)

#### Fields

§`expr: ExprId`
§`pat: Box<Pat<'tcx>>`
§

### Match

A `match` expression.

#### Fields

§`scrutinee: ExprId`
§`arms: Box<[ArmId]>`
§`match_source: MatchSource`
§

### Block

A block.

#### Fields

§`block: BlockId`
§

### Assign

An assignment: `lhs = rhs`.

#### Fields

§`lhs: ExprId`
§`rhs: ExprId`
§

### AssignOp

A non-overloaded operation assignment, e.g. `lhs += rhs`.

#### Fields

§`op: AssignOp`
§`lhs: ExprId`
§`rhs: ExprId`
§

### Field

Access to a field of a struct, a tuple, an union, or an enum.

#### Fields

§`lhs: ExprId`
§`variant_index: VariantIdx`

Variant containing the field.

§`name: FieldIdx`

This can be a named (`.foo`) or unnamed (`.0`) field.

§

### Index

A non-overloaded indexing operation.

#### Fields

§`lhs: ExprId`
§`index: ExprId`
§

### VarRef

A local variable.

#### Fields

§`id: LocalVarId`
§

### UpvarRef

Used to represent upvars mentioned in a closure/coroutine

#### Fields

§`closure_def_id: DefId`

DefId of the closure/coroutine

§`var_hir_id: LocalVarId`

HirId of the root variable

§

### Borrow

A borrow, e.g. `&arg`.

#### Fields

§`borrow_kind: BorrowKind`
§`arg: ExprId`
§

### RawBorrow

A `&raw [const|mut] $place_expr` raw borrow resulting in type `*[const|mut] T`.

#### Fields

§`mutability: Mutability`
§`arg: ExprId`
§

### Break

A `break` expression.

#### Fields

§`label: Scope`
§`value: Option<ExprId>`
§

### Continue

A `continue` expression.

#### Fields

§`label: Scope`
§

### ConstContinue

A `#[const_continue] break` expression.

#### Fields

§`label: Scope`
§`value: ExprId`
§

### Return

A `return` expression.

#### Fields

§`value: Option<ExprId>`
§

### Become

A `become` expression.

#### Fields

§`value: ExprId`
§

### ConstBlock

An inline `const` block, e.g. `const {}`.

#### Fields

§`did: DefId`
§`args: GenericArgsRef<'tcx>`
§

### Repeat

An array literal constructed from one repeated element, e.g. `[1; 5]`.

#### Fields

§`value: ExprId`
§`count: Const<'tcx>`
§

### Array

An array, e.g. `[a, b, c, d]`.

#### Fields

§`fields: Box<[ExprId]>`
§

### Tuple

A tuple, e.g. `(a, b, c, d)`.

#### Fields

§`fields: Box<[ExprId]>`
§

### Adt(Box<AdtExpr<'tcx>>)

An ADT constructor, e.g. `Foo {x: 1, y: 2}`.

§

### PlaceTypeAscription

A type ascription on a place.

#### Fields

§`source: ExprId`
§`user_ty: Option<Box<CanonicalUserType<'tcx>>>`

Type that the user gave to this expression

§`user_ty_span: Span`
§

### ValueTypeAscription

A type ascription on a value, e.g. `type_ascribe!(42, i32)` or `42 as i32`.

#### Fields

§`source: ExprId`
§`user_ty: Option<Box<CanonicalUserType<'tcx>>>`

Type that the user gave to this expression

§`user_ty_span: Span`
§

### PlaceUnwrapUnsafeBinder

An unsafe binder cast on a place, e.g. `unwrap_binder!(*ptr)`.

#### Fields

§`source: ExprId`
§

### ValueUnwrapUnsafeBinder

An unsafe binder cast on a value, e.g. `unwrap_binder!(rvalue())`, which makes a temporary.

#### Fields

§`source: ExprId`
§

### WrapUnsafeBinder

Construct an unsafe binder, e.g. `wrap_binder(&ref)`.

#### Fields

§`source: ExprId`
§

### Closure(Box<ClosureExpr<'tcx>>)

A closure definition.

§

### Literal

A literal.

#### Fields

§`lit: Lit`
§`neg: bool`
§

### NonHirLiteral

For literals that don’t correspond to anything in the HIR

#### Fields

§`lit: ScalarInt`
§`user_ty: Option<Box<CanonicalUserType<'tcx>>>`
§

### ZstLiteral

A literal of a ZST type.

#### Fields

§`user_ty: Option<Box<CanonicalUserType<'tcx>>>`
§

### NamedConst

Associated constants and named constants

#### Fields

§`def_id: DefId`
§`args: GenericArgsRef<'tcx>`
§`user_ty: Option<Box<CanonicalUserType<'tcx>>>`
§

### ConstParam

#### Fields

§`param: ParamConst`
§`def_id: DefId`
§

### StaticRef

A literal containing the address of a `static`.

This is only distinguished from `Literal` so that we can register some info for diagnostics.

#### Fields

§`alloc_id: AllocId`
§`ty: Ty<'tcx>`
§`def_id: DefId`
§

### InlineAsm(Box<InlineAsmExpr<'tcx>>)

Inline assembly, i.e. `asm!()`.

§

### ThreadLocalRef(DefId)

An expression taking a reference to a thread local.

§

### Yield

A `yield` expression.

#### Fields

§`value: ExprId`
§

### Reborrow

Use of an ADT that implements the Reborrow (for Mut) or CoerceShared traits (for Not). This expression is produced by the `Adjust::GenericReborrow` in places where normally the ADT would be moved or assigned over. Instead, this produces an `Rvalue::Reborrow` which produces a bitwise copy of the source ADT and disables the source for the copy’s lifetime.

#### Fields

§`source: ExprId`
§`mutability: Mutability`
§`target: Ty<'tcx>`

## Trait Implementations§

Source§

### impl<'tcx> Clone for ExprKind<'tcx>

Source§

#### fn clone(&self) -> ExprKind<'tcx>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

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

### impl<'tcx> Debug for ExprKind<'tcx>

Source§

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

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

### impl<'tcx> StableHash for ExprKind<'tcx>

Source§

#### fn stable_hash<__Hcx: StableHashCtxt>( &self, __hcx: &mut __Hcx, __hasher: &mut StableHasher, )

## Auto Trait Implementations§

§

### impl<'tcx> !RefUnwindSafe for ExprKind<'tcx>

§

### impl<'tcx> !UnwindSafe for ExprKind<'tcx>

§

### impl<'tcx> DynSend for ExprKind<'tcx>

§

### impl<'tcx> DynSync for ExprKind<'tcx>

§

### impl<'tcx> Freeze for ExprKind<'tcx>

§

### impl<'tcx> Send for ExprKind<'tcx>

§

### impl<'tcx> Sync for ExprKind<'tcx>

§

### impl<'tcx> Unpin for ExprKind<'tcx>

§

### impl<'tcx> UnsafeUnpin for ExprKind<'tcx>

## 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> 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<'tcx, T> DepNodeKey<'tcx> for T
where T: StableHash + 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<T> ErasedDestructor for T
where T: 'static,

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

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

Size for each variant:

- `Scope`: 23 bytes
- `If`: 23 bytes
- `Call`: 39 bytes
- `ByUse`: 15 bytes
- `Deref`: 7 bytes
- `Binary`: 11 bytes
- `LogicalOp`: 11 bytes
- `Unary`: 7 bytes
- `Cast`: 7 bytes
- `Use`: 7 bytes
- `NeverToAny`: 7 bytes
- `PointerCoercion`: 7 bytes
- `Loop`: 7 bytes
- `LoopMatch`: 23 bytes
- `Let`: 15 bytes
- `Match`: 31 bytes
- `Block`: 7 bytes
- `Assign`: 11 bytes
- `AssignOp`: 11 bytes
- `Field`: 15 bytes
- `Index`: 11 bytes
- `VarRef`: 11 bytes
- `UpvarRef`: 19 bytes
- `Borrow`: 7 bytes
- `RawBorrow`: 7 bytes
- `Break`: 15 bytes
- `Continue`: 11 bytes
- `ConstContinue`: 15 bytes
- `Return`: 7 bytes
- `Become`: 7 bytes
- `ConstBlock`: 23 bytes
- `Repeat`: 15 bytes
- `Array`: 23 bytes
- `Tuple`: 23 bytes
- `Adt`: 15 bytes
- `PlaceTypeAscription`: 23 bytes
- `ValueTypeAscription`: 23 bytes
- `PlaceUnwrapUnsafeBinder`: 7 bytes
- `ValueUnwrapUnsafeBinder`: 7 bytes
- `WrapUnsafeBinder`: 7 bytes
- `Closure`: 15 bytes
- `Literal`: 39 bytes
- `NonHirLiteral`: 31 bytes
- `ZstLiteral`: 15 bytes
- `NamedConst`: 31 bytes
- `ConstParam`: 19 bytes
- `StaticRef`: 31 bytes
- `InlineAsm`: 15 bytes
- `ThreadLocalRef`: 11 bytes
- `Yield`: 7 bytes
- `Reborrow`: 15 bytes