diff options
Diffstat (limited to 'compiler/rustc_query_impl/src')
| -rw-r--r-- | compiler/rustc_query_impl/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_query_impl/src/plumbing.rs | 74 |
2 files changed, 62 insertions, 14 deletions
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 33116737a42..52767155532 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -41,7 +41,7 @@ use rustc_span::{ErrorGuaranteed, Span}; #[macro_use] mod plumbing; -pub use crate::plumbing::QueryCtxt; +pub use crate::plumbing::{query_key_hash_verify_all, QueryCtxt}; mod profiling_support; pub use self::profiling_support::alloc_self_profile_query_strings; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 5917d79983d..aa965779731 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -7,7 +7,8 @@ use crate::rustc_middle::ty::TyEncoder; use crate::QueryConfigRestored; use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_data_structures::sync::Lock; -use rustc_errors::Diagnostic; +use rustc_data_structures::unord::UnordMap; +use rustc_errors::DiagInner; use rustc_index::Idx; use rustc_middle::dep_graph::dep_kinds; @@ -17,8 +18,9 @@ use rustc_middle::dep_graph::{ use rustc_middle::query::on_disk_cache::AbsoluteBytePos; use rustc_middle::query::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex}; use rustc_middle::query::Key; +use rustc_middle::ty::print::with_reduced_queries; use rustc_middle::ty::tls::{self, ImplicitCtxt}; -use rustc_middle::ty::{self, print::with_no_queries, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext}; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ @@ -125,7 +127,7 @@ impl QueryContext for QueryCtxt<'_> { self, token: QueryJobId, depth_limit: bool, - diagnostics: Option<&Lock<ThinVec<Diagnostic>>>, + diagnostics: Option<&Lock<ThinVec<DiagInner>>>, compute: impl FnOnce() -> R, ) -> R { // The `TyCtxt` stored in TLS has the same global interner lifetime @@ -188,6 +190,16 @@ pub(super) fn encode_all_query_results<'tcx>( } } +pub fn query_key_hash_verify_all<'tcx>(tcx: TyCtxt<'tcx>) { + if tcx.sess().opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions) { + tcx.sess.time("query_key_hash_verify_all", || { + for verify in super::QUERY_KEY_HASH_VERIFY.iter() { + verify(tcx); + } + }) + } +} + macro_rules! handle_cycle_error { ([]) => {{ rustc_query_system::HandleCycleError::Error @@ -304,21 +316,18 @@ pub(crate) fn create_query_frame< kind: DepKind, name: &'static str, ) -> QueryStackFrame { + // 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!( - // Disable visible paths printing for performance reasons. - // Showing visible path instead of any path is not that important in production. - ty::print::with_no_visible_paths!( - // Force filename-line mode to avoid invoking `type_of` query. - ty::print::with_forced_impl_filename_line!(do_describe(tcx, key)) - ) - ); + let description = ty::print::with_no_queries!(do_describe(tcx, key)); let description = if tcx.sess.verbose_internals() { format!("{description} [{name:?}]") } else { description }; - let span = if kind == dep_graph::dep_kinds::def_span || with_no_queries() { + let span = if 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 @@ -326,7 +335,7 @@ pub(crate) fn create_query_frame< Some(key.default_span(tcx)) }; let def_id = key.key_as_def_id(); - let def_kind = if kind == dep_graph::dep_kinds::def_kind || with_no_queries() { + let def_kind = if kind == dep_graph::dep_kinds::def_kind || reduce_queries { // Try to avoid infinite recursion. None } else { @@ -372,6 +381,34 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q>( }); } +pub(crate) fn query_key_hash_verify<'tcx>( + query: impl QueryConfig<QueryCtxt<'tcx>>, + qcx: QueryCtxt<'tcx>, +) { + let _timer = + qcx.profiler().generic_activity_with_arg("query_key_hash_verify_for", query.name()); + + let mut map = UnordMap::default(); + + let cache = query.query_cache(qcx); + cache.iter(&mut |key, _, _| { + let node = DepNode::construct(qcx.tcx, query.dep_kind(), key); + if let Some(other_key) = map.insert(node, *key) { + bug!( + "query key:\n\ + `{:?}`\n\ + and key:\n\ + `{:?}`\n\ + mapped to the same dep node:\n\ + {:?}", + key, + other_key, + node + ); + } + }); +} + fn try_load_from_on_disk_cache<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) where Q: QueryConfig<QueryCtxt<'tcx>>, @@ -693,6 +730,13 @@ macro_rules! define_queries { ) } }} + + pub fn query_key_hash_verify<'tcx>(tcx: TyCtxt<'tcx>) { + $crate::plumbing::query_key_hash_verify( + query_impl::$name::QueryType::config(tcx), + QueryCtxt::new(tcx), + ) + } })*} pub(crate) fn engine(incremental: bool) -> QueryEngine { @@ -732,6 +776,10 @@ macro_rules! define_queries { > ] = &[$(expand_if_cached!([$($modifiers)*], query_impl::$name::encode_query_results)),*]; + const QUERY_KEY_HASH_VERIFY: &[ + for<'tcx> fn(TyCtxt<'tcx>) + ] = &[$(query_impl::$name::query_key_hash_verify),*]; + #[allow(nonstandard_style)] mod query_callbacks { use super::*; |
