RegionKind in rustc_type_ir::region_kind - Rust
Description: Representation of regions. Note that the NLL checker uses a distinct representation of regions. For this reason, it internally replaces all the regions with inference variables – the index of the variable is then used to index into internal NLL data structures. See `rustc_const_eval::borrow_check` module for more information.

Skip to main content

## RegionKind

# Enum RegionKind

Source

    pub enum RegionKind<I: Interner> {
        ReEarlyParam(I::EarlyParamRegion),
        ReBound(BoundVarIndexKind, BoundRegion<I>),
        ReLateParam(I::LateParamRegion),
        ReStatic,
        ReVar(RegionVid),
        RePlaceholder(PlaceholderRegion<I>),
        ReErased,
        ReError(I::ErrorGuaranteed),
    }

Expand description

Representation of regions. Note that the NLL checker uses a distinct representation of regions. For this reason, it internally replaces all the regions with inference variables – the index of the variable is then used to index into internal NLL data structures. See `rustc_const_eval::borrow_check` module for more information.

Note: operations are on the wrapper `Region` type, which is interned, rather than this type.

### §The Region lattice within a given function

In general, the region lattice looks like

    empty(Un) --------                      (smallest)
    |                 \
    ...                \
    |                   \
    empty(U1) --         \
    |           \         placeholder(Un)
    |            \                  |
    empty(root)   placeholder(U1)   |
    |                |              |
    |                |              |
    |                |              |
    param regions    |              |
    |                |              |
    static ----------+-----...------+       (greatest)

Lifetimes in scope from a function declaration are represented via `RegionKind::ReEarlyParam`/`RegionKind::ReLateParam`. They have relationships to one another and `'static` based on the declared relationships from the function.

Note that inference variables and bound regions are not included in this diagram. In the case of inference variables, they should be inferred to some other region from the diagram. In the case of bound regions, they are excluded because they don’t make sense to include – the diagram indicates the relationship between free regions.

You can read more about the distinction between early and late bound parameters in the rustc dev guide: Early vs Late bound parameters.

A note on subtyping: If we assume that references take their region covariantly, and use that to define the subtyping relationship of regions, it may be somewhat surprising that `'empty` is Top and `'static` is Bottom, and that “`'a` is a subtype of `'b`” is defined as “`'a` is bigger than `'b`” - good to keep in mind.

### §Inference variables

During region inference, we sometimes create inference variables, represented as `RegionKind::ReVar`. These will be inferred by the code in `infer::lexical_region_resolve` to some free region from the lattice above (the minimal region that meets the constraints).

During NLL checking, where regions are defined differently, we also use `RegionKind::ReVar` – in that case, the index is used to index into the NLL region checker’s data structures. The variable may in fact represent either a free region or an inference variable, in that case.

### §Bound Regions

These are regions that are stored behind a binder and must be instantiated with some concrete region before being used. A type can be wrapped in a `Binder`, which introduces new type/const/lifetime variables (e.g., `for<'a> fn(&'a ())`). These parameters are referred to via `RegionKind::ReBound`. You can instantiate them by the likes of `liberate_late_bound_regions`.

Unlike `Param`s, bound regions are not supposed to exist “in the wild” outside their binder, e.g., in types passed to type inference, and should first be instantiated (by placeholder regions, free regions, or region variables).

### §Placeholder and Free Regions

One often wants to work with bound regions without knowing their precise identity. For example, when checking a function, the lifetime of a borrow can end up being assigned to some region parameter. In these cases, it must be ensured that bounds on the region can’t be accidentally assumed without being checked.

To do this, we replace the bound regions with placeholder markers, which don’t satisfy any relation not explicitly provided.

There are two kinds of placeholder regions in rustc: `ReLateParam` and `RePlaceholder`. When checking an item’s body, `ReLateParam` is supposed to be used. These also support explicit bounds: both the internally-stored scope, which the region is assumed to outlive, as well as other relations stored in the `FreeRegionMap`. Note that these relations aren’t checked when you `make_subregion` (or `eq_types`), only by `resolve_regions_and_report_errors`.

When working with higher-ranked types, some region relations aren’t yet known, so you can’t just call `resolve_regions_and_report_errors`. `RePlaceholder` is designed for this purpose. In these contexts, there’s also the risk that some inference variable laying around will get unified with your placeholder region: if you want to check whether `for<'a> Foo<'_>: 'a`, and you instantiate your bound region `'a` with a placeholder region `'%a`, the variable `'_` would just be instantiated to the placeholder region `'%a`, which is wrong because the inference variable is supposed to satisfy the relation for every value of the placeholder region. To ensure that doesn’t happen, you can use `leak_check`. This is more clearly explained by the rustc dev guide.

## Variants§

§

### ReEarlyParam(I::EarlyParamRegion)

A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`.

There are some important differences between region and type parameters. Not all region parameters in the source are represented via `ReEarlyParam`: late-bound function parameters are instead lowered to a `ReBound`. Late-bound regions get eagerly replaced with `ReLateParam` which behaves in the same way as `ReEarlyParam`. Region parameters are also sometimes implicit, e.g. in `impl Trait for &()`.

§

### ReBound(BoundVarIndexKind, BoundRegion<I>)

A higher-ranked region. These represent either late-bound function parameters or bound variables from a `for<'a>`-binder.

While inside of a function, e.g. during typeck, the late-bound function parameters can be converted to `ReLateParam` by calling `tcx.liberate_late_bound_regions`.

Bound regions inside of types must not be erased, as they impact trait selection and the `TypeId` of that type. `for<'a> fn(&'a ())` and `fn(&'static ())` are different types and have to be treated as such.

§

### ReLateParam(I::LateParamRegion)

Late-bound function parameters are represented using a `ReBound`. When inside of a function, we convert these bound variables to placeholder parameters via `tcx.liberate_late_bound_regions`. They are then treated the same way as `ReEarlyParam` while inside of the function.

See https://rustc-dev-guide.rust-lang.org/early_late_parameters.html for more info about early and late bound lifetime parameters.

§

### ReStatic

Static data that has an “infinite” lifetime. Bottom in the region lattice.

§

### ReVar(RegionVid)

A region variable. Should not exist outside of type inference.

§

### RePlaceholder(PlaceholderRegion<I>)

A placeholder region – the higher-ranked version of `ReLateParam`. Should not exist outside of type inference.

Used when instantiating a `forall` binder via `infcx.enter_forall`.

§

### ReErased

Erased region, used by trait selection, in MIR and during codegen.

§

### ReError(I::ErrorGuaranteed)

A region that resulted from some other error. Used exclusively for diagnostics.

## Trait Implementations§

Source§

### impl<I> Clone for RegionKind<I>
where I: Interner,

Source§

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

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<I> Copy for RegionKind<I>
where I: Interner,

Source§

### impl<I: Interner> Debug for RegionKind<I>

Source§

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

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

### impl<I: Interner, __D: Decoder> Decodable<__D> for RegionKind<I>
where I::EarlyParamRegion: Decodable<__D>, BoundRegion<I>: Decodable<__D>, I::LateParamRegion: Decodable<__D>, PlaceholderRegion<I>: Decodable<__D>, I::ErrorGuaranteed: Decodable<__D>,

Source§

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

Source§

### impl<I: Interner, __E: Encoder> Encodable<__E> for RegionKind<I>
where I::EarlyParamRegion: Encodable<__E>, BoundRegion<I>: Encodable<__E>, I::LateParamRegion: Encodable<__E>, PlaceholderRegion<I>: Encodable<__E>, I::ErrorGuaranteed: Encodable<__E>,

Source§

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

Source§

### impl<I: Interner> Eq for RegionKind<I>

Source§

### impl<I> Hash for RegionKind<I>
where I: Interner,

Source§

#### fn hash<__H: Hasher>(&self, __state: &mut __H)

Feeds this value into the given `Hasher`. Read more
1.3.0 · Source§

#### fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given `Hasher`. Read more
Source§

### impl<I> PartialEq for RegionKind<I>
where I: Interner,

Source§

#### fn eq(&self, __other: &Self) -> bool

Tests for `self` and `other` values to be equal, and is used by `==`.
1.0.0 (const: unstable) · 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<I: Interner> StableHash for RegionKind<I>
where I::EarlyParamRegion: StableHash, I::LateParamRegion: StableHash, I::DefId: StableHash, I::Symbol: StableHash,

Available on crate feature `nightly` only.
Source§

#### fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )

## Auto Trait Implementations§

§

### impl<I> DynSend for RegionKind<I>
where <I as Interner>::EarlyParamRegion: DynSend, <I as Interner>::LateParamRegion: DynSend, <I as Interner>::ErrorGuaranteed: DynSend, <I as Interner>::Symbol: DynSend, <I as Interner>::DefId: DynSend,

§

### impl<I> DynSync for RegionKind<I>
where <I as Interner>::EarlyParamRegion: DynSync, <I as Interner>::LateParamRegion: DynSync, <I as Interner>::ErrorGuaranteed: DynSync, <I as Interner>::Symbol: DynSync, <I as Interner>::DefId: DynSync,

§

### impl<I> Freeze for RegionKind<I>
where <I as Interner>::EarlyParamRegion: Freeze, <I as Interner>::LateParamRegion: Freeze, <I as Interner>::ErrorGuaranteed: Freeze, <I as Interner>::Symbol: Freeze, <I as Interner>::DefId: Freeze,

§

### impl<I> RefUnwindSafe for RegionKind<I>
where <I as Interner>::EarlyParamRegion: RefUnwindSafe, <I as Interner>::LateParamRegion: RefUnwindSafe, <I as Interner>::ErrorGuaranteed: RefUnwindSafe, <I as Interner>::Symbol: RefUnwindSafe, <I as Interner>::DefId: RefUnwindSafe,

§

### impl<I> Send for RegionKind<I>
where <I as Interner>::EarlyParamRegion: Send, <I as Interner>::LateParamRegion: Send, <I as Interner>::ErrorGuaranteed: Send, <I as Interner>::Symbol: Send, <I as Interner>::DefId: Send,

§

### impl<I> Sync for RegionKind<I>
where <I as Interner>::EarlyParamRegion: Sync, <I as Interner>::LateParamRegion: Sync, <I as Interner>::ErrorGuaranteed: Sync, <I as Interner>::Symbol: Sync, <I as Interner>::DefId: Sync,

§

### impl<I> Unpin for RegionKind<I>
where <I as Interner>::EarlyParamRegion: Unpin, <I as Interner>::LateParamRegion: Unpin, <I as Interner>::ErrorGuaranteed: Unpin, <I as Interner>::Symbol: Unpin, <I as Interner>::DefId: Unpin,

§

### impl<I> UnsafeUnpin for RegionKind<I>
where <I as Interner>::EarlyParamRegion: UnsafeUnpin, <I as Interner>::LateParamRegion: UnsafeUnpin, <I as Interner>::ErrorGuaranteed: UnsafeUnpin, <I as Interner>::Symbol: UnsafeUnpin, <I as Interner>::DefId: UnsafeUnpin,

§

### impl<I> UnwindSafe for RegionKind<I>
where <I as Interner>::EarlyParamRegion: UnwindSafe, <I as Interner>::LateParamRegion: UnwindSafe, <I as Interner>::ErrorGuaranteed: UnwindSafe, <I as Interner>::Symbol: UnwindSafe, <I as Interner>::DefId: UnwindSafe,

## Blanket Implementations§

§

### impl<T> Aligned for T

§

#### 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<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> 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> 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<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: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.