From 71f749a683731421c31591ea09f2623ef498c47a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 18 Jan 2021 22:32:20 +0100 Subject: [PATCH] Introduce a QueryEngine trait object. --- compiler/rustc_middle/src/ty/context.rs | 6 +- compiler/rustc_middle/src/ty/query/mod.rs | 39 ++++++- .../rustc_middle/src/ty/query/plumbing.rs | 101 +++++++++--------- 3 files changed, 92 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ec680eeb30f..6c1e09b9bf9 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -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, Queries, TyCtxtAt}; +use crate::ty::query::{self, OnDiskCache, 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>, - pub queries: &'tcx query::Queries<'tcx>, + pub queries: &'tcx dyn query::QueryEngine<'tcx>, pub query_caches: query::QueryCaches<'tcx>, maybe_unused_trait_imports: FxHashSet, @@ -1115,7 +1115,7 @@ impl<'tcx> TyCtxt<'tcx> { definitions: &'tcx Definitions, dep_graph: DepGraph, on_disk_cache: Option>, - queries: &'tcx Queries<'tcx>, + queries: &'tcx dyn query::QueryEngine<'tcx>, crate_name: &str, output_filenames: &OutputFilenames, ) -> GlobalCtxt<'tcx> { diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index faef1f048cc..0abd5676557 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -37,7 +37,7 @@ use rustc_data_structures::stable_hasher::StableVec; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; -use rustc_errors::ErrorReported; +use rustc_errors::{Diagnostic, ErrorReported, Handler, Level}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId}; @@ -122,8 +122,7 @@ impl TyCtxt<'tcx> { } pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool { - let qcx = QueryCtxt { tcx: self, queries: self.queries }; - self.dep_graph.try_mark_green(qcx, dep_node).is_some() + self.queries.try_mark_green(self, dep_node) } } @@ -240,6 +239,40 @@ macro_rules! define_callbacks { impl Clone for Providers { fn clone(&self) -> Self { *self } } + + pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync { + #[cfg(parallel_compiler)] + unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry); + + 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; + + fn exec_cache_promotions(&'tcx self, tcx: TyCtxt<'tcx>); + + fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool; + + fn try_print_query_stack( + &'tcx self, + tcx: TyCtxt<'tcx>, + query: Option>, + handler: &Handler, + num_frames: Option, + ) -> usize; + + $($(#[$attr])* + fn $name( + &'tcx self, + tcx: TyCtxt<$tcx>, + span: Span, + key: query_keys::$name<$tcx>, + lookup: QueryLookup, + mode: QueryMode, + ) -> Option>;)* + } }; } diff --git a/compiler/rustc_middle/src/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index 53bac4181e6..79900fc7636 100644 --- a/compiler/rustc_middle/src/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs @@ -2,8 +2,8 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::dep_graph::{self, DepKind, DepNode, DepNodeExt, DepNodeIndex, SerializedDepNodeIndex}; -use crate::ty::query::{on_disk_cache, queries, Queries, Query}; +use crate::dep_graph::{DepKind, DepNode, DepNodeExt, DepNodeIndex, SerializedDepNodeIndex}; +use crate::ty::query::{on_disk_cache, queries, Query}; use crate::ty::tls::{self, ImplicitCtxt}; use crate::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::HasDepContext; @@ -13,7 +13,7 @@ use rustc_query_system::query::{QueryContext, QueryDescription}; 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_errors::{struct_span_err, Diagnostic, DiagnosticBuilder}; use rustc_serialize::opaque; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; @@ -266,49 +266,6 @@ impl<'tcx> QueryCtxt<'tcx> { } } -impl<'tcx> Queries<'tcx> { - pub fn try_print_query_stack( - &'tcx self, - tcx: TyCtxt<'tcx>, - query: Option>, - handler: &Handler, - num_frames: Option, - ) -> usize { - let query_map = self.try_collect_active_jobs(); - - let mut current_query = query; - let mut i = 0; - - while let Some(query) = current_query { - if Some(i) == num_frames { - break; - } - let query_info = if let Some(info) = query_map.as_ref().and_then(|map| map.get(&query)) - { - info - } else { - break; - }; - let mut diag = Diagnostic::new( - Level::FailureNote, - &format!( - "#{} [{}] {}", - i, - query_info.info.query.name(), - query_info.info.query.describe(QueryCtxt { tcx, queries: self }) - ), - ); - diag.span = tcx.sess.source_map().guess_head_span(query_info.info.span).into(); - handler.force_print_diagnostic(diag); - - current_query = query_info.job.parent; - i += 1; - } - - i - } -} - /// This struct stores metadata about each Query. /// /// Information is retrieved by indexing the `QUERIES` array using the integer value @@ -689,14 +646,16 @@ macro_rules! define_queries_struct { Some(jobs) } + } + impl QueryEngine<'tcx> for Queries<'tcx> { #[cfg(parallel_compiler)] - pub unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry) { + 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( + fn encode_query_results( &'tcx self, tcx: TyCtxt<'tcx>, encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>, @@ -711,6 +670,52 @@ macro_rules! define_queries_struct { tcx.dep_graph.exec_cache_promotions(tcx) } + fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool { + let qcx = QueryCtxt { tcx, queries: self }; + tcx.dep_graph.try_mark_green(qcx, dep_node).is_some() + } + + fn try_print_query_stack( + &'tcx self, + tcx: TyCtxt<'tcx>, + query: Option>, + handler: &Handler, + num_frames: Option, + ) -> usize { + let query_map = self.try_collect_active_jobs(); + + let mut current_query = query; + let mut i = 0; + + while let Some(query) = current_query { + if Some(i) == num_frames { + break; + } + let query_info = if let Some(info) = query_map.as_ref().and_then(|map| map.get(&query)) + { + info + } else { + break; + }; + let mut diag = Diagnostic::new( + Level::FailureNote, + &format!( + "#{} [{}] {}", + i, + query_info.info.query.name(), + query_info.info.query.describe(QueryCtxt { tcx, queries: self }) + ), + ); + diag.span = tcx.sess.source_map().guess_head_span(query_info.info.span).into(); + handler.force_print_diagnostic(diag); + + current_query = query_info.job.parent; + i += 1; + } + + i + } + $($(#[$attr])* #[inline(always)] fn $name(