Struct rustc_query_system::dep_graph::dep_node::DepKindStruct

source ·
pub struct DepKindStruct<Tcx: DepContext> {
    pub is_anon: bool,
    pub is_eval_always: bool,
    pub fingerprint_style: FingerprintStyle,
    pub force_from_dep_node: Option<fn(tcx: Tcx, dep_node: DepNode) -> bool>,
    pub try_load_from_on_disk_cache: Option<fn(_: Tcx, _: DepNode)>,
    pub name: &'static &'static str,
}
Expand description

This struct stores metadata about each DepKind.

Information is retrieved by indexing the DEP_KINDS array using the integer value of the DepKind. Overall, this allows to implement DepContext using this manual jump table instead of large matches.

Fields§

§is_anon: bool

Anonymous queries cannot be replayed from one compiler invocation to the next. When their result is needed, it is recomputed. They are useful for fine-grained dependency tracking, and caching within one compiler invocation.

§is_eval_always: bool

Eval-always queries do not track their dependencies, and are always recomputed, even if their inputs have not changed since the last compiler invocation. The result is still cached within one compiler invocation.

§fingerprint_style: FingerprintStyle

Whether the query key can be recovered from the hashed fingerprint. See DepNodeParams trait for the behaviour of each key type.

§force_from_dep_node: Option<fn(tcx: Tcx, dep_node: DepNode) -> bool>

The red/green evaluation system will try to mark a specific DepNode in the dependency graph as green by recursively trying to mark the dependencies of that DepNode as green. While doing so, it will sometimes encounter a DepNode where we don’t know if it is red or green and we therefore actually have to recompute its value in order to find out. Since the only piece of information that we have at that point is the DepNode we are trying to re-evaluate, we need some way to re-run a query from just that. This is what force_from_dep_node() implements.

In the general case, a DepNode consists of a DepKind and an opaque GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint is usually constructed by computing a stable hash of the query-key that the DepNode corresponds to. Consequently, it is not in general possible to go back from hash to query-key (since hash functions are not reversible). For this reason force_from_dep_node() is expected to fail from time to time because we just cannot find out, from the DepNode alone, what the corresponding query-key is and therefore cannot re-run the query.

The system deals with this case letting try_mark_green fail which forces the root query to be re-evaluated.

Now, if force_from_dep_node() would always fail, it would be pretty useless. Fortunately, we can use some contextual information that will allow us to reconstruct query-keys for certain kinds of DepNodes. In particular, we enforce by construction that the GUID/fingerprint of certain DepNodes is a valid DefPathHash. Since we also always build a huge table that maps every DefPathHash in the current codebase to the corresponding DefId, we have everything we need to re-run the query.

Take the mir_promoted query as an example. Like many other queries, it just has a single parameter: the DefId of the item it will compute the validated MIR for. Now, when we call force_from_dep_node() on a DepNode with kind MirValidated, we know that the GUID/fingerprint of the DepNode is actually a DefPathHash, and can therefore just look up the corresponding DefId in tcx.def_path_hash_to_def_id.

§try_load_from_on_disk_cache: Option<fn(_: Tcx, _: DepNode)>

Invoke a query to put the on-disk cached value in memory.

§name: &'static &'static str

The name of this dep kind.

Auto Trait Implementations§

§

impl<Tcx> Freeze for DepKindStruct<Tcx>

§

impl<Tcx> RefUnwindSafe for DepKindStruct<Tcx>

§

impl<Tcx> Send for DepKindStruct<Tcx>

§

impl<Tcx> Sync for DepKindStruct<Tcx>

§

impl<Tcx> Unpin for DepKindStruct<Tcx>

§

impl<Tcx> UnwindSafe for DepKindStruct<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, 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<T> Filterable for T

source§

fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>

Creates a filterable data provider with the given name for debugging. Read more
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

source§

type Output = T

Should always be Self
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<Tcx, T> Value<Tcx> for T
where Tcx: DepContext,

source§

default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> 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,

source§

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

source§

impl<T> MaybeSendSync for T

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: 32 bytes