Struct rustc_type_ir::search_graph::StackEntry

source ·
struct StackEntry<X: Cx> {
    input: X::Input,
    available_depth: AvailableDepth,
    reached_depth: StackDepth,
    non_root_cycle_participant: Option<StackDepth>,
    encountered_overflow: bool,
    has_been_used: Option<UsageKind>,
    nested_goals: HashSet<X::Input>,
    provisional_result: Option<X::Result>,
}

Fields§

§input: X::Input§available_depth: AvailableDepth§reached_depth: StackDepth

The maximum depth reached by this stack entry, only up-to date for the top of the stack and lazily updated for the rest.

§non_root_cycle_participant: Option<StackDepth>

Whether this entry is a non-root cycle participant.

We must not move the result of non-root cycle participants to the global cache. We store the highest stack depth of a head of a cycle this goal is involved in. This necessary to soundly cache its provisional result.

§encountered_overflow: bool§has_been_used: Option<UsageKind>§nested_goals: HashSet<X::Input>

We put only the root goal of a coinductive cycle into the global cache.

If we were to use that result when later trying to prove another cycle participant, we can end up with unstable query results.

See tests/ui/next-solver/coinduction/incompleteness-unstable-result.rs for an example of where this is needed.

There can be multiple roots on the same stack, so we need to track cycle participants per root:

A :- B
B :- A, C
C :- D
D :- C
§provisional_result: Option<X::Result>

Starts out as None and gets set when rerunning this goal in case we encounter a cycle.

Trait Implementations§

source§

impl<X: Cx> Debug for StackEntry<X>

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<X> Freeze for StackEntry<X>
where <X as Cx>::Input: Freeze, <X as Cx>::Result: Freeze,

§

impl<X> RefUnwindSafe for StackEntry<X>
where <X as Cx>::Input: RefUnwindSafe, <X as Cx>::Result: RefUnwindSafe,

§

impl<X> Send for StackEntry<X>
where <X as Cx>::Input: Send, <X as Cx>::Result: Send,

§

impl<X> Sync for StackEntry<X>
where <X as Cx>::Input: Sync, <X as Cx>::Result: Sync,

§

impl<X> Unpin for StackEntry<X>
where <X as Cx>::Input: Unpin, <X as Cx>::Result: Unpin,

§

impl<X> UnwindSafe for StackEntry<X>
where <X as Cx>::Input: UnwindSafe, <X as Cx>::Result: UnwindSafe,

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

§

type Output = R

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> Same for T

§

type Output = T

Should always be Self
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.
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<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
source§

impl<'a, T> Captures<'a> for T
where T: ?Sized,

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.