## TypingMode

# Enum TypingMode

    pub enum TypingMode<I>where
        I: Interner,{
        Coherence,
        Analysis {
            defining_opaque_types_and_generators: <I as Interner>::LocalDefIds,
        },
        Borrowck {
            defining_opaque_types: <I as Interner>::LocalDefIds,
        },
        PostBorrowckAnalysis {
            defined_opaque_types: <I as Interner>::LocalDefIds,
        },
        PostAnalysis,
    }

Expand description

The current typing mode of an inference context. We unfortunately have some slightly different typing rules depending on the current context. See the doc comment for each variant for how and why they are used.

In most cases you can get the correct typing mode automatically via:

- `mir::Body::typing_mode`
- `rustc_lint::LateContext::typing_mode`

If neither of these functions are available, feel free to reach out to t-types for help.

## Variants§

§

### Coherence

When checking whether impls overlap, we check whether any obligations are guaranteed to never hold when unifying the impls. This requires us to be complete: we must never fail to prove something which may actually hold.

In this typing mode we bail with ambiguity in case its not knowable whether a trait goal may hold, e.g. because the trait may get implemented in a downstream or sibling crate.

We also have to be careful when generalizing aliases inside of higher-ranked types to not unnecessarily constrain any inference variables.

§

### Analysis

Analysis includes type inference, checking that items are well-formed, and pretty much everything else which may emit proper type errors to the user.

We only normalize opaque types which may get defined by the current body, which are stored in `defining_opaque_types`.

We also refuse to project any associated type that is marked `default`. Non-`default` (“final”) types are always projected. This is necessary in general for soundness of specialization. However, we could allow projections in fully-monomorphic cases. We choose not to, because we prefer for `default type` to force the type definition to be treated abstractly by any consumers of the impl. Concretely, that means that the following example will fail to compile:

ⓘ

    #![feature(specialization)]
    trait Assoc {
        type Output;
    }

    impl<T> Assoc for T {
        default type Output = bool;
    }

    fn main() {
        let x: <() as Assoc>::Output = true;
    }

#### Fields

§`defining_opaque_types_and_generators: <I as Interner>::LocalDefIds`
§

### Borrowck

The behavior during MIR borrowck is identical to `TypingMode::Analysis` except that the initial value for opaque types is the type computed during HIR typeck with unique unconstrained region inference variables.

This is currently only used with by the new solver as it results in new non-universal defining uses of opaque types, which is a breaking change. See tests/ui/impl-trait/non-defining-use/as-projection-term.rs.

#### Fields

§`defining_opaque_types: <I as Interner>::LocalDefIds`
§

### PostBorrowckAnalysis

Any analysis after borrowck for a given body should be able to use all the hidden types defined by borrowck, without being able to define any new ones.

This is currently only used by the new solver, but should be implemented in the old solver as well.

#### Fields

§`defined_opaque_types: <I as Interner>::LocalDefIds`
§

### PostAnalysis

After analysis, mostly during codegen and MIR optimizations, we’re able to reveal all opaque types. As the hidden type should never be observable directly by the user, this should not be used by checks which may expose such details to the user.

There are some exceptions to this as for example `layout_of` and const-evaluation always run in `PostAnalysis` mode, even when used during analysis. This exposes some information about the underlying type to users, but not the type itself.

## Implementations§

§

### impl<I> TypingMode<I>
where I: Interner,

#### pub fn non_body_analysis() -> TypingMode<I>

Analysis outside of a body does not define any opaque types.

#### pub fn typeck_for_body( cx: I, body_def_id: <I as Interner>::LocalDefId, ) -> TypingMode<I>

#### pub fn analysis_in_body( cx: I, body_def_id: <I as Interner>::LocalDefId, ) -> TypingMode<I>

While typechecking a body, we need to be able to define the opaque types defined by that body.

FIXME: This will be removed because it’s generally not correct to define opaques outside of HIR typeck.

#### pub fn borrowck( cx: I, body_def_id: <I as Interner>::LocalDefId, ) -> TypingMode<I>

#### pub fn post_borrowck_analysis( cx: I, body_def_id: <I as Interner>::LocalDefId, ) -> TypingMode<I>

## Trait Implementations§

§

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

§

#### fn clone(&self) -> TypingMode<I>

Returns a duplicate of the value. Read more
1.0.0§

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

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

### impl<I> Debug for TypingMode<I>
where I: Interner,

§

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

Formats the value using the given formatter. Read more
§

### impl<I, __D> Decodable<__D> for TypingMode<I>
where I: Interner, __D: Decoder, <I as Interner>::LocalDefIds: Decodable<__D>,

§

#### fn decode(__decoder: &mut __D) -> TypingMode<I>

§

### impl<I, __E> Encodable<__E> for TypingMode<I>
where I: Interner, __E: Encoder, <I as Interner>::LocalDefIds: Encodable<__E>,

§

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

§

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

§

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

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

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

### impl<I, __CTX> HashStable<__CTX> for TypingMode<I>
where I: Interner, <I as Interner>::LocalDefIds: HashStable<__CTX>,

§

#### fn hash_stable( &self, __hcx: &mut __CTX, __hasher: &mut StableHasher<SipHasher128>, )

§

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

§

#### fn eq(&self, __other: &TypingMode<I>) -> bool

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

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

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

### impl<I> Copy for TypingMode<I>
where I: Interner,

§

### impl<I> Eq for TypingMode<I>
where I: Interner,

## Auto Trait Implementations§

§

### impl<I> DynSend for TypingMode<I>
where <I as Interner>::LocalDefIds: DynSend,

§

### impl<I> DynSync for TypingMode<I>
where <I as Interner>::LocalDefIds: DynSync,

§

### impl<I> Freeze for TypingMode<I>
where <I as Interner>::LocalDefIds: Freeze,

§

### impl<I> RefUnwindSafe for TypingMode<I>
where <I as Interner>::LocalDefIds: RefUnwindSafe,

§

### impl<I> Send for TypingMode<I>
where <I as Interner>::LocalDefIds: Send,

§

### impl<I> Sync for TypingMode<I>
where <I as Interner>::LocalDefIds: Sync,

§

### impl<I> Unpin for TypingMode<I>
where <I as Interner>::LocalDefIds: Unpin,

§

### impl<I> UnwindSafe for TypingMode<I>
where <I as Interner>::LocalDefIds: UnwindSafe,

## Blanket Implementations§

§

### impl<T> Aligned for T

§

#### const ALIGN: Alignment

Alignment of `Self`.
§

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

§

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

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

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

§

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

§

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

§

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

§

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

§

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

§

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

§

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

§

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

§

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

§

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

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
§

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

§

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

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

§

#### 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<_>>())`.

§

#### type Output = R

§

### impl<Tcx, T> DepNodeParams<Tcx> for T
where Tcx: DepContext, T: for<'a> HashStable<StableHashingContext<'a>> + Debug,

§

#### default fn fingerprint_style() -> FingerprintStyle

§

#### default fn to_fingerprint(&self, tcx: Tcx) -> Fingerprint

This method turns the parameters of a DepNodeConstructor into an opaque Fingerprint to be used in DepNode. Not all DepNodeParams support being turned into a Fingerprint (they don’t need to if the corresponding DepNode is anonymous).
§

#### default fn to_debug_str(&self, tcx: Tcx) -> String

§

#### default fn recover(_: 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.
§

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

§

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

§

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

§

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

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

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

§

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

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

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

§

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

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

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

§

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

Returns the argument unchanged.

§

### impl<T> Instrument for T

§

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

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

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

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

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

§

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

Calls `U::from(self)`.

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

§

### impl<T> IntoEither for T

§

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

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

### impl<P> IntoQueryParam<P> for P

§

#### fn into_query_param(self) -> P

§

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

§

#### type Error = !

§

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

§

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

§

### impl<T> Pointable for T

§

#### const ALIGN: usize

The alignment of pointer.
§

#### type Init = T

The type for initializers.
§

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

Initializes a with the given initializer. Read more
§

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

Dereferences the given pointer. Read more
§

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

Mutably dereferences the given pointer. Read more
§

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

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

### impl<T> Same for T

§

#### type Output = T

Should always be `Self`
§

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

§

#### type Owned = T

The resulting type after obtaining ownership.
§

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

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

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

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

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

§

#### type Error = Infallible

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

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

Performs the conversion.
§

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

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

Performs the conversion.
§

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

§

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

§

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

§

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

§

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

§

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

§

### impl<Tcx, T> Value<Tcx> for T
where Tcx: DepContext,

§

#### default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> T

§

### impl<T> WithSubscriber for T

§

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

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

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

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

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