Do not hold query key in Query.

This commit is contained in:
Camille GILLOT 2020-12-26 16:36:55 +01:00
parent f96e960ccf
commit 0144d6a3b7
4 changed files with 70 additions and 59 deletions

View file

@ -26,10 +26,9 @@
use rustc_middle::ich::StableHashingContext; use rustc_middle::ich::StableHashingContext;
use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values}; use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values};
use rustc_middle::ty::query::{Providers, QueryEngine}; use rustc_middle::ty::query::{Providers, QueryEngine};
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::{self, TyCtxt};
use rustc_serialize::opaque; use rustc_serialize::opaque;
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
use std::mem;
#[macro_use] #[macro_use]
mod plumbing; mod plumbing;

View file

@ -45,7 +45,7 @@ fn dep_context(&self) -> &Self::DepContext {
} }
impl QueryContext for QueryCtxt<'tcx> { impl QueryContext for QueryCtxt<'tcx> {
type Query = Query<'tcx>; type Query = Query;
fn def_path_str(&self, def_id: DefId) -> String { fn def_path_str(&self, def_id: DefId) -> String {
self.tcx.def_path_str(def_id) self.tcx.def_path_str(def_id)
@ -59,7 +59,7 @@ fn try_collect_active_jobs(
&self, &self,
) -> Option<FxHashMap<QueryJobId<Self::DepKind>, QueryJobInfo<Self::DepKind, Self::Query>>> ) -> Option<FxHashMap<QueryJobId<Self::DepKind>, QueryJobInfo<Self::DepKind, Self::Query>>>
{ {
self.queries.try_collect_active_jobs() self.queries.try_collect_active_jobs(**self)
} }
fn try_load_from_on_disk_cache(&self, dep_node: &DepNode) { fn try_load_from_on_disk_cache(&self, dep_node: &DepNode) {
@ -185,12 +185,12 @@ impl<'tcx> QueryCtxt<'tcx> {
#[cold] #[cold]
pub(super) fn report_cycle( pub(super) fn report_cycle(
self, self,
CycleError { usage, cycle: stack }: CycleError<Query<'tcx>>, CycleError { usage, cycle: stack }: CycleError<Query>,
) -> DiagnosticBuilder<'tcx> { ) -> DiagnosticBuilder<'tcx> {
assert!(!stack.is_empty()); assert!(!stack.is_empty());
let fix_span = |span: Span, query: &Query<'tcx>| { let fix_span = |span: Span, query: &Query| {
self.sess.source_map().guess_head_span(query.default_span(*self, span)) self.sess.source_map().guess_head_span(query.default_span(span))
}; };
// Disable naming impls with types in this path, since that // Disable naming impls with types in this path, since that
@ -204,24 +204,24 @@ pub(super) fn report_cycle(
span, span,
E0391, E0391,
"cycle detected when {}", "cycle detected when {}",
stack[0].query.describe(self) stack[0].query.description
); );
for i in 1..stack.len() { for i in 1..stack.len() {
let query = &stack[i].query; let query = &stack[i].query;
let span = fix_span(stack[(i + 1) % stack.len()].span, query); let span = fix_span(stack[(i + 1) % stack.len()].span, query);
err.span_note(span, &format!("...which requires {}...", query.describe(self))); err.span_note(span, &format!("...which requires {}...", query.description));
} }
err.note(&format!( err.note(&format!(
"...which again requires {}, completing the cycle", "...which again requires {}, completing the cycle",
stack[0].query.describe(self) stack[0].query.description
)); ));
if let Some((span, query)) = usage { if let Some((span, query)) = usage {
err.span_note( err.span_note(
fix_span(span, &query), fix_span(span, &query),
&format!("cycle used when {}", query.describe(self)), &format!("cycle used when {}", query.description),
); );
} }
@ -371,54 +371,58 @@ macro_rules! define_queries {
input: ($(([$($modifiers)*] [$($attr)*] [$name]))*) input: ($(([$($modifiers)*] [$($attr)*] [$name]))*)
} }
#[allow(nonstandard_style)]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Query<$tcx> { pub struct Query {
$($(#[$attr])* $name(query_keys::$name<$tcx>)),* pub name: &'static str,
hash: Fingerprint,
description: String,
span: Option<Span>,
} }
impl<$tcx> Query<$tcx> { impl Query {
pub fn name(&self) -> &'static str { $(#[allow(nonstandard_style)] $(#[$attr])*
match *self { pub fn $name<$tcx>(tcx: QueryCtxt<$tcx>, key: query_keys::$name<$tcx>) -> Self {
$(Query::$name(_) => stringify!($name),)* let kind = dep_graph::DepKind::$name;
} let name = stringify!($name);
} let description = ty::print::with_forced_impl_filename_line(
// Force filename-line mode to avoid invoking `type_of` query.
pub(crate) fn describe(&self, tcx: QueryCtxt<$tcx>) -> String { || queries::$name::describe(tcx, key)
let (r, name) = match *self { );
$(Query::$name(key) => { let description = if tcx.sess.verbose() {
(queries::$name::describe(tcx, key), stringify!($name)) format!("{} [{}]", description, name)
})*
};
if tcx.sess.verbose() {
format!("{} [{}]", r, name)
} else { } else {
r description
} };
} let span = if kind == dep_graph::DepKind::def_span {
// The `def_span` query is used to calculate `default_span`,
// so exit to avoid infinite recursion.
None
} else {
Some(key.default_span(*tcx))
};
let hash = {
let mut hcx = tcx.create_stable_hashing_context();
let mut hasher = StableHasher::new();
std::mem::discriminant(&kind).hash_stable(&mut hcx, &mut hasher);
key.hash_stable(&mut hcx, &mut hasher);
hasher.finish()
};
Self { name, description, span, hash }
})*
// FIXME(eddyb) Get more valid `Span`s on queries. // FIXME(eddyb) Get more valid `Span`s on queries.
pub fn default_span(&self, tcx: TyCtxt<$tcx>, span: Span) -> Span { pub fn default_span(&self, span: Span) -> Span {
if !span.is_dummy() { if !span.is_dummy() {
return span; return span;
} }
// The `def_span` query is used to calculate `default_span`, self.span.unwrap_or(span)
// so exit to avoid infinite recursion.
if let Query::def_span(..) = *self {
return span
}
match *self {
$(Query::$name(key) => key.default_span(tcx),)*
}
} }
} }
impl<'a, $tcx> HashStable<StableHashingContext<'a>> for Query<$tcx> { impl<'a> HashStable<StableHashingContext<'a>> for Query {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
mem::discriminant(self).hash_stable(hcx, hasher); self.hash.hash_stable(hcx, hasher)
match *self {
$(Query::$name(key) => key.hash_stable(hcx, hasher),)*
}
} }
} }
@ -446,7 +450,9 @@ impl<$tcx> QueryAccessors<QueryCtxt<$tcx>> for queries::$name<$tcx> {
type Cache = query_storage::$name<$tcx>; type Cache = query_storage::$name<$tcx>;
#[inline(always)] #[inline(always)]
fn query_state<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryState<crate::dep_graph::DepKind, Query<$tcx>, Self::Key> { fn query_state<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryState<crate::dep_graph::DepKind, Query, Self::Key>
where QueryCtxt<$tcx>: 'a
{
&tcx.queries.$name &tcx.queries.$name
} }
@ -478,7 +484,7 @@ fn hash_result(
fn handle_cycle_error( fn handle_cycle_error(
tcx: QueryCtxt<'tcx>, tcx: QueryCtxt<'tcx>,
error: CycleError<Query<'tcx>> error: CycleError<Query>
) -> Self::Value { ) -> Self::Value {
handle_cycle_error!([$($modifiers)*][tcx, error]) handle_cycle_error!([$($modifiers)*][tcx, error])
} }
@ -581,7 +587,7 @@ pub struct Queries<$tcx> {
$($(#[$attr])* $name: QueryState< $($(#[$attr])* $name: QueryState<
crate::dep_graph::DepKind, crate::dep_graph::DepKind,
Query<$tcx>, Query,
query_keys::$name<$tcx>, query_keys::$name<$tcx>,
>,)* >,)*
} }
@ -599,13 +605,16 @@ pub fn new(
} }
pub(crate) fn try_collect_active_jobs( pub(crate) fn try_collect_active_jobs(
&self &$tcx self,
) -> Option<FxHashMap<QueryJobId<crate::dep_graph::DepKind>, QueryJobInfo<crate::dep_graph::DepKind, Query<$tcx>>>> { tcx: TyCtxt<$tcx>,
) -> Option<FxHashMap<QueryJobId<crate::dep_graph::DepKind>, QueryJobInfo<crate::dep_graph::DepKind, Query>>> {
let tcx = QueryCtxt { tcx, queries: self };
let mut jobs = FxHashMap::default(); let mut jobs = FxHashMap::default();
$( $(
self.$name.try_collect_active_jobs( self.$name.try_collect_active_jobs(
<queries::$name<'tcx> as QueryAccessors<QueryCtxt<'tcx>>>::DEP_KIND, tcx,
dep_graph::DepKind::$name,
Query::$name, Query::$name,
&mut jobs, &mut jobs,
)?; )?;
@ -651,7 +660,7 @@ fn try_print_query_stack(
handler: &Handler, handler: &Handler,
num_frames: Option<usize>, num_frames: Option<usize>,
) -> usize { ) -> usize {
let query_map = self.try_collect_active_jobs(); let query_map = self.try_collect_active_jobs(tcx);
let mut current_query = query; let mut current_query = query;
let mut i = 0; let mut i = 0;
@ -671,8 +680,8 @@ fn try_print_query_stack(
&format!( &format!(
"#{} [{}] {}", "#{} [{}] {}",
i, i,
query_info.info.query.name(), query_info.info.query.name,
query_info.info.query.describe(QueryCtxt { tcx, queries: self }) query_info.info.query.description,
), ),
); );
diag.span = tcx.sess.source_map().guess_head_span(query_info.info.span).into(); diag.span = tcx.sess.source_map().guess_head_span(query_info.info.span).into();

View file

@ -73,7 +73,9 @@ pub trait QueryAccessors<CTX: QueryContext>: QueryConfig {
type Cache: QueryCache<Key = Self::Key, Stored = Self::Stored, Value = Self::Value>; type Cache: QueryCache<Key = Self::Key, Stored = Self::Stored, Value = Self::Value>;
// Don't use this method to access query results, instead use the methods on TyCtxt // Don't use this method to access query results, instead use the methods on TyCtxt
fn query_state<'a>(tcx: CTX) -> &'a QueryState<CTX::DepKind, CTX::Query, Self::Key>; fn query_state<'a>(tcx: CTX) -> &'a QueryState<CTX::DepKind, CTX::Query, Self::Key>
where
CTX: 'a;
// Don't use this method to access query results, instead use the methods on TyCtxt // Don't use this method to access query results, instead use the methods on TyCtxt
fn query_cache<'a>(tcx: CTX) -> &'a QueryCacheStore<Self::Cache> fn query_cache<'a>(tcx: CTX) -> &'a QueryCacheStore<Self::Cache>

View file

@ -119,10 +119,11 @@ pub fn all_inactive(&self) -> bool {
shards.iter().all(|shard| shard.active.is_empty()) shards.iter().all(|shard| shard.active.is_empty())
} }
pub fn try_collect_active_jobs( pub fn try_collect_active_jobs<CTX: Copy>(
&self, &self,
tcx: CTX,
kind: D, kind: D,
make_query: fn(K) -> Q, make_query: fn(CTX, K) -> Q,
jobs: &mut QueryMap<D, Q>, jobs: &mut QueryMap<D, Q>,
) -> Option<()> { ) -> Option<()> {
// We use try_lock_shards here since we are called from the // We use try_lock_shards here since we are called from the
@ -133,7 +134,7 @@ pub fn try_collect_active_jobs(
shard.active.iter().filter_map(move |(k, v)| { shard.active.iter().filter_map(move |(k, v)| {
if let QueryResult::Started(ref job) = *v { if let QueryResult::Started(ref job) = *v {
let id = QueryJobId::new(job.id, shard_id, kind); let id = QueryJobId::new(job.id, shard_id, kind);
let info = QueryInfo { span: job.span, query: make_query(k.clone()) }; let info = QueryInfo { span: job.span, query: make_query(tcx, k.clone()) };
Some((id, QueryJobInfo { info, job: job.clone() })) Some((id, QueryJobInfo { info, job: job.clone() }))
} else { } else {
None None