Make QueryEngine opaque to TyCtxt.

This commit is contained in:
Camille GILLOT 2020-10-11 10:34:13 +02:00
parent 3f868b1791
commit 5d71b99690
12 changed files with 99 additions and 63 deletions

View File

@ -3890,6 +3890,7 @@ dependencies = [
"rustc_expand",
"rustc_hir",
"rustc_incremental",
"rustc_index",
"rustc_lint",
"rustc_metadata",
"rustc_middle",

View File

@ -30,6 +30,7 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
rustc_codegen_llvm = { path = "../rustc_codegen_llvm", optional = true }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_metadata = { path = "../rustc_metadata" }
rustc_mir = { path = "../rustc_mir" }
rustc_mir_build = { path = "../rustc_mir_build" }

View File

@ -15,11 +15,13 @@ use rustc_expand::base::ExtCtxt;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_hir::definitions::Definitions;
use rustc_hir::Crate;
use rustc_index::vec::IndexVec;
use rustc_lint::LintStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::middle;
use rustc_middle::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
use rustc_middle::ty::query;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
use rustc_mir as mir;
@ -738,20 +740,18 @@ pub static DEFAULT_EXTERN_QUERY_PROVIDERS: SyncLazy<Providers> = SyncLazy::new(|
extern_providers
});
pub struct QueryContext<'tcx>(&'tcx GlobalCtxt<'tcx>);
pub struct QueryContext<'tcx> {
gcx: &'tcx GlobalCtxt<'tcx>,
}
impl<'tcx> QueryContext<'tcx> {
pub fn enter<F, R>(&mut self, f: F) -> R
where
F: FnOnce(TyCtxt<'tcx>) -> R,
{
let icx = ty::tls::ImplicitCtxt::new(self.0);
let icx = ty::tls::ImplicitCtxt::new(self.gcx);
ty::tls::enter_context(&icx, |_| f(icx.tcx))
}
pub fn print_stats(&mut self) {
self.enter(ty::query::print_stats)
}
}
pub fn create_global_ctxt<'tcx>(
@ -762,6 +762,7 @@ pub fn create_global_ctxt<'tcx>(
mut resolver_outputs: ResolverOutputs,
outputs: OutputFilenames,
crate_name: &str,
queries: &'tcx OnceCell<query::Queries<'tcx>>,
global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
) -> QueryContext<'tcx> {
@ -785,26 +786,33 @@ pub fn create_global_ctxt<'tcx>(
callback(sess, &mut local_providers, &mut extern_providers);
}
let queries = {
let crates = resolver_outputs.cstore.crates_untracked();
let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0);
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
providers[LOCAL_CRATE] = local_providers;
queries.get_or_init(|| query::Queries::new(providers, extern_providers))
};
let gcx = sess.time("setup_global_ctxt", || {
global_ctxt.get_or_init(|| {
TyCtxt::create_global_ctxt(
sess,
lint_store,
local_providers,
extern_providers,
arena,
resolver_outputs,
krate,
defs,
dep_graph,
query_result_on_disk_cache,
queries,
&crate_name,
&outputs,
)
})
});
QueryContext(gcx)
QueryContext { gcx }
}
/// Runs the resolution, type-checking, region checking and other

View File

@ -13,6 +13,7 @@ use rustc_incremental::DepGraphFuture;
use rustc_lint::LintStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::ty::query;
use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt};
use rustc_serialize::json;
use rustc_session::config::{self, OutputFilenames, OutputType};
@ -71,6 +72,7 @@ impl<T> Default for Query<T> {
pub struct Queries<'tcx> {
compiler: &'tcx Compiler,
gcx: OnceCell<GlobalCtxt<'tcx>>,
queries: OnceCell<query::Queries<'tcx>>,
arena: WorkerLocal<Arena<'tcx>>,
hir_arena: WorkerLocal<rustc_ast_lowering::Arena<'tcx>>,
@ -92,6 +94,7 @@ impl<'tcx> Queries<'tcx> {
Queries {
compiler,
gcx: OnceCell::new(),
queries: OnceCell::new(),
arena: WorkerLocal::new(|_| Arena::default()),
hir_arena: WorkerLocal::new(|_| rustc_ast_lowering::Arena::default()),
dep_graph_future: Default::default(),
@ -265,6 +268,7 @@ impl<'tcx> Queries<'tcx> {
resolver_outputs.steal(),
outputs,
&crate_name,
&self.queries,
&self.gcx,
&self.arena,
))
@ -429,7 +433,7 @@ impl Compiler {
}
if self.session().opts.debugging_opts.query_stats {
gcx.print_stats();
gcx.enter(query::print_stats);
}
}

View File

@ -354,10 +354,9 @@ fn add_query_description_impl(
quote! {
#[inline]
fn try_load_from_disk(
tcx: QueryCtxt<'tcx>,
id: SerializedDepNodeIndex
#tcx: QueryCtxt<'tcx>,
#id: SerializedDepNodeIndex
) -> Option<Self::Value> {
let (#tcx, #id) = (*tcx, id);
#block
}
}
@ -394,11 +393,10 @@ fn add_query_description_impl(
#[inline]
#[allow(unused_variables, unused_braces)]
fn cache_on_disk(
tcx: QueryCtxt<'tcx>,
key: &Self::Key,
value: Option<&Self::Value>
#tcx: QueryCtxt<'tcx>,
#key: &Self::Key,
#value: Option<&Self::Value>
) -> bool {
let (#tcx, #key, #value) = (*tcx, key, value);
#expr
}

View File

@ -262,7 +262,7 @@ pub mod dep_kind {
if let Some(key) = recover(tcx, dep_node) {
force_query::<queries::$variant<'_>, _>(
QueryCtxt(tcx),
QueryCtxt { tcx, queries: tcx.queries },
key,
DUMMY_SP,
*dep_node
@ -288,7 +288,8 @@ pub mod dep_kind {
.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));
if queries::$variant::cache_on_disk(QueryCtxt(tcx), &key, None) {
let qcx = QueryCtxt { tcx, queries: tcx.queries };
if queries::$variant::cache_on_disk(qcx, &key, None) {
let _ = tcx.$variant(key);
}
}

View File

@ -699,7 +699,7 @@ rustc_queries! {
load_cached(tcx, id) {
let typeck_results: Option<ty::TypeckResults<'tcx>> = tcx
.on_disk_cache.as_ref()
.and_then(|c| c.try_load_query_result(tcx, id));
.and_then(|c| c.try_load_query_result(*tcx, id));
typeck_results.map(|x| &*tcx.arena.alloc(x))
}

View File

@ -14,7 +14,7 @@ use crate::middle::stability;
use crate::mir::interpret::{self, Allocation, ConstValue, Scalar};
use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
use crate::traits;
use crate::ty::query::{self, OnDiskCache, TyCtxtAt};
use crate::ty::query::{self, OnDiskCache, Queries, TyCtxtAt};
use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts};
use crate::ty::TyKind::*;
use crate::ty::{
@ -968,7 +968,7 @@ pub struct GlobalCtxt<'tcx> {
/// This is `None` if we are not incremental compilation mode
pub(crate) on_disk_cache: Option<OnDiskCache<'tcx>>,
pub queries: query::Queries<'tcx>,
pub queries: &'tcx query::Queries<'tcx>,
pub query_caches: query::QueryCaches<'tcx>,
maybe_unused_trait_imports: FxHashSet<LocalDefId>,
@ -1109,14 +1109,13 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn create_global_ctxt(
s: &'tcx Session,
lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
local_providers: ty::query::Providers,
extern_providers: ty::query::Providers,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
resolutions: ty::ResolverOutputs,
krate: &'tcx hir::Crate<'tcx>,
definitions: &'tcx Definitions,
dep_graph: DepGraph,
on_disk_cache: Option<query::OnDiskCache<'tcx>>,
queries: &'tcx Queries<'tcx>,
crate_name: &str,
output_filenames: &OutputFilenames,
) -> GlobalCtxt<'tcx> {
@ -1128,10 +1127,6 @@ impl<'tcx> TyCtxt<'tcx> {
let common_lifetimes = CommonLifetimes::new(&interners);
let common_consts = CommonConsts::new(&interners, &common_types);
let cstore = resolutions.cstore;
let crates = cstore.crates_untracked();
let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0);
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
providers[LOCAL_CRATE] = local_providers;
let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
for (hir_id, v) in krate.trait_map.iter() {
@ -1161,7 +1156,7 @@ impl<'tcx> TyCtxt<'tcx> {
untracked_crate: krate,
definitions,
on_disk_cache,
queries: query::Queries::new(providers, extern_providers),
queries,
query_caches: query::QueryCaches::default(),
ty_rcache: Default::default(),
pred_rcache: Default::default(),

View File

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

View File

@ -44,6 +44,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
use rustc_hir::lang_items::{LangItem, LanguageItems};
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
use rustc_serialize::opaque;
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
use rustc_session::utils::NativeLibKind;
use rustc_session::CrateDisambiguator;

View File

@ -133,7 +133,7 @@ struct Footer {
foreign_def_path_hashes: UnhashMap<DefPathHash, RawDefId>,
}
type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
pub type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
type EncodedDiagnosticsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
type EncodedDiagnostics = Vec<Diagnostic>;
@ -141,7 +141,7 @@ type EncodedDiagnostics = Vec<Diagnostic>;
struct SourceFileIndex(u32);
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Encodable, Decodable)]
struct AbsoluteBytePos(u32);
pub struct AbsoluteBytePos(u32);
impl AbsoluteBytePos {
fn new(pos: usize) -> AbsoluteBytePos {
@ -308,22 +308,7 @@ impl<'sess> OnDiskCache<'sess> {
tcx.sess.time("encode_query_results", || -> FileEncodeResult {
let enc = &mut encoder;
let qri = &mut query_result_index;
macro_rules! encode_queries {
($($query:ident,)*) => {
$(
encode_query_results::<ty::query::queries::$query<'_>>(
QueryCtxt(tcx),
enc,
qri
)?;
)*
}
}
rustc_cached_queries!(encode_queries!);
Ok(())
tcx.queries.encode_query_results(tcx, enc, qri)
})?;
// Encode diagnostics.
@ -973,7 +958,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [Span] {
//- ENCODING -------------------------------------------------------------------
trait OpaqueEncoder: Encoder {
pub trait OpaqueEncoder: Encoder {
fn position(&self) -> usize;
}
@ -985,7 +970,7 @@ impl OpaqueEncoder for FileEncoder {
}
/// An encoder that can write to the incremental compilation cache.
struct CacheEncoder<'a, 'tcx, E: OpaqueEncoder> {
pub struct CacheEncoder<'a, 'tcx, E: OpaqueEncoder> {
tcx: TyCtxt<'tcx>,
encoder: &'a mut E,
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
@ -1230,7 +1215,7 @@ impl<'a> Decodable<opaque::Decoder<'a>> for IntEncodedWithFixedSize {
}
}
fn encode_query_results<'a, 'tcx, Q>(
pub fn encode_query_results<'a, 'tcx, Q>(
tcx: QueryCtxt<'tcx>,
encoder: &mut CacheEncoder<'a, 'tcx, FileEncoder>,
query_result_index: &mut EncodedQueryResultIndex,

View File

@ -2,7 +2,7 @@
//! generate the actual methods on tcx which find and execute the provider,
//! manage the caches, and so forth.
use crate::ty::query::Query;
use crate::ty::query::{on_disk_cache, Query};
use crate::ty::tls::{self, ImplicitCtxt};
use crate::ty::{self, TyCtxt};
use rustc_query_system::dep_graph::HasDepContext;
@ -13,17 +13,21 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lock;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Level};
use rustc_serialize::opaque;
use rustc_span::def_id::DefId;
use rustc_span::Span;
#[derive(Copy, Clone)]
pub struct QueryCtxt<'tcx>(pub TyCtxt<'tcx>);
pub struct QueryCtxt<'tcx> {
pub tcx: TyCtxt<'tcx>,
pub queries: &'tcx super::Queries<'tcx>,
}
impl<'tcx> std::ops::Deref for QueryCtxt<'tcx> {
type Target = TyCtxt<'tcx>;
fn deref(&self) -> &Self::Target {
&self.0
&self.tcx
}
}
@ -34,7 +38,7 @@ impl HasDepContext for QueryCtxt<'tcx> {
#[inline]
fn dep_context(&self) -> &Self::DepContext {
&self.0
&self.tcx
}
}
@ -49,7 +53,7 @@ impl QueryContext for QueryCtxt<'tcx> {
}
fn def_path_str(&self, def_id: DefId) -> String {
self.0.def_path_str(def_id)
self.tcx.def_path_str(def_id)
}
fn current_query_job(&self) -> Option<QueryJobId<Self::DepKind>> {
@ -142,6 +146,28 @@ impl<'tcx> QueryCtxt<'tcx> {
err
})
}
pub(super) fn encode_query_results(
self,
encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>,
query_result_index: &mut on_disk_cache::EncodedQueryResultIndex,
) -> opaque::FileEncodeResult {
macro_rules! encode_queries {
($($query:ident,)*) => {
$(
on_disk_cache::encode_query_results::<ty::query::queries::$query<'_>>(
self,
encoder,
query_result_index
)?;
)*
}
}
rustc_cached_queries!(encode_queries!);
Ok(())
}
}
impl<'tcx> TyCtxt<'tcx> {
@ -174,7 +200,10 @@ impl<'tcx> TyCtxt<'tcx> {
"#{} [{}] {}",
i,
query_info.info.query.name(),
query_info.info.query.describe(QueryCtxt(icx.tcx))
query_info
.info
.query
.describe(QueryCtxt { tcx: icx.tcx, queries: icx.tcx.queries })
),
);
diag.span =
@ -570,7 +599,7 @@ macro_rules! define_queries_struct {
}
impl<$tcx> Queries<$tcx> {
pub(crate) fn new(
pub fn new(
providers: IndexVec<CrateNum, Providers>,
fallback_extern_providers: Providers,
) -> Self {
@ -597,17 +626,33 @@ macro_rules! define_queries_struct {
Some(jobs)
}
#[cfg(parallel_compiler)]
unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry) {
let tcx = QueryCtxt { tcx, queries: self };
rustc_query_system::query::deadlock(tcx, registry)
}
pub(crate) fn encode_query_results(
&'tcx self,
tcx: TyCtxt<'tcx>,
encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>,
query_result_index: &mut on_disk_cache::EncodedQueryResultIndex,
) -> opaque::FileEncodeResult {
let tcx = QueryCtxt { tcx, queries: self };
tcx.encode_query_results(encoder, query_result_index)
}
$($(#[$attr])*
#[inline(always)]
fn $name(
&self,
&'tcx self,
tcx: TyCtxt<$tcx>,
span: Span,
key: query_keys::$name<$tcx>,
lookup: QueryLookup,
mode: QueryMode,
) -> Option<query_stored::$name<$tcx>> {
let qcx = QueryCtxt(tcx);
let qcx = QueryCtxt { tcx, queries: self };
get_query::<queries::$name<$tcx>, _>(qcx, span, key, lookup, mode)
})*
}