Wrap TyCtxt inside a QueryCtxt for queries.

This commit is contained in:
Camille GILLOT 2020-04-08 17:03:34 +02:00
parent dab9b89221
commit 2db2776589
9 changed files with 82 additions and 49 deletions

View file

@ -354,9 +354,10 @@ fn add_query_description_impl(
quote! { quote! {
#[inline] #[inline]
fn try_load_from_disk( fn try_load_from_disk(
#tcx: TyCtxt<'tcx>, tcx: QueryCtxt<'tcx>,
#id: SerializedDepNodeIndex id: SerializedDepNodeIndex
) -> Option<Self::Value> { ) -> Option<Self::Value> {
let (#tcx, #id) = (*tcx, id);
#block #block
} }
} }
@ -365,10 +366,10 @@ fn add_query_description_impl(
quote! { quote! {
#[inline] #[inline]
fn try_load_from_disk( fn try_load_from_disk(
tcx: TyCtxt<'tcx>, tcx: QueryCtxt<'tcx>,
id: SerializedDepNodeIndex id: SerializedDepNodeIndex
) -> Option<Self::Value> { ) -> Option<Self::Value> {
tcx.on_disk_cache.as_ref()?.try_load_query_result(tcx, id) tcx.on_disk_cache.as_ref()?.try_load_query_result(*tcx, id)
} }
} }
}; };
@ -393,10 +394,11 @@ fn add_query_description_impl(
#[inline] #[inline]
#[allow(unused_variables, unused_braces)] #[allow(unused_variables, unused_braces)]
fn cache_on_disk( fn cache_on_disk(
#tcx: TyCtxt<'tcx>, tcx: QueryCtxt<'tcx>,
#key: &Self::Key, key: &Self::Key,
#value: Option<&Self::Value> value: Option<&Self::Value>
) -> bool { ) -> bool {
let (#tcx, #key, #value) = (*tcx, key, value);
#expr #expr
} }
@ -414,16 +416,14 @@ fn add_query_description_impl(
let desc = quote! { let desc = quote! {
#[allow(unused_variables)] #[allow(unused_variables)]
fn describe( fn describe(tcx: QueryCtxt<'tcx>, key: #arg) -> String {
#tcx: TyCtxt<'tcx>, let (#tcx, #key) = (*tcx, key);
#key: #arg, ::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc).into())
) -> String {
::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc))
} }
}; };
impls.extend(quote! { impls.extend(quote! {
impl<'tcx> QueryDescription<TyCtxt<'tcx>> for queries::#name<'tcx> { impl<'tcx> QueryDescription<QueryCtxt<'tcx>> for queries::#name<'tcx> {
#desc #desc
#cache #cache
} }

View file

@ -55,6 +55,7 @@
//! //!
//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html //! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
use crate::ty::query::QueryCtxt;
use crate::ty::TyCtxt; use crate::ty::TyCtxt;
use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fingerprint::Fingerprint;
@ -261,7 +262,7 @@ pub mod dep_kind {
if let Some(key) = recover(tcx, dep_node) { if let Some(key) = recover(tcx, dep_node) {
force_query::<queries::$variant<'_>, _>( force_query::<queries::$variant<'_>, _>(
tcx, QueryCtxt(tcx),
key, key,
DUMMY_SP, DUMMY_SP,
*dep_node *dep_node
@ -287,7 +288,7 @@ pub mod dep_kind {
.unwrap_or(false)); .unwrap_or(false));
let key = recover(tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash)); let key = recover(tcx, dep_node).unwrap_or_else(|| panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash));
if queries::$variant::cache_on_disk(tcx, &key, None) { if queries::$variant::cache_on_disk(QueryCtxt(tcx), &key, None) {
let _ = tcx.$variant(key); let _ = tcx.$variant(key);
} }
} }

View file

@ -7,6 +7,7 @@ use crate::traits::query::{
CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
}; };
use crate::ty::query::queries; use crate::ty::query::queries;
use crate::ty::query::QueryCtxt;
use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::subst::{GenericArg, SubstsRef};
use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};

View file

@ -1,3 +1,4 @@
use crate::ty::query::QueryCtxt;
use crate::ty::tls; use crate::ty::tls;
use rustc_query_system::query::deadlock; use rustc_query_system::query::deadlock;
@ -20,7 +21,7 @@ pub unsafe fn handle_deadlock() {
thread::spawn(move || { thread::spawn(move || {
tls::enter_context(icx, |_| { tls::enter_context(icx, |_| {
rustc_span::SESSION_GLOBALS rustc_span::SESSION_GLOBALS
.set(session_globals, || tls::with(|tcx| deadlock(tcx, &registry))) .set(session_globals, || tls::with(|tcx| deadlock(QueryCtxt(tcx), &registry)))
}) });
}); });
} }

View file

@ -60,6 +60,7 @@ use std::sync::Arc;
#[macro_use] #[macro_use]
mod plumbing; mod plumbing;
pub use plumbing::QueryCtxt;
pub(crate) use rustc_query_system::query::CycleError; pub(crate) use rustc_query_system::query::CycleError;
use rustc_query_system::query::*; use rustc_query_system::query::*;

View file

@ -3,6 +3,7 @@ use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState};
use crate::mir::{self, interpret}; use crate::mir::{self, interpret};
use crate::ty::codec::{RefDecodable, TyDecoder, TyEncoder}; use crate::ty::codec::{RefDecodable, TyDecoder, TyEncoder};
use crate::ty::context::TyCtxt; use crate::ty::context::TyCtxt;
use crate::ty::query::QueryCtxt;
use crate::ty::{self, Ty}; use crate::ty::{self, Ty};
use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder, FingerprintEncoder}; use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder, FingerprintEncoder};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
@ -312,7 +313,7 @@ impl<'sess> OnDiskCache<'sess> {
($($query:ident,)*) => { ($($query:ident,)*) => {
$( $(
encode_query_results::<ty::query::queries::$query<'_>>( encode_query_results::<ty::query::queries::$query<'_>>(
tcx, QueryCtxt(tcx),
enc, enc,
qri qri
)?; )?;
@ -1230,12 +1231,12 @@ impl<'a> Decodable<opaque::Decoder<'a>> for IntEncodedWithFixedSize {
} }
fn encode_query_results<'a, 'tcx, Q>( fn encode_query_results<'a, 'tcx, Q>(
tcx: TyCtxt<'tcx>, tcx: QueryCtxt<'tcx>,
encoder: &mut CacheEncoder<'a, 'tcx, FileEncoder>, encoder: &mut CacheEncoder<'a, 'tcx, FileEncoder>,
query_result_index: &mut EncodedQueryResultIndex, query_result_index: &mut EncodedQueryResultIndex,
) -> FileEncodeResult ) -> FileEncodeResult
where where
Q: super::QueryDescription<TyCtxt<'tcx>> + super::QueryAccessors<TyCtxt<'tcx>>, Q: super::QueryDescription<QueryCtxt<'tcx>> + super::QueryAccessors<QueryCtxt<'tcx>>,
Q::Value: Encodable<CacheEncoder<'a, 'tcx, FileEncoder>>, Q::Value: Encodable<CacheEncoder<'a, 'tcx, FileEncoder>>,
{ {
let _timer = tcx let _timer = tcx

View file

@ -5,6 +5,7 @@
use crate::ty::query::Query; use crate::ty::query::Query;
use crate::ty::tls::{self, ImplicitCtxt}; use crate::ty::tls::{self, ImplicitCtxt};
use crate::ty::{self, TyCtxt}; use crate::ty::{self, TyCtxt};
use rustc_query_system::dep_graph::HasDepContext;
use rustc_query_system::query::QueryContext; use rustc_query_system::query::QueryContext;
use rustc_query_system::query::{CycleError, QueryJobId, QueryJobInfo}; use rustc_query_system::query::{CycleError, QueryJobId, QueryJobInfo};
@ -15,7 +16,29 @@ use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Leve
use rustc_span::def_id::DefId; use rustc_span::def_id::DefId;
use rustc_span::Span; use rustc_span::Span;
impl QueryContext for TyCtxt<'tcx> { #[derive(Copy, Clone)]
pub struct QueryCtxt<'tcx>(pub TyCtxt<'tcx>);
impl<'tcx> std::ops::Deref for QueryCtxt<'tcx> {
type Target = TyCtxt<'tcx>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl HasDepContext for QueryCtxt<'tcx> {
type DepKind = crate::dep_graph::DepKind;
type StableHashingContext = crate::ich::StableHashingContext<'tcx>;
type DepContext = TyCtxt<'tcx>;
#[inline]
fn dep_context(&self) -> &Self::DepContext {
&self.0
}
}
impl QueryContext for QueryCtxt<'tcx> {
type Query = Query<'tcx>; type Query = Query<'tcx>;
fn incremental_verify_ich(&self) -> bool { fn incremental_verify_ich(&self) -> bool {
@ -26,11 +49,11 @@ impl QueryContext for TyCtxt<'tcx> {
} }
fn def_path_str(&self, def_id: DefId) -> String { fn def_path_str(&self, def_id: DefId) -> String {
TyCtxt::def_path_str(*self, def_id) self.0.def_path_str(def_id)
} }
fn current_query_job(&self) -> Option<QueryJobId<Self::DepKind>> { fn current_query_job(&self) -> Option<QueryJobId<Self::DepKind>> {
tls::with_related_context(*self, |icx| icx.query) tls::with_related_context(**self, |icx| icx.query)
} }
fn try_collect_active_jobs( fn try_collect_active_jobs(
@ -53,10 +76,10 @@ impl QueryContext for TyCtxt<'tcx> {
// The `TyCtxt` stored in TLS has the same global interner lifetime // The `TyCtxt` stored in TLS has the same global interner lifetime
// as `self`, so we use `with_related_context` to relate the 'tcx lifetimes // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes
// when accessing the `ImplicitCtxt`. // when accessing the `ImplicitCtxt`.
tls::with_related_context(*self, move |current_icx| { tls::with_related_context(**self, move |current_icx| {
// Update the `ImplicitCtxt` to point to our new query job. // Update the `ImplicitCtxt` to point to our new query job.
let new_icx = ImplicitCtxt { let new_icx = ImplicitCtxt {
tcx: *self, tcx: **self,
query: Some(token), query: Some(token),
diagnostics, diagnostics,
layout_depth: current_icx.layout_depth, layout_depth: current_icx.layout_depth,
@ -71,7 +94,7 @@ impl QueryContext for TyCtxt<'tcx> {
} }
} }
impl<'tcx> TyCtxt<'tcx> { impl<'tcx> QueryCtxt<'tcx> {
#[inline(never)] #[inline(never)]
#[cold] #[cold]
pub(super) fn report_cycle( pub(super) fn report_cycle(
@ -81,7 +104,7 @@ impl<'tcx> TyCtxt<'tcx> {
assert!(!stack.is_empty()); assert!(!stack.is_empty());
let fix_span = |span: Span, query: &Query<'tcx>| { let fix_span = |span: Span, query: &Query<'tcx>| {
self.sess.source_map().guess_head_span(query.default_span(self, span)) self.sess.source_map().guess_head_span(query.default_span(*self, span))
}; };
// Disable naming impls with types in this path, since that // Disable naming impls with types in this path, since that
@ -119,7 +142,9 @@ impl<'tcx> TyCtxt<'tcx> {
err err
}) })
} }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn try_print_query_stack(handler: &Handler, num_frames: Option<usize>) { pub fn try_print_query_stack(handler: &Handler, num_frames: Option<usize>) {
eprintln!("query stack during panic:"); eprintln!("query stack during panic:");
@ -149,7 +174,7 @@ impl<'tcx> TyCtxt<'tcx> {
"#{} [{}] {}", "#{} [{}] {}",
i, i,
query_info.info.query.name(), query_info.info.query.name(),
query_info.info.query.describe(icx.tcx) query_info.info.query.describe(QueryCtxt(icx.tcx))
), ),
); );
diag.span = diag.span =
@ -272,7 +297,7 @@ macro_rules! define_queries {
} }
} }
pub fn describe(&self, tcx: TyCtxt<$tcx>) -> String { pub(crate) fn describe(&self, tcx: QueryCtxt<$tcx>) -> String {
let (r, name) = match *self { let (r, name) = match *self {
$(Query::$name(key) => { $(Query::$name(key) => {
(queries::$name::describe(tcx, key), stringify!($name)) (queries::$name::describe(tcx, key), stringify!($name))
@ -362,7 +387,7 @@ macro_rules! define_queries {
const NAME: &'static str = stringify!($name); const NAME: &'static str = stringify!($name);
} }
impl<$tcx> QueryAccessors<TyCtxt<$tcx>> for queries::$name<$tcx> { impl<$tcx> QueryAccessors<QueryCtxt<$tcx>> for queries::$name<$tcx> {
const ANON: bool = is_anon!([$($modifiers)*]); const ANON: bool = is_anon!([$($modifiers)*]);
const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]); const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]);
const DEP_KIND: dep_graph::DepKind = dep_graph::DepKind::$name; const DEP_KIND: dep_graph::DepKind = dep_graph::DepKind::$name;
@ -370,19 +395,19 @@ macro_rules! define_queries {
type Cache = query_storage::$name<$tcx>; type Cache = query_storage::$name<$tcx>;
#[inline(always)] #[inline(always)]
fn query_state<'a>(tcx: TyCtxt<$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<$tcx>, Self::Key> {
&tcx.queries.$name &tcx.queries.$name
} }
#[inline(always)] #[inline(always)]
fn query_cache<'a>(tcx: TyCtxt<$tcx>) -> &'a QueryCacheStore<Self::Cache> fn query_cache<'a>(tcx: QueryCtxt<$tcx>) -> &'a QueryCacheStore<Self::Cache>
where 'tcx:'a where 'tcx:'a
{ {
&tcx.query_caches.$name &tcx.query_caches.$name
} }
#[inline] #[inline]
fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { fn compute(tcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value {
let provider = tcx.queries.providers.get(key.query_crate()) let provider = tcx.queries.providers.get(key.query_crate())
// HACK(eddyb) it's possible crates may be loaded after // HACK(eddyb) it's possible crates may be loaded after
// the query engine is created, and because crate loading // the query engine is created, and because crate loading
@ -390,7 +415,7 @@ macro_rules! define_queries {
// would be missing appropriate entries in `providers`. // would be missing appropriate entries in `providers`.
.unwrap_or(&tcx.queries.fallback_extern_providers) .unwrap_or(&tcx.queries.fallback_extern_providers)
.$name; .$name;
provider(tcx, key) provider(*tcx, key)
} }
fn hash_result( fn hash_result(
@ -401,7 +426,7 @@ macro_rules! define_queries {
} }
fn handle_cycle_error( fn handle_cycle_error(
tcx: TyCtxt<'tcx>, tcx: QueryCtxt<'tcx>,
error: CycleError<Query<'tcx>> error: CycleError<Query<'tcx>>
) -> Self::Value { ) -> Self::Value {
handle_cycle_error!([$($modifiers)*][tcx, error]) handle_cycle_error!([$($modifiers)*][tcx, error])
@ -425,7 +450,8 @@ macro_rules! define_queries {
Err(lookup) => lookup, Err(lookup) => lookup,
}; };
get_query::<queries::$name<'_>, _>(self.tcx, DUMMY_SP, key, lookup, QueryMode::Ensure); let qcx = QueryCtxt(self.tcx);
get_query::<queries::$name<'_>, _>(qcx, DUMMY_SP, key, lookup, QueryMode::Ensure);
})* })*
} }
@ -516,7 +542,8 @@ macro_rules! define_queries {
Err(lookup) => lookup, Err(lookup) => lookup,
}; };
get_query::<queries::$name<'_>, _>(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap() let qcx = QueryCtxt(self.tcx);
get_query::<queries::$name<'_>, _>(qcx, self.span, key, lookup, QueryMode::Get).unwrap()
})* })*
} }
@ -558,12 +585,12 @@ macro_rules! define_queries_struct {
pub(crate) fn try_collect_active_jobs( pub(crate) fn try_collect_active_jobs(
&self &self
) -> Option<FxHashMap<QueryJobId<crate::dep_graph::DepKind>, QueryJobInfo<crate::dep_graph::DepKind, <TyCtxt<$tcx> as QueryContext>::Query>>> { ) -> Option<FxHashMap<QueryJobId<crate::dep_graph::DepKind>, QueryJobInfo<crate::dep_graph::DepKind, Query<$tcx>>>> {
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<TyCtxt<'tcx>>>::DEP_KIND, <queries::$name<'tcx> as QueryAccessors<QueryCtxt<'tcx>>>::DEP_KIND,
Query::$name, Query::$name,
&mut jobs, &mut jobs,
)?; )?;

View file

@ -1,7 +1,7 @@
use crate::ty::query::queries; use crate::ty::query::query_storage;
use crate::ty::TyCtxt; use crate::ty::TyCtxt;
use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_query_system::query::{QueryAccessors, QueryCache, QueryCacheStore}; use rustc_query_system::query::{QueryCache, QueryCacheStore};
use std::any::type_name; use std::any::type_name;
use std::mem; use std::mem;
@ -125,7 +125,7 @@ macro_rules! print_stats {
$( $(
queries.push(stats::< queries.push(stats::<
<queries::$name<'_> as QueryAccessors<TyCtxt<'_>>>::Cache, query_storage::$name<'_>,
>( >(
stringify!($name), stringify!($name),
&tcx.query_caches.$name, &tcx.query_caches.$name,

View file

@ -1,18 +1,19 @@
use crate::ty::{self, AdtSizedConstraint, Ty, TyCtxt, TyS}; use crate::ty::query::QueryCtxt;
use crate::ty::{self, AdtSizedConstraint, Ty, TyS};
pub(super) trait Value<'tcx>: Sized { pub(super) trait Value<'tcx>: Sized {
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self; fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self;
} }
impl<'tcx, T> Value<'tcx> for T { impl<'tcx, T> Value<'tcx> for T {
default fn from_cycle_error(tcx: TyCtxt<'tcx>) -> T { default fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> T {
tcx.sess.abort_if_errors(); tcx.sess.abort_if_errors();
bug!("Value::from_cycle_error called without errors"); bug!("Value::from_cycle_error called without errors");
} }
} }
impl<'tcx> Value<'tcx> for &'_ TyS<'_> { impl<'tcx> Value<'tcx> for &'_ TyS<'_> {
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self { fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
// SAFETY: This is never called when `Self` is not `Ty<'tcx>`. // SAFETY: This is never called when `Self` is not `Ty<'tcx>`.
// FIXME: Represent the above fact in the trait system somehow. // FIXME: Represent the above fact in the trait system somehow.
unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error()) } unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error()) }
@ -20,19 +21,19 @@ impl<'tcx> Value<'tcx> for &'_ TyS<'_> {
} }
impl<'tcx> Value<'tcx> for ty::SymbolName<'_> { impl<'tcx> Value<'tcx> for ty::SymbolName<'_> {
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self { fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
// SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`. // SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`.
// FIXME: Represent the above fact in the trait system somehow. // FIXME: Represent the above fact in the trait system somehow.
unsafe { unsafe {
std::mem::transmute::<ty::SymbolName<'tcx>, ty::SymbolName<'_>>(ty::SymbolName::new( std::mem::transmute::<ty::SymbolName<'tcx>, ty::SymbolName<'_>>(ty::SymbolName::new(
tcx, "<error>", *tcx, "<error>",
)) ))
} }
} }
} }
impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> { impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> {
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self { fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
// SAFETY: This is never called when `Self` is not `AdtSizedConstraint<'tcx>`. // SAFETY: This is never called when `Self` is not `AdtSizedConstraint<'tcx>`.
// FIXME: Represent the above fact in the trait system somehow. // FIXME: Represent the above fact in the trait system somehow.
unsafe { unsafe {