Repository: rust-lang/rust
File: compiler/rustc_query_impl/src/plumbing.rs (Rust)

Code before:
    ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => {
        if_cache_on_disk!([$($modifiers)*] $yes $no)
    };
}

/// Conditionally expands to some token trees, if the current query has the
/// `cache_on_disk_if` modifier.
macro_rules! item_if_cache_on_disk {
    ([] $($item:tt)*) => {};
    ([(cache_on_disk) $($rest:tt)*] $($item:tt)*) => {
        $($item)*
    };
    ([$other:tt $($modifiers:tt)*] $($item:tt)*) => {
        item_if_cache_on_disk! { [$($modifiers)*] $($item)* }
    };
}

/// The deferred part of a deferred query stack frame.
fn mk_query_stack_frame_extra<'tcx, K>(
    (tcx, name, dep_kind, description_fn, key): (
        TyCtxt<'tcx>,
        &'static str,
        DepKind,
        fn(TyCtxt<'tcx>, K) -> String,
        K,
    ),
) -> QueryStackFrameExtra
where
    K: Key + Copy,
{
    let def_id = key.key_as_def_id();

    // If reduced queries are requested, we may be printing a query stack due
    // to a panic. Avoid using `default_span` and `def_kind` in that case.
    let reduce_queries = with_reduced_queries();

    // Avoid calling queries while formatting the description
    let description = ty::print::with_no_queries!(description_fn(tcx, key));
    let description = if tcx.sess.verbose_internals() {
        format!("{description} [{name:?}]")
    } else {
        description
    };
    let span = if dep_kind == dep_graph::dep_kinds::def_span || reduce_queries {
        // The `def_span` query is used to calculate `default_span`,
        // so exit to avoid infinite recursion.
        None
    } else {
        Some(key.default_span(tcx))
    };


Review comment (performance):
Suggestion: Based on my local testing, I think this entire commit can be avoided by just adding a `QueryVTable<'tcx, C>: DynSync` bound to `create_deferred_query_stack_frame`.

(This makes sense because the state and cache *should* be `DynSync`, and the caller knows that this happens to be true of every concrete state and cache.)

Code after:

/// Conditionally expands to some token trees, if the current query has the
/// `cache_on_disk_if` modifier.
macro_rules! item_if_cache_on_disk {
    ([] $($item:tt)*) => {};
    ([(cache_on_disk) $($rest:tt)*] $($item:tt)*) => {
        $($item)*
    };
    ([$other:tt $($modifiers:tt)*] $($item:tt)*) => {
        item_if_cache_on_disk! { [$($modifiers)*] $($item)* }
    };
}

/// The deferred part of a deferred query stack frame.
fn mk_query_stack_frame_extra<'tcx, Cache>(
    (tcx, vtable, key): (TyCtxt<'tcx>, &'tcx QueryVTable<'tcx, Cache>, Cache::Key),
) -> QueryStackFrameExtra
where
    Cache: QueryCache,
    Cache::Key: Key,
{
    let def_id = key.key_as_def_id();

    // If reduced queries are requested, we may be printing a query stack due
    // to a panic. Avoid using `default_span` and `def_kind` in that case.
    let reduce_queries = with_reduced_queries();

    // Avoid calling queries while formatting the description
    let description = ty::print::with_no_queries!((vtable.description_fn)(tcx, key));
    let description = if tcx.sess.verbose_internals() {
        format!("{description} [{name:?}]", name = vtable.name)
    } else {
        description
    };
    let span = if vtable.dep_kind == DepKind::def_span || reduce_queries {
        // The `def_span` query is used to calculate `default_span`,
        // so exit to avoid infinite recursion.
        None
    } else {
        Some(key.default_span(tcx))
    };

    let def_kind = if vtable.dep_kind == DepKind::def_kind || reduce_queries {
        // Try to avoid infinite recursion.
        None
    } else {
        def_id.and_then(|def_id| def_id.as_local()).map(|def_id| tcx.def_kind(def_id))
    };
    QueryStackFrameExtra::new(description, span, def_kind)
}