summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_query_impl
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_query_impl')
-rw-r--r--compiler/rustc_query_impl/Cargo.toml4
-rw-r--r--compiler/rustc_query_impl/src/lib.rs10
-rw-r--r--compiler/rustc_query_impl/src/on_disk_cache.rs76
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs447
-rw-r--r--compiler/rustc_query_impl/src/profiling_support.rs12
-rw-r--r--compiler/rustc_query_impl/src/values.rs45
6 files changed, 343 insertions, 251 deletions
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml
index 5673bb83b..e7f12caaf 100644
--- a/compiler/rustc_query_impl/Cargo.toml
+++ b/compiler/rustc_query_impl/Cargo.toml
@@ -8,7 +8,6 @@ doctest = false
[dependencies]
measureme = "10.0.0"
-rustc-rayon-core = { version = "0.4.0", optional = true }
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
@@ -17,9 +16,12 @@ rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_query_system = { path = "../rustc_query_system" }
+rustc-rayon-core = { version = "0.4.0", optional = true }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
+thin-vec = "0.2.8"
tracing = "0.1"
[features]
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index eda61df77..c87d26b39 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -7,16 +7,17 @@
#![feature(rustc_attrs)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_macros;
#[macro_use]
extern crate rustc_middle;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::AtomicU64;
use rustc_middle::arena::Arena;
-use rustc_middle::dep_graph::{self, DepKindStruct, SerializedDepNodeIndex};
+use rustc_middle::dep_graph::{self, DepKindStruct};
use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values};
use rustc_middle::ty::query::{ExternProviders, Providers, QueryEngine};
use rustc_middle::ty::{self, TyCtxt};
@@ -33,9 +34,6 @@ pub use rustc_query_system::query::{deadlock, QueryContext};
mod keys;
use keys::Key;
-mod values;
-use self::values::Value;
-
pub use rustc_query_system::query::QueryConfig;
pub(crate) use rustc_query_system::query::{QueryDescription, QueryVTable};
@@ -53,7 +51,7 @@ fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
}
}
-rustc_query_append! { [define_queries!][<'tcx>] }
+rustc_query_append! { define_queries! }
impl<'tcx> Queries<'tcx> {
// Force codegen in the dyn-trait transformation in this crate.
diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index 56fd90c98..0e93f3ce1 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -22,8 +22,9 @@ use rustc_span::hygiene::{
ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
};
use rustc_span::source_map::{SourceMap, StableSourceFileId};
-use rustc_span::CachingSourceMapView;
use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, SourceFile, Span};
+use rustc_span::{CachingSourceMapView, Symbol};
+use std::collections::hash_map::Entry;
use std::io;
use std::mem;
@@ -38,6 +39,11 @@ const TAG_RELATIVE_SPAN: u8 = 2;
const TAG_SYNTAX_CONTEXT: u8 = 0;
const TAG_EXPN_DATA: u8 = 1;
+// Tags for encoding Symbol's
+const SYMBOL_STR: u8 = 0;
+const SYMBOL_OFFSET: u8 = 1;
+const SYMBOL_PREINTERNED: u8 = 2;
+
/// Provides an interface to incremental compilation data cached from the
/// previous compilation session. This data will eventually include the results
/// of a few selected queries (like `typeck` and `mir_optimized`) and
@@ -254,6 +260,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
source_map: CachingSourceMapView::new(tcx.sess.source_map()),
file_to_file_index,
hygiene_context: &hygiene_encode_context,
+ symbol_table: Default::default(),
};
// Encode query results.
@@ -714,6 +721,40 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
}
}
+// copy&paste impl from rustc_metadata
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Symbol {
+ fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
+ let tag = d.read_u8();
+
+ match tag {
+ SYMBOL_STR => {
+ let s = d.read_str();
+ Symbol::intern(s)
+ }
+ SYMBOL_OFFSET => {
+ // read str offset
+ let pos = d.read_usize();
+ let old_pos = d.opaque.position();
+
+ // move to str ofset and read
+ d.opaque.set_position(pos);
+ let s = d.read_str();
+ let sym = Symbol::intern(s);
+
+ // restore position
+ d.opaque.set_position(old_pos);
+
+ sym
+ }
+ SYMBOL_PREINTERNED => {
+ let symbol_index = d.read_u32();
+ Symbol::new_from_decoded(symbol_index)
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for CrateNum {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
let stable_id = StableCrateId::decode(d);
@@ -757,6 +798,12 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId>
}
}
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashMap<DefId, Ty<'tcx>> {
+ fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
+ RefDecodable::decode(d)
+ }
+}
+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
for &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>>
{
@@ -815,6 +862,7 @@ pub struct CacheEncoder<'a, 'tcx> {
source_map: CachingSourceMapView<'tcx>,
file_to_file_index: FxHashMap<*const SourceFile, SourceFileIndex>,
hygiene_context: &'a HygieneEncodeContext,
+ symbol_table: FxHashMap<Symbol, usize>,
}
impl<'a, 'tcx> CacheEncoder<'a, 'tcx> {
@@ -899,6 +947,32 @@ impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Span {
}
}
+// copy&paste impl from rustc_metadata
+impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Symbol {
+ fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
+ // if symbol preinterned, emit tag and symbol index
+ if self.is_preinterned() {
+ s.encoder.emit_u8(SYMBOL_PREINTERNED);
+ s.encoder.emit_u32(self.as_u32());
+ } else {
+ // otherwise write it as string or as offset to it
+ match s.symbol_table.entry(*self) {
+ Entry::Vacant(o) => {
+ s.encoder.emit_u8(SYMBOL_STR);
+ let pos = s.encoder.position();
+ o.insert(pos);
+ s.emit_str(self.as_str());
+ }
+ Entry::Occupied(o) => {
+ let x = o.get().clone();
+ s.emit_u8(SYMBOL_OFFSET);
+ s.emit_usize(x);
+ }
+ }
+ }
+ }
+}
+
impl<'a, 'tcx> TyEncoder for CacheEncoder<'a, 'tcx> {
type I = TyCtxt<'tcx>;
const CLEAR_CROSS_CRATE: bool = false;
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index eda4401c8..6f39bbfc0 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -2,19 +2,28 @@
//! generate the actual methods on tcx which find and execute the provider,
//! manage the caches, and so forth.
+use crate::keys::Key;
+use crate::on_disk_cache::CacheDecoder;
use crate::{on_disk_cache, Queries};
-use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
-use rustc_middle::ty::tls::{self, ImplicitCtxt};
-use rustc_middle::ty::TyCtxt;
-use rustc_query_system::dep_graph::HasDepContext;
-use rustc_query_system::query::{QueryContext, QueryJobId, QueryMap, QuerySideEffects};
-
-use rustc_data_structures::sync::Lock;
-use rustc_data_structures::thin_vec::ThinVec;
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_data_structures::sync::{AtomicU64, Lock};
use rustc_errors::{Diagnostic, Handler};
-
+use rustc_middle::dep_graph::{
+ self, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex,
+};
+use rustc_middle::ty::tls::{self, ImplicitCtxt};
+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::{
+ force_query, QueryConfig, QueryContext, QueryDescription, QueryJobId, QueryMap,
+ QuerySideEffects, QueryStackFrame,
+};
+use rustc_query_system::Value;
+use rustc_serialize::Decodable;
use std::any::Any;
use std::num::NonZeroU64;
+use thin_vec::ThinVec;
#[derive(Copy, Clone)]
pub struct QueryCtxt<'tcx> {
@@ -91,6 +100,7 @@ impl QueryContext for QueryCtxt<'_> {
fn start_query<R>(
&self,
token: QueryJobId,
+ depth_limit: bool,
diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
compute: impl FnOnce() -> R,
) -> R {
@@ -98,12 +108,16 @@ impl QueryContext for QueryCtxt<'_> {
// as `self`, so we use `with_related_context` to relate the 'tcx lifetimes
// when accessing the `ImplicitCtxt`.
tls::with_related_context(**self, move |current_icx| {
+ if depth_limit && !self.recursion_limit().value_within_limit(current_icx.query_depth) {
+ self.depth_limit_error();
+ }
+
// Update the `ImplicitCtxt` to point to our new query job.
let new_icx = ImplicitCtxt {
tcx: **self,
query: Some(token),
diagnostics,
- layout_depth: current_icx.layout_depth,
+ query_depth: current_icx.query_depth + depth_limit as usize,
task_deps: current_icx.task_deps,
};
@@ -137,19 +151,31 @@ impl<'tcx> QueryCtxt<'tcx> {
encoder: &mut on_disk_cache::CacheEncoder<'_, 'tcx>,
query_result_index: &mut on_disk_cache::EncodedDepNodeIndex,
) {
+ macro_rules! expand_if_cached {
+ ([] $encode:expr) => {};
+ ([(cache) $($rest:tt)*] $encode:expr) => {
+ $encode
+ };
+ ([$other:tt $($modifiers:tt)*] $encode:expr) => {
+ expand_if_cached!([$($modifiers)*] $encode)
+ };
+ }
+
macro_rules! encode_queries {
- ($($query:ident,)*) => {
+ (
+ $($(#[$attr:meta])*
+ [$($modifiers:tt)*] fn $query:ident($($K:tt)*) -> $V:ty,)*) => {
$(
- on_disk_cache::encode_query_results::<_, super::queries::$query<'_>>(
+ expand_if_cached!([$($modifiers)*] on_disk_cache::encode_query_results::<_, super::queries::$query<'_>>(
self,
encoder,
query_result_index
- );
+ ));
)*
}
}
- rustc_cached_queries!(encode_queries!);
+ rustc_query_append!(encode_queries!);
}
pub fn try_print_query_stack(
@@ -163,21 +189,17 @@ impl<'tcx> QueryCtxt<'tcx> {
}
macro_rules! handle_cycle_error {
- ([][$tcx: expr, $error:expr]) => {{
- $error.emit();
- Value::from_cycle_error($tcx)
+ ([]) => {{
+ rustc_query_system::HandleCycleError::Error
}};
- ([(fatal_cycle) $($rest:tt)*][$tcx:expr, $error:expr]) => {{
- $error.emit();
- $tcx.sess.abort_if_errors();
- unreachable!()
+ ([(fatal_cycle) $($rest:tt)*]) => {{
+ rustc_query_system::HandleCycleError::Fatal
}};
- ([(cycle_delay_bug) $($rest:tt)*][$tcx:expr, $error:expr]) => {{
- $error.delay_as_bug();
- Value::from_cycle_error($tcx)
+ ([(cycle_delay_bug) $($rest:tt)*]) => {{
+ rustc_query_system::HandleCycleError::DelayBug
}};
- ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
- handle_cycle_error!([$($modifiers)*][$($args)*])
+ ([$other:tt $($modifiers:tt)*]) => {
+ handle_cycle_error!([$($modifiers)*])
};
}
@@ -205,6 +227,18 @@ macro_rules! is_eval_always {
};
}
+macro_rules! depth_limit {
+ ([]) => {{
+ false
+ }};
+ ([(depth_limit) $($rest:tt)*]) => {{
+ true
+ }};
+ ([$other:tt $($modifiers:tt)*]) => {
+ depth_limit!([$($modifiers)*])
+ };
+}
+
macro_rules! hash_result {
([]) => {{
Some(dep_graph::hash_result)
@@ -233,106 +267,174 @@ macro_rules! get_provider {
};
}
-macro_rules! opt_remap_env_constness {
- ([][$name:ident]) => {};
- ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
- let $name = $name.without_const();
+macro_rules! should_ever_cache_on_disk {
+ ([]) => {{
+ None
+ }};
+ ([(cache) $($rest:tt)*]) => {{
+ Some($crate::plumbing::try_load_from_disk::<Self::Value>)
+ }};
+ ([$other:tt $($modifiers:tt)*]) => {
+ should_ever_cache_on_disk!([$($modifiers)*])
};
- ([$other:tt $($modifiers:tt)*][$name:ident]) => {
- opt_remap_env_constness!([$($modifiers)*][$name])
+}
+
+pub(crate) fn create_query_frame<
+ 'tcx,
+ K: Copy + Key + for<'a> HashStable<StableHashingContext<'a>>,
+>(
+ tcx: QueryCtxt<'tcx>,
+ do_describe: fn(QueryCtxt<'tcx>, K) -> String,
+ key: K,
+ kind: DepKind,
+ name: &'static str,
+) -> QueryStackFrame {
+ // Disable visible paths printing for performance reasons.
+ // Showing visible path instead of any path is not that important in production.
+ let description = 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 =
+ if tcx.sess.verbose() { format!("{} [{}]", description, name) } else { 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 def_kind = if kind == dep_graph::DepKind::opt_def_kind {
+ // Try to avoid infinite recursion.
+ None
+ } else {
+ key.key_as_def_id()
+ .and_then(|def_id| def_id.as_local())
+ .and_then(|def_id| tcx.opt_def_kind(def_id))
+ };
+ let hash = || {
+ tcx.with_stable_hashing_context(|mut hcx| {
+ let mut hasher = StableHasher::new();
+ std::mem::discriminant(&kind).hash_stable(&mut hcx, &mut hasher);
+ key.hash_stable(&mut hcx, &mut hasher);
+ hasher.finish::<u64>()
+ })
+ };
+
+ QueryStackFrame::new(name, description, span, def_kind, hash)
+}
+
+fn try_load_from_on_disk_cache<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode)
+where
+ Q: QueryDescription<QueryCtxt<'tcx>>,
+ Q::Key: DepNodeParams<TyCtxt<'tcx>>,
+{
+ debug_assert!(tcx.dep_graph.is_green(&dep_node));
+
+ let key = Q::Key::recover(tcx, &dep_node).unwrap_or_else(|| {
+ panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)
+ });
+ if Q::cache_on_disk(tcx, &key) {
+ let _ = Q::execute_query(tcx, key);
+ }
+}
+
+pub(crate) fn try_load_from_disk<'tcx, V>(
+ tcx: QueryCtxt<'tcx>,
+ id: SerializedDepNodeIndex,
+) -> Option<V>
+where
+ V: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
+{
+ tcx.on_disk_cache().as_ref()?.try_load_query_result(*tcx, id)
+}
+
+fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool
+where
+ Q: QueryDescription<QueryCtxt<'tcx>>,
+ Q::Key: DepNodeParams<TyCtxt<'tcx>>,
+ Q::Value: Value<TyCtxt<'tcx>>,
+{
+ if let Some(key) = Q::Key::recover(tcx, &dep_node) {
+ #[cfg(debug_assertions)]
+ let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
+ let tcx = QueryCtxt::from_tcx(tcx);
+ force_query::<Q, _>(tcx, key, dep_node);
+ true
+ } else {
+ false
+ }
+}
+
+pub(crate) fn query_callback<'tcx, Q: QueryConfig>(
+ is_anon: bool,
+ is_eval_always: bool,
+) -> DepKindStruct<'tcx>
+where
+ Q: QueryDescription<QueryCtxt<'tcx>>,
+ Q::Key: DepNodeParams<TyCtxt<'tcx>>,
+{
+ let fingerprint_style = Q::Key::fingerprint_style();
+
+ if is_anon || !fingerprint_style.reconstructible() {
+ return DepKindStruct {
+ is_anon,
+ is_eval_always,
+ fingerprint_style,
+ force_from_dep_node: None,
+ try_load_from_on_disk_cache: None,
+ };
+ }
+
+ DepKindStruct {
+ is_anon,
+ is_eval_always,
+ fingerprint_style,
+ force_from_dep_node: Some(force_from_dep_node::<Q>),
+ try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache::<Q>),
+ }
}
+// NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros
+// invoked by `rustc_query_append`.
macro_rules! define_queries {
- (<$tcx:tt>
+ (
$($(#[$attr:meta])*
[$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
-
define_queries_struct! {
- tcx: $tcx,
input: ($(([$($modifiers)*] [$($attr)*] [$name]))*)
}
- mod make_query {
- use super::*;
-
- // Create an eponymous constructor for each query.
- $(#[allow(nonstandard_style)] $(#[$attr])*
- pub fn $name<$tcx>(tcx: QueryCtxt<$tcx>, key: query_keys::$name<$tcx>) -> QueryStackFrame {
- opt_remap_env_constness!([$($modifiers)*][key]);
- let kind = dep_graph::DepKind::$name;
- let name = stringify!($name);
- // Disable visible paths printing for performance reasons.
- // Showing visible path instead of any path is not that important in production.
- let description = ty::print::with_no_visible_paths!(
- // Force filename-line mode to avoid invoking `type_of` query.
- ty::print::with_forced_impl_filename_line!(
- queries::$name::describe(tcx, key)
- )
- );
- let description = if tcx.sess.verbose() {
- format!("{} [{}]", description, name)
- } else {
- 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 def_kind = if kind == dep_graph::DepKind::opt_def_kind {
- // Try to avoid infinite recursion.
- None
- } else {
- key.key_as_def_id()
- .and_then(|def_id| def_id.as_local())
- .and_then(|def_id| tcx.opt_def_kind(def_id))
- };
- let hash = || {
- tcx.with_stable_hashing_context(|mut hcx|{
- let mut hasher = StableHasher::new();
- std::mem::discriminant(&kind).hash_stable(&mut hcx, &mut hasher);
- key.hash_stable(&mut hcx, &mut hasher);
- hasher.finish::<u64>()
- })
- };
-
- QueryStackFrame::new(name, description, span, def_kind, hash)
- })*
- }
-
#[allow(nonstandard_style)]
mod queries {
use std::marker::PhantomData;
- $(pub struct $name<$tcx> {
- data: PhantomData<&$tcx ()>
+ $(pub struct $name<'tcx> {
+ data: PhantomData<&'tcx ()>
})*
}
- $(impl<$tcx> QueryConfig for queries::$name<$tcx> {
- type Key = query_keys::$name<$tcx>;
- type Value = query_values::$name<$tcx>;
- type Stored = query_stored::$name<$tcx>;
+ $(impl<'tcx> QueryConfig for queries::$name<'tcx> {
+ type Key = query_keys::$name<'tcx>;
+ type Value = query_values::$name<'tcx>;
+ type Stored = query_stored::$name<'tcx>;
const NAME: &'static str = stringify!($name);
}
- impl<$tcx> QueryDescription<QueryCtxt<$tcx>> for queries::$name<$tcx> {
- rustc_query_description! { $name<$tcx> }
+ impl<'tcx> QueryDescription<QueryCtxt<'tcx>> for queries::$name<'tcx> {
+ rustc_query_description! { $name }
- type Cache = query_storage::$name<$tcx>;
+ type Cache = query_storage::$name<'tcx>;
#[inline(always)]
- fn query_state<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryState<Self::Key>
- where QueryCtxt<$tcx>: 'a
+ fn query_state<'a>(tcx: QueryCtxt<'tcx>) -> &'a QueryState<Self::Key>
+ where QueryCtxt<'tcx>: 'a
{
&tcx.queries.$name
}
#[inline(always)]
- fn query_cache<'a>(tcx: QueryCtxt<$tcx>) -> &'a Self::Cache
+ fn query_cache<'a>(tcx: QueryCtxt<'tcx>) -> &'a Self::Cache
where 'tcx:'a
{
&tcx.query_caches.$name
@@ -340,34 +442,34 @@ macro_rules! define_queries {
#[inline]
fn make_vtable(tcx: QueryCtxt<'tcx>, key: &Self::Key) ->
- QueryVTable<QueryCtxt<$tcx>, Self::Key, Self::Value>
+ QueryVTable<QueryCtxt<'tcx>, Self::Key, Self::Value>
{
let compute = get_provider!([$($modifiers)*][tcx, $name, key]);
let cache_on_disk = Self::cache_on_disk(tcx.tcx, key);
QueryVTable {
anon: is_anon!([$($modifiers)*]),
eval_always: is_eval_always!([$($modifiers)*]),
+ depth_limit: depth_limit!([$($modifiers)*]),
dep_kind: dep_graph::DepKind::$name,
hash_result: hash_result!([$($modifiers)*]),
- handle_cycle_error: |tcx, mut error| handle_cycle_error!([$($modifiers)*][tcx, error]),
+ handle_cycle_error: handle_cycle_error!([$($modifiers)*]),
compute,
- cache_on_disk,
- try_load_from_disk: Self::TRY_LOAD_FROM_DISK,
+ try_load_from_disk: if cache_on_disk { should_ever_cache_on_disk!([$($modifiers)*]) } else { None },
}
}
+
+ fn execute_query(tcx: TyCtxt<'tcx>, k: Self::Key) -> Self::Stored {
+ tcx.$name(k)
+ }
})*
#[allow(nonstandard_style)]
mod query_callbacks {
use super::*;
- use rustc_middle::dep_graph::DepNode;
- use rustc_middle::ty::query::query_keys;
- use rustc_query_system::dep_graph::DepNodeParams;
- use rustc_query_system::query::{force_query, QueryDescription};
use rustc_query_system::dep_graph::FingerprintStyle;
// We use this for most things when incr. comp. is turned off.
- pub fn Null() -> DepKindStruct {
+ pub fn Null<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
@@ -378,7 +480,7 @@ macro_rules! define_queries {
}
// We use this for the forever-red node.
- pub fn Red() -> DepKindStruct {
+ pub fn Red<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
@@ -388,7 +490,7 @@ macro_rules! define_queries {
}
}
- pub fn TraitSelect() -> DepKindStruct {
+ pub fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: true,
is_eval_always: false,
@@ -398,7 +500,7 @@ macro_rules! define_queries {
}
}
- pub fn CompileCodegenUnit() -> DepKindStruct {
+ pub fn CompileCodegenUnit<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
@@ -408,7 +510,7 @@ macro_rules! define_queries {
}
}
- pub fn CompileMonoItem() -> DepKindStruct {
+ pub fn CompileMonoItem<'tcx>() -> DepKindStruct<'tcx> {
DepKindStruct {
is_anon: false,
is_eval_always: false,
@@ -418,108 +520,70 @@ macro_rules! define_queries {
}
}
- $(pub(crate) fn $name()-> DepKindStruct {
- let is_anon = is_anon!([$($modifiers)*]);
- let is_eval_always = is_eval_always!([$($modifiers)*]);
-
- let fingerprint_style =
- <query_keys::$name<'_> as DepNodeParams<TyCtxt<'_>>>::fingerprint_style();
-
- if is_anon || !fingerprint_style.reconstructible() {
- return DepKindStruct {
- is_anon,
- is_eval_always,
- fingerprint_style,
- force_from_dep_node: None,
- try_load_from_on_disk_cache: None,
- }
- }
-
- #[inline(always)]
- fn recover<'tcx>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> Option<query_keys::$name<'tcx>> {
- <query_keys::$name<'_> as DepNodeParams<TyCtxt<'_>>>::recover(tcx, &dep_node)
- }
-
- fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: DepNode) -> bool {
- if let Some(key) = recover(tcx, dep_node) {
- #[cfg(debug_assertions)]
- let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered();
- let tcx = QueryCtxt::from_tcx(tcx);
- force_query::<queries::$name<'_>, _>(tcx, key, dep_node);
- true
- } else {
- false
- }
- }
-
- fn try_load_from_on_disk_cache(tcx: TyCtxt<'_>, dep_node: DepNode) {
- debug_assert!(tcx.dep_graph.is_green(&dep_node));
-
- let key = recover(tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash));
- if queries::$name::cache_on_disk(tcx, &key) {
- let _ = tcx.$name(key);
- }
- }
-
- DepKindStruct {
- is_anon,
- is_eval_always,
- fingerprint_style,
- force_from_dep_node: Some(force_from_dep_node),
- try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache),
- }
+ $(pub(crate) fn $name<'tcx>()-> DepKindStruct<'tcx> {
+ $crate::plumbing::query_callback::<queries::$name<'tcx>>(
+ is_anon!([$($modifiers)*]),
+ is_eval_always!([$($modifiers)*]),
+ )
})*
}
- pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct] {
+ pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] {
arena.alloc_from_iter(make_dep_kind_array!(query_callbacks))
}
}
}
-// FIXME(eddyb) this macro (and others?) use `$tcx` and `'tcx` interchangeably.
-// We should either not take `$tcx` at all and use `'tcx` everywhere, or use
-// `$tcx` everywhere (even if that isn't necessary due to lack of hygiene).
+use crate::{ExternProviders, OnDiskCache, Providers};
+
+impl<'tcx> Queries<'tcx> {
+ pub fn new(
+ local_providers: Providers,
+ extern_providers: ExternProviders,
+ on_disk_cache: Option<OnDiskCache<'tcx>>,
+ ) -> Self {
+ Queries {
+ local_providers: Box::new(local_providers),
+ extern_providers: Box::new(extern_providers),
+ on_disk_cache,
+ jobs: AtomicU64::new(1),
+ ..Queries::default()
+ }
+ }
+}
+
macro_rules! define_queries_struct {
- (tcx: $tcx:tt,
+ (
input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
- pub struct Queries<$tcx> {
+ #[derive(Default)]
+ pub struct Queries<'tcx> {
local_providers: Box<Providers>,
extern_providers: Box<ExternProviders>,
- pub on_disk_cache: Option<OnDiskCache<$tcx>>,
+ pub on_disk_cache: Option<OnDiskCache<'tcx>>,
jobs: AtomicU64,
- $($(#[$attr])* $name: QueryState<query_keys::$name<$tcx>>,)*
+ $($(#[$attr])* $name: QueryState<<queries::$name<'tcx> as QueryConfig>::Key>,)*
}
- impl<$tcx> Queries<$tcx> {
- pub fn new(
- local_providers: Providers,
- extern_providers: ExternProviders,
- on_disk_cache: Option<OnDiskCache<$tcx>>,
- ) -> Self {
- Queries {
- local_providers: Box::new(local_providers),
- extern_providers: Box::new(extern_providers),
- on_disk_cache,
- jobs: AtomicU64::new(1),
- $($name: Default::default()),*
- }
- }
-
+ impl<'tcx> Queries<'tcx> {
pub(crate) fn try_collect_active_jobs(
- &$tcx self,
- tcx: TyCtxt<$tcx>,
+ &'tcx self,
+ tcx: TyCtxt<'tcx>,
) -> Option<QueryMap> {
let tcx = QueryCtxt { tcx, queries: self };
let mut jobs = QueryMap::default();
$(
+ let make_query = |tcx, key| {
+ let kind = dep_graph::DepKind::$name;
+ let name = stringify!($name);
+ $crate::plumbing::create_query_frame(tcx, queries::$name::describe, key, kind, name)
+ };
self.$name.try_collect_active_jobs(
tcx,
- make_query::$name,
+ make_query,
&mut jobs,
)?;
)*
@@ -541,17 +605,16 @@ macro_rules! define_queries_struct {
$($(#[$attr])*
#[inline(always)]
- #[tracing::instrument(level = "trace", skip(self, tcx))]
+ #[tracing::instrument(level = "trace", skip(self, tcx), ret)]
fn $name(
&'tcx self,
- tcx: TyCtxt<$tcx>,
+ tcx: TyCtxt<'tcx>,
span: Span,
- key: query_keys::$name<$tcx>,
+ key: <queries::$name<'tcx> as QueryConfig>::Key,
mode: QueryMode,
- ) -> Option<query_stored::$name<$tcx>> {
- opt_remap_env_constness!([$($modifiers)*][key]);
+ ) -> Option<query_stored::$name<'tcx>> {
let qcx = QueryCtxt { tcx, queries: self };
- get_query::<queries::$name<$tcx>, _>(qcx, span, key, mode)
+ get_query::<queries::$name<'tcx>, _>(qcx, span, key, mode)
})*
}
};
diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs
index 551f09420..98ec3bc09 100644
--- a/compiler/rustc_query_impl/src/profiling_support.rs
+++ b/compiler/rustc_query_impl/src/profiling_support.rs
@@ -306,19 +306,19 @@ pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) {
let mut string_cache = QueryKeyStringCache::new();
macro_rules! alloc_once {
- (<$tcx:tt>
- $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($K:ty) -> $V:ty,)*
- ) => {
- $({
+ (
+ $($(#[$attr:meta])*
+ [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
+ $(
alloc_self_profile_query_strings_for_query_cache(
tcx,
stringify!($name),
&tcx.query_caches.$name,
&mut string_cache,
);
- })*
+ )+
}
}
- rustc_query_append! { [alloc_once!][<'tcx>] }
+ rustc_query_append! { alloc_once! }
}
diff --git a/compiler/rustc_query_impl/src/values.rs b/compiler/rustc_query_impl/src/values.rs
deleted file mode 100644
index 718a2971c..000000000
--- a/compiler/rustc_query_impl/src/values.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use super::QueryCtxt;
-use rustc_middle::ty::{self, AdtSizedConstraint, Ty};
-
-pub(super) trait Value<'tcx>: Sized {
- fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self;
-}
-
-impl<'tcx, T> Value<'tcx> for T {
- default fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> T {
- tcx.sess.abort_if_errors();
- bug!("Value::from_cycle_error called without errors");
- }
-}
-
-impl<'tcx> Value<'tcx> for Ty<'_> {
- fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
- // SAFETY: This is never called when `Self` is not `Ty<'tcx>`.
- // FIXME: Represent the above fact in the trait system somehow.
- unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error()) }
- }
-}
-
-impl<'tcx> Value<'tcx> for ty::SymbolName<'_> {
- fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
- // SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`.
- // FIXME: Represent the above fact in the trait system somehow.
- unsafe {
- std::mem::transmute::<ty::SymbolName<'tcx>, ty::SymbolName<'_>>(ty::SymbolName::new(
- *tcx, "<error>",
- ))
- }
- }
-}
-
-impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> {
- fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
- // SAFETY: This is never called when `Self` is not `AdtSizedConstraint<'tcx>`.
- // FIXME: Represent the above fact in the trait system somehow.
- unsafe {
- std::mem::transmute::<AdtSizedConstraint<'tcx>, AdtSizedConstraint<'_>>(
- AdtSizedConstraint(tcx.intern_type_list(&[tcx.ty_error()])),
- )
- }
- }
-}