Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion compiler/rustc_macros/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,14 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
$macro!(#feedable_queries);
}
}
pub mod descs {

/// Functions that format a human-readable description of each query
/// and its key, as specified by the `desc` query modifier.
///
/// (The leading `_` avoids collisions with actual query names when
/// expanded in `rustc_middle::queries`, and makes this macro-generated
/// module easier to search for.)
pub mod _description_fns {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the leading _?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a comment to explain my two reasons:

  • It reduces the possibility of colliding with the name of an actual query when expanded inside rustc_middle::queries.
  • It reduces the possibility of colliding with other identifier names when searching, which is handy for macro-generated code.
    • This is not such a big deal with the new, more verbose name, but it was a recurring hassle when the module was named descs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

use super::*;
#query_description_stream
}
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_middle/src/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ pub type IsLoadableFromDiskFn<'tcx, Key> =

/// Stores function pointers and other metadata for a particular query.
///
/// Used indirectly by query plumbing in `rustc_query_system`, via a trait.
/// Used indirectly by query plumbing in `rustc_query_system` via a trait,
/// and also used directly by query plumbing in `rustc_query_impl`.
pub struct QueryVTable<'tcx, C: QueryCache> {
pub name: &'static str,
pub eval_always: bool,
Expand All @@ -52,6 +53,12 @@ pub struct QueryVTable<'tcx, C: QueryCache> {
pub value_from_cycle_error:
fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value,
pub format_value: fn(&C::Value) -> String,

/// Formats a human-readable description of this query and its key, as
/// specified by the `desc` query modifier.
///
/// Used when reporting query cycle errors and similar problems.
pub description_fn: fn(TyCtxt<'tcx>, C::Key) -> String,
}

pub struct QuerySystemFns {
Expand Down
63 changes: 31 additions & 32 deletions compiler/rustc_query_impl/src/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_data_structures::unord::UnordMap;
use rustc_hashes::Hash64;
use rustc_hir::def_id::DefId;
use rustc_hir::limit::Limit;
use rustc_index::Idx;
use rustc_middle::bug;
use rustc_middle::dep_graph::{
self, DepContext, DepKind, DepKindVTable, DepNode, DepNodeIndex, SerializedDepNodeIndex,
dep_kinds,
self, DepContext, DepKindVTable, DepNode, DepNodeIndex, SerializedDepNodeIndex, dep_kinds,
};
use rustc_middle::query::Key;
use rustc_middle::query::on_disk_cache::{
AbsoluteBytePos, CacheDecoder, CacheEncoder, EncodedDepNodeIndex,
};
use rustc_middle::query::plumbing::QueryVTable;
use rustc_middle::ty::codec::TyEncoder;
use rustc_middle::ty::print::with_reduced_queries;
use rustc_middle::ty::tls::{self, ImplicitCtxt};
Expand Down Expand Up @@ -312,37 +313,36 @@ macro_rules! should_ever_cache_on_disk {
};
}

fn mk_query_stack_frame_extra<'tcx, K: Key + Copy + 'tcx>(
(tcx, key, kind, name, do_describe): (
TyCtxt<'tcx>,
K,
DepKind,
&'static str,
fn(TyCtxt<'tcx>, K) -> String,
),
) -> QueryStackFrameExtra {
/// 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!(do_describe(tcx, key));
let description = ty::print::with_no_queries!((vtable.description_fn)(tcx, key));
let description = if tcx.sess.verbose_internals() {
format!("{description} [{name:?}]")
format!("{description} [{name:?}]", name = vtable.name)
} else {
description
};
let span = if kind == dep_graph::dep_kinds::def_span || reduce_queries {
let span = if vtable.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))
};

let def_kind = if kind == dep_graph::dep_kinds::def_kind || reduce_queries {
let def_kind = if vtable.dep_kind == dep_graph::dep_kinds::def_kind || reduce_queries {
// Try to avoid infinite recursion.
None
} else {
Expand All @@ -351,29 +351,28 @@ fn mk_query_stack_frame_extra<'tcx, K: Key + Copy + 'tcx>(
QueryStackFrameExtra::new(description, span, def_kind)
}

pub(crate) fn create_query_frame<
'tcx,
K: Copy + DynSend + DynSync + Key + for<'a> HashStable<StableHashingContext<'a>> + 'tcx,
>(
pub(crate) fn create_deferred_query_stack_frame<'tcx, Cache>(
tcx: TyCtxt<'tcx>,
do_describe: fn(TyCtxt<'tcx>, K) -> String,
key: K,
kind: DepKind,
name: &'static str,
) -> QueryStackFrame<QueryStackDeferred<'tcx>> {
let def_id = key.key_as_def_id();
vtable: &'tcx QueryVTable<'tcx, Cache>,
key: Cache::Key,
) -> QueryStackFrame<QueryStackDeferred<'tcx>>
where
Cache: QueryCache,
Cache::Key: Key + DynSend + DynSync + for<'a> HashStable<StableHashingContext<'a>> + 'tcx,
{
let kind = vtable.dep_kind;

let hash = tcx.with_stable_hashing_context(|mut hcx| {
let mut hasher = StableHasher::new();
kind.as_usize().hash_stable(&mut hcx, &mut hasher);
key.hash_stable(&mut hcx, &mut hasher);
hasher.finish::<Hash64>()
});
let def_id_for_ty_in_cycle = key.def_id_for_ty_in_cycle();

let info =
QueryStackDeferred::new((tcx, key, kind, name, do_describe), mk_query_stack_frame_extra);
let def_id: Option<DefId> = key.key_as_def_id();
let def_id_for_ty_in_cycle: Option<DefId> = key.def_id_for_ty_in_cycle();

let info = QueryStackDeferred::new((tcx, vtable, key), mk_query_stack_frame_extra);
QueryStackFrame::new(info, kind, hash, def_id, def_id_for_ty_in_cycle)
}

Expand Down Expand Up @@ -697,6 +696,7 @@ macro_rules! define_queries {
},
hash_result: hash_result!([$($modifiers)*][queries::$name::Value<'tcx>]),
format_value: |value| format!("{:?}", erase::restore_val::<queries::$name::Value<'tcx>>(*value)),
description_fn: $crate::queries::_description_fns::$name,
}
}

Expand Down Expand Up @@ -742,10 +742,9 @@ macro_rules! define_queries {
qmap: &mut QueryMap<'tcx>,
require_complete: bool,
) -> Option<()> {
let make_frame = |tcx, key| {
let kind = rustc_middle::dep_graph::dep_kinds::$name;
let name = stringify!($name);
$crate::plumbing::create_query_frame(tcx, queries::descs::$name, key, kind, name)
let make_frame = |tcx: TyCtxt<'tcx>, key| {
let vtable = &tcx.query_system.query_vtables.$name;
$crate::plumbing::create_deferred_query_stack_frame(tcx, vtable, key)
};

// Call `gather_active_jobs_inner` to do the actual work.
Expand Down
Loading