Avoid a branch on key being local for queries that use the same local and extern providers

This commit is contained in:
bjorn3 2021-05-30 17:24:54 +02:00
parent 56694b0453
commit f5c3e83013
11 changed files with 189 additions and 27 deletions

View File

@ -11,7 +11,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::exported_symbols::{ use rustc_middle::middle::exported_symbols::{
metadata_symbol_name, ExportedSymbol, SymbolExportLevel, metadata_symbol_name, ExportedSymbol, SymbolExportLevel,
}; };
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::Instance; use rustc_middle::ty::Instance;
use rustc_middle::ty::{SymbolName, TyCtxt}; use rustc_middle::ty::{SymbolName, TyCtxt};
@ -363,7 +363,7 @@ pub fn provide(providers: &mut Providers) {
providers.wasm_import_module_map = wasm_import_module_map; providers.wasm_import_module_map = wasm_import_module_map;
} }
pub fn provide_extern(providers: &mut Providers) { pub fn provide_extern(providers: &mut ExternProviders) {
providers.is_reachable_non_generic = is_reachable_non_generic_provider_extern; providers.is_reachable_non_generic = is_reachable_non_generic_provider_extern;
providers.upstream_monomorphizations_for = upstream_monomorphizations_for_provider; providers.upstream_monomorphizations_for = upstream_monomorphizations_for_provider;
} }

View File

@ -28,7 +28,7 @@ use rustc_hir::def_id::CrateNum;
use rustc_hir::LangItem; use rustc_hir::LangItem;
use rustc_middle::dep_graph::WorkProduct; use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::middle::dependency_format::Dependencies;
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT}; use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT};
use rustc_session::cstore::{self, CrateSource}; use rustc_session::cstore::{self, CrateSource};
use rustc_session::utils::NativeLibKind; use rustc_session::utils::NativeLibKind;
@ -170,7 +170,7 @@ pub fn provide(providers: &mut Providers) {
crate::target_features::provide(providers); crate::target_features::provide(providers);
} }
pub fn provide_extern(providers: &mut Providers) { pub fn provide_extern(providers: &mut ExternProviders) {
crate::back::symbol_export::provide_extern(providers); crate::back::symbol_export::provide_extern(providers);
} }

View File

@ -9,7 +9,7 @@ use rustc_errors::ErrorReported;
use rustc_metadata::EncodedMetadata; use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout};
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::ty::{Ty, TyCtxt};
use rustc_session::{ use rustc_session::{
config::{self, OutputFilenames, PrintRequest}, config::{self, OutputFilenames, PrintRequest},
@ -80,7 +80,7 @@ pub trait CodegenBackend {
} }
fn provide(&self, _providers: &mut Providers) {} fn provide(&self, _providers: &mut Providers) {}
fn provide_extern(&self, _providers: &mut Providers) {} fn provide_extern(&self, _providers: &mut ExternProviders) {}
fn codegen_crate<'tcx>( fn codegen_crate<'tcx>(
&self, &self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,

View File

@ -38,7 +38,7 @@ pub struct Compiler {
pub(crate) output_file: Option<PathBuf>, pub(crate) output_file: Option<PathBuf>,
pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>, pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>,
pub(crate) override_queries: pub(crate) override_queries:
Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::Providers)>, Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::ExternProviders)>,
} }
impl Compiler { impl Compiler {
@ -155,7 +155,7 @@ pub struct Config {
/// ///
/// The second parameter is local providers and the third parameter is external providers. /// The second parameter is local providers and the third parameter is external providers.
pub override_queries: pub override_queries:
Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::Providers)>, Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::ExternProviders)>,
/// This is a callback from the driver that is called to create a codegen backend. /// This is a callback from the driver that is called to create a codegen backend.
pub make_codegen_backend: pub make_codegen_backend:

View File

@ -19,7 +19,7 @@ use rustc_metadata::creader::CStore;
use rustc_metadata::{encode_metadata, EncodedMetadata}; use rustc_metadata::{encode_metadata, EncodedMetadata};
use rustc_middle::arena::Arena; use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph; use rustc_middle::dep_graph::DepGraph;
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt}; use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
use rustc_mir_build as mir_build; use rustc_mir_build as mir_build;
use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr}; use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr};
@ -764,8 +764,8 @@ pub static DEFAULT_QUERY_PROVIDERS: SyncLazy<Providers> = SyncLazy::new(|| {
*providers *providers
}); });
pub static DEFAULT_EXTERN_QUERY_PROVIDERS: SyncLazy<Providers> = SyncLazy::new(|| { pub static DEFAULT_EXTERN_QUERY_PROVIDERS: SyncLazy<ExternProviders> = SyncLazy::new(|| {
let mut extern_providers = *DEFAULT_QUERY_PROVIDERS; let mut extern_providers = ExternProviders::default();
rustc_metadata::provide_extern(&mut extern_providers); rustc_metadata::provide_extern(&mut extern_providers);
rustc_codegen_ssa::provide_extern(&mut extern_providers); rustc_codegen_ssa::provide_extern(&mut extern_providers);
extern_providers extern_providers
@ -816,7 +816,6 @@ pub fn create_global_ctxt<'tcx>(
codegen_backend.provide(&mut local_providers); codegen_backend.provide(&mut local_providers);
let mut extern_providers = *DEFAULT_EXTERN_QUERY_PROVIDERS; let mut extern_providers = *DEFAULT_EXTERN_QUERY_PROVIDERS;
codegen_backend.provide(&mut extern_providers);
codegen_backend.provide_extern(&mut extern_providers); codegen_backend.provide_extern(&mut extern_providers);
if let Some(callback) = compiler.override_queries { if let Some(callback) = compiler.override_queries {

View File

@ -55,6 +55,9 @@ enum QueryModifier {
/// Always evaluate the query, ignoring its dependencies /// Always evaluate the query, ignoring its dependencies
EvalAlways(Ident), EvalAlways(Ident),
/// Use a separate query provider for local and extern crates
SeparateProvideExtern(Ident),
} }
impl Parse for QueryModifier { impl Parse for QueryModifier {
@ -118,6 +121,8 @@ impl Parse for QueryModifier {
Ok(QueryModifier::Anon(modifier)) Ok(QueryModifier::Anon(modifier))
} else if modifier == "eval_always" { } else if modifier == "eval_always" {
Ok(QueryModifier::EvalAlways(modifier)) Ok(QueryModifier::EvalAlways(modifier))
} else if modifier == "separate_provide_extern" {
Ok(QueryModifier::SeparateProvideExtern(modifier))
} else { } else {
Err(Error::new(modifier.span(), "unknown query modifier")) Err(Error::new(modifier.span(), "unknown query modifier"))
} }
@ -214,6 +219,9 @@ struct QueryModifiers {
// Always evaluate the query, ignoring its dependencies // Always evaluate the query, ignoring its dependencies
eval_always: Option<Ident>, eval_always: Option<Ident>,
/// Use a separate query provider for local and extern crates
separate_provide_extern: Option<Ident>,
} }
/// Process query modifiers into a struct, erroring on duplicates /// Process query modifiers into a struct, erroring on duplicates
@ -227,6 +235,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
let mut no_hash = None; let mut no_hash = None;
let mut anon = None; let mut anon = None;
let mut eval_always = None; let mut eval_always = None;
let mut separate_provide_extern = None;
for modifier in query.modifiers.0.drain(..) { for modifier in query.modifiers.0.drain(..) {
match modifier { match modifier {
QueryModifier::LoadCached(tcx, id, block) => { QueryModifier::LoadCached(tcx, id, block) => {
@ -317,6 +326,15 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
} }
eval_always = Some(ident); eval_always = Some(ident);
} }
QueryModifier::SeparateProvideExtern(ident) => {
if separate_provide_extern.is_some() {
panic!(
"duplicate modifier `separate_provide_extern` for query `{}`",
query.name
);
}
separate_provide_extern = Some(ident);
}
} }
} }
let desc = desc.unwrap_or_else(|| { let desc = desc.unwrap_or_else(|| {
@ -332,6 +350,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
no_hash, no_hash,
anon, anon,
eval_always, eval_always,
separate_provide_extern,
} }
} }
@ -462,6 +481,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
if let Some(eval_always) = &modifiers.eval_always { if let Some(eval_always) = &modifiers.eval_always {
attributes.push(quote! { (#eval_always) }); attributes.push(quote! { (#eval_always) });
}; };
// Pass on the separate_provide_extern modifier
if let Some(separate_provide_extern) = &modifiers.separate_provide_extern {
attributes.push(quote! { (#separate_provide_extern) });
}
// This uses the span of the query definition for the commas, // This uses the span of the query definition for the commas,
// which can be important if we later encounter any ambiguity // which can be important if we later encounter any ambiguity

View File

@ -10,7 +10,7 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
use rustc_middle::hir::exports::Export; use rustc_middle::hir::exports::Export;
use rustc_middle::middle::exported_symbols::ExportedSymbol; use rustc_middle::middle::exported_symbols::ExportedSymbol;
use rustc_middle::middle::stability::DeprecationEntry; use rustc_middle::middle::stability::DeprecationEntry;
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::{self, TyCtxt, Visibility}; use rustc_middle::ty::{self, TyCtxt, Visibility};
use rustc_session::cstore::{CrateSource, CrateStore, ForeignModule}; use rustc_session::cstore::{CrateSource, CrateStore, ForeignModule};
use rustc_session::utils::NativeLibKind; use rustc_session::utils::NativeLibKind;
@ -26,7 +26,7 @@ use std::any::Any;
macro_rules! provide { macro_rules! provide {
(<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident, (<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
$($name:ident => $compute:block)*) => { $($name:ident => $compute:block)*) => {
pub fn provide_extern(providers: &mut Providers) { pub fn provide_extern(providers: &mut ExternProviders) {
$(fn $name<$lt>( $(fn $name<$lt>(
$tcx: TyCtxt<$lt>, $tcx: TyCtxt<$lt>,
def_id_arg: ty::query::query_keys::$name<$lt>, def_id_arg: ty::query::query_keys::$name<$lt>,
@ -51,7 +51,7 @@ macro_rules! provide {
$compute $compute
})* })*
*providers = Providers { *providers = ExternProviders {
$($name,)* $($name,)*
..*providers ..*providers
}; };

View File

@ -107,6 +107,7 @@ rustc_queries! {
/// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`. /// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
query const_param_default(param: DefId) -> &'tcx ty::Const<'tcx> { query const_param_default(param: DefId) -> &'tcx ty::Const<'tcx> {
desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) } desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) }
separate_provide_extern
} }
query default_anon_const_substs(key: DefId) -> SubstsRef<'tcx> { query default_anon_const_substs(key: DefId) -> SubstsRef<'tcx> {
@ -128,6 +129,7 @@ rustc_queries! {
path = tcx.def_path_str(key), path = tcx.def_path_str(key),
} }
cache_on_disk_if { key.is_local() } cache_on_disk_if { key.is_local() }
separate_provide_extern
} }
query analysis(key: ()) -> Result<(), ErrorReported> { query analysis(key: ()) -> Result<(), ErrorReported> {
@ -141,6 +143,7 @@ rustc_queries! {
desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) } desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) }
storage(ArenaCacheSelector<'tcx>) storage(ArenaCacheSelector<'tcx>)
cache_on_disk_if { key.is_local() } cache_on_disk_if { key.is_local() }
separate_provide_extern
} }
/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
@ -181,6 +184,7 @@ rustc_queries! {
/// Bounds from the parent (e.g. with nested impl trait) are not included. /// Bounds from the parent (e.g. with nested impl trait) are not included.
query explicit_item_bounds(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] { query explicit_item_bounds(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
/// Elaborated version of the predicates from `explicit_item_bounds`. /// Elaborated version of the predicates from `explicit_item_bounds`.
@ -209,6 +213,7 @@ rustc_queries! {
query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLib>> { query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLib>> {
desc { "looking up the native libraries of a linked crate" } desc { "looking up the native libraries of a linked crate" }
separate_provide_extern
} }
query lint_levels(_: ()) -> LintLevelMap { query lint_levels(_: ()) -> LintLevelMap {
@ -226,11 +231,13 @@ rustc_queries! {
// This query reads from untracked data in definitions. // This query reads from untracked data in definitions.
eval_always eval_always
desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) } desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
query is_panic_runtime(_: CrateNum) -> bool { query is_panic_runtime(_: CrateNum) -> bool {
fatal_cycle fatal_cycle
desc { "checking if the crate is_panic_runtime" } desc { "checking if the crate is_panic_runtime" }
separate_provide_extern
} }
/// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`. /// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`.
@ -260,6 +267,7 @@ rustc_queries! {
query mir_const_qualif(key: DefId) -> mir::ConstQualifs { query mir_const_qualif(key: DefId) -> mir::ConstQualifs {
desc { |tcx| "const checking `{}`", tcx.def_path_str(key) } desc { |tcx| "const checking `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() } cache_on_disk_if { key.is_local() }
separate_provide_extern
} }
query mir_const_qualif_const_arg( query mir_const_qualif_const_arg(
key: (LocalDefId, DefId) key: (LocalDefId, DefId)
@ -296,6 +304,7 @@ rustc_queries! {
desc { desc {
|tcx| "building an abstract representation for {}", tcx.def_path_str(key), |tcx| "building an abstract representation for {}", tcx.def_path_str(key),
} }
separate_provide_extern
} }
/// Try to build an abstract representation of the given constant. /// Try to build an abstract representation of the given constant.
query thir_abstract_const_of_const_arg( query thir_abstract_const_of_const_arg(
@ -329,6 +338,7 @@ rustc_queries! {
) -> &'tcx mir::Body<'tcx> { ) -> &'tcx mir::Body<'tcx> {
desc { |tcx| "caching mir of `{}` for CTFE", tcx.def_path_str(key) } desc { |tcx| "caching mir of `{}` for CTFE", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() } cache_on_disk_if { key.is_local() }
separate_provide_extern
} }
query mir_for_ctfe_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> { query mir_for_ctfe_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> {
@ -366,6 +376,7 @@ rustc_queries! {
query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> { query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> {
desc { |tcx| "optimizing MIR for `{}`", tcx.def_path_str(key) } desc { |tcx| "optimizing MIR for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() } cache_on_disk_if { key.is_local() }
separate_provide_extern
} }
/// Returns coverage summary info for a function, after executing the `InstrumentCoverage` /// Returns coverage summary info for a function, after executing the `InstrumentCoverage`
@ -404,6 +415,7 @@ rustc_queries! {
query promoted_mir(key: DefId) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> { query promoted_mir(key: DefId) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> {
desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) } desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() } cache_on_disk_if { key.is_local() }
separate_provide_extern
} }
query promoted_mir_of_const_arg( query promoted_mir_of_const_arg(
key: (LocalDefId, DefId) key: (LocalDefId, DefId)
@ -462,12 +474,14 @@ rustc_queries! {
/// Returns the predicates written explicitly by the user. /// Returns the predicates written explicitly by the user.
query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) } desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
/// Returns the inferred outlives predicates (e.g., for `struct /// Returns the inferred outlives predicates (e.g., for `struct
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`). /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] { query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) } desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
/// Maps from the `DefId` of a trait to the list of /// Maps from the `DefId` of a trait to the list of
@ -478,6 +492,7 @@ rustc_queries! {
/// additional acyclicity requirements). /// additional acyclicity requirements).
query super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { query super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) } desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
/// The `Option<Ident>` is the name of an associated type. If it is `None`, then this query /// The `Option<Ident>` is the name of an associated type. If it is `None`, then this query
@ -503,12 +518,15 @@ rustc_queries! {
query trait_def(key: DefId) -> ty::TraitDef { query trait_def(key: DefId) -> ty::TraitDef {
desc { |tcx| "computing trait definition for `{}`", tcx.def_path_str(key) } desc { |tcx| "computing trait definition for `{}`", tcx.def_path_str(key) }
storage(ArenaCacheSelector<'tcx>) storage(ArenaCacheSelector<'tcx>)
separate_provide_extern
} }
query adt_def(key: DefId) -> &'tcx ty::AdtDef { query adt_def(key: DefId) -> &'tcx ty::AdtDef {
desc { |tcx| "computing ADT definition for `{}`", tcx.def_path_str(key) } desc { |tcx| "computing ADT definition for `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
query adt_destructor(key: DefId) -> Option<ty::Destructor> { query adt_destructor(key: DefId) -> Option<ty::Destructor> {
desc { |tcx| "computing `Drop` impl for `{}`", tcx.def_path_str(key) } desc { |tcx| "computing `Drop` impl for `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
// The cycle error here should be reported as an error by `check_representable`. // The cycle error here should be reported as an error by `check_representable`.
@ -537,10 +555,12 @@ rustc_queries! {
/// `is_const_fn` function. /// `is_const_fn` function.
query is_const_fn_raw(key: DefId) -> bool { query is_const_fn_raw(key: DefId) -> bool {
desc { |tcx| "checking if item is const fn: `{}`", tcx.def_path_str(key) } desc { |tcx| "checking if item is const fn: `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
query asyncness(key: DefId) -> hir::IsAsync { query asyncness(key: DefId) -> hir::IsAsync {
desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) } desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
/// Returns `true` if calls to the function may be promoted. /// Returns `true` if calls to the function may be promoted.
@ -557,16 +577,19 @@ rustc_queries! {
/// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`). /// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`).
query is_foreign_item(key: DefId) -> bool { query is_foreign_item(key: DefId) -> bool {
desc { |tcx| "checking if `{}` is a foreign item", tcx.def_path_str(key) } desc { |tcx| "checking if `{}` is a foreign item", tcx.def_path_str(key) }
separate_provide_extern
} }
/// Returns `Some(mutability)` if the node pointed to by `def_id` is a static item. /// Returns `Some(mutability)` if the node pointed to by `def_id` is a static item.
query static_mutability(def_id: DefId) -> Option<hir::Mutability> { query static_mutability(def_id: DefId) -> Option<hir::Mutability> {
desc { |tcx| "looking up static mutability of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "looking up static mutability of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
/// Returns `Some(generator_kind)` if the node pointed to by `def_id` is a generator. /// Returns `Some(generator_kind)` if the node pointed to by `def_id` is a generator.
query generator_kind(def_id: DefId) -> Option<hir::GeneratorKind> { query generator_kind(def_id: DefId) -> Option<hir::GeneratorKind> {
desc { |tcx| "looking up generator kind of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "looking up generator kind of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
/// Gets a map with the variance of every item; use `item_variance` instead. /// Gets a map with the variance of every item; use `item_variance` instead.
@ -578,6 +601,7 @@ rustc_queries! {
/// Maps from the `DefId` of a type or region parameter to its (inferred) variance. /// Maps from the `DefId` of a type or region parameter to its (inferred) variance.
query variances_of(def_id: DefId) -> &'tcx [ty::Variance] { query variances_of(def_id: DefId) -> &'tcx [ty::Variance] {
desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
/// Maps from thee `DefId` of a type to its (inferred) outlives. /// Maps from thee `DefId` of a type to its (inferred) outlives.
@ -589,12 +613,14 @@ rustc_queries! {
/// Maps from an impl/trait `DefId` to a list of the `DefId`s of its items. /// Maps from an impl/trait `DefId` to a list of the `DefId`s of its items.
query associated_item_def_ids(key: DefId) -> &'tcx [DefId] { query associated_item_def_ids(key: DefId) -> &'tcx [DefId] {
desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) } desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
/// Maps from a trait item to the trait item "descriptor". /// Maps from a trait item to the trait item "descriptor".
query associated_item(key: DefId) -> ty::AssocItem { query associated_item(key: DefId) -> ty::AssocItem {
desc { |tcx| "computing associated item data for `{}`", tcx.def_path_str(key) } desc { |tcx| "computing associated item data for `{}`", tcx.def_path_str(key) }
storage(ArenaCacheSelector<'tcx>) storage(ArenaCacheSelector<'tcx>)
separate_provide_extern
} }
/// Collects the associated items defined on a trait or impl. /// Collects the associated items defined on a trait or impl.
@ -607,9 +633,11 @@ rustc_queries! {
/// Return `None` if this is an inherent impl. /// Return `None` if this is an inherent impl.
query impl_trait_ref(impl_id: DefId) -> Option<ty::TraitRef<'tcx>> { query impl_trait_ref(impl_id: DefId) -> Option<ty::TraitRef<'tcx>> {
desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) } desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) }
separate_provide_extern
} }
query impl_polarity(impl_id: DefId) -> ty::ImplPolarity { query impl_polarity(impl_id: DefId) -> ty::ImplPolarity {
desc { |tcx| "computing implementation polarity of `{}`", tcx.def_path_str(impl_id) } desc { |tcx| "computing implementation polarity of `{}`", tcx.def_path_str(impl_id) }
separate_provide_extern
} }
query issue33140_self_ty(key: DefId) -> Option<ty::Ty<'tcx>> { query issue33140_self_ty(key: DefId) -> Option<ty::Ty<'tcx>> {
@ -622,6 +650,7 @@ rustc_queries! {
query inherent_impls(key: DefId) -> &'tcx [DefId] { query inherent_impls(key: DefId) -> &'tcx [DefId] {
desc { |tcx| "collecting inherent impls for `{}`", tcx.def_path_str(key) } desc { |tcx| "collecting inherent impls for `{}`", tcx.def_path_str(key) }
eval_always eval_always
separate_provide_extern
} }
/// The result of unsafety-checking this `LocalDefId`. /// The result of unsafety-checking this `LocalDefId`.
@ -661,6 +690,7 @@ rustc_queries! {
/// The signature of functions. /// The signature of functions.
query fn_sig(key: DefId) -> ty::PolyFnSig<'tcx> { query fn_sig(key: DefId) -> ty::PolyFnSig<'tcx> {
desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) } desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
query lint_mod(key: LocalDefId) -> () { query lint_mod(key: LocalDefId) -> () {
@ -715,10 +745,10 @@ rustc_queries! {
} }
/// Caches `CoerceUnsized` kinds for impls on custom types. /// Caches `CoerceUnsized` kinds for impls on custom types.
query coerce_unsized_info(key: DefId) query coerce_unsized_info(key: DefId) -> ty::adjustment::CoerceUnsizedInfo {
-> ty::adjustment::CoerceUnsizedInfo { desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) }
desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) } separate_provide_extern
} }
query typeck_item_bodies(_: ()) -> () { query typeck_item_bodies(_: ()) -> () {
desc { "type-checking all item bodies" } desc { "type-checking all item bodies" }
@ -913,22 +943,27 @@ rustc_queries! {
query opt_def_kind(def_id: DefId) -> Option<DefKind> { query opt_def_kind(def_id: DefId) -> Option<DefKind> {
desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query def_span(def_id: DefId) -> Span { query def_span(def_id: DefId) -> Span {
desc { |tcx| "looking up span for `{}`", tcx.def_path_str(def_id) } desc { |tcx| "looking up span for `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query def_ident_span(def_id: DefId) -> Option<Span> { query def_ident_span(def_id: DefId) -> Option<Span> {
desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) } desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query lookup_stability(def_id: DefId) -> Option<&'tcx attr::Stability> { query lookup_stability(def_id: DefId) -> Option<&'tcx attr::Stability> {
desc { |tcx| "looking up stability of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "looking up stability of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query lookup_const_stability(def_id: DefId) -> Option<&'tcx attr::ConstStability> { query lookup_const_stability(def_id: DefId) -> Option<&'tcx attr::ConstStability> {
desc { |tcx| "looking up const stability of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "looking up const stability of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query should_inherit_track_caller(def_id: DefId) -> bool { query should_inherit_track_caller(def_id: DefId) -> bool {
@ -937,10 +972,12 @@ rustc_queries! {
query lookup_deprecation_entry(def_id: DefId) -> Option<DeprecationEntry> { query lookup_deprecation_entry(def_id: DefId) -> Option<DeprecationEntry> {
desc { |tcx| "checking whether `{}` is deprecated", tcx.def_path_str(def_id) } desc { |tcx| "checking whether `{}` is deprecated", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query item_attrs(def_id: DefId) -> &'tcx [ast::Attribute] { query item_attrs(def_id: DefId) -> &'tcx [ast::Attribute] {
desc { |tcx| "collecting attributes of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "collecting attributes of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query codegen_fn_attrs(def_id: DefId) -> CodegenFnAttrs { query codegen_fn_attrs(def_id: DefId) -> CodegenFnAttrs {
@ -951,27 +988,33 @@ rustc_queries! {
query fn_arg_names(def_id: DefId) -> &'tcx [rustc_span::symbol::Ident] { query fn_arg_names(def_id: DefId) -> &'tcx [rustc_span::symbol::Ident] {
desc { |tcx| "looking up function parameter names for `{}`", tcx.def_path_str(def_id) } desc { |tcx| "looking up function parameter names for `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
/// Gets the rendered value of the specified constant or associated constant. /// Gets the rendered value of the specified constant or associated constant.
/// Used by rustdoc. /// Used by rustdoc.
query rendered_const(def_id: DefId) -> String { query rendered_const(def_id: DefId) -> String {
desc { |tcx| "rendering constant intializer of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "rendering constant intializer of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query impl_parent(def_id: DefId) -> Option<DefId> { query impl_parent(def_id: DefId) -> Option<DefId> {
desc { |tcx| "computing specialization parent impl of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "computing specialization parent impl of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
/// Given an `associated_item`, find the trait it belongs to. /// Given an `associated_item`, find the trait it belongs to.
/// Return `None` if the `DefId` is not an associated item. /// Return `None` if the `DefId` is not an associated item.
query trait_of_item(associated_item: DefId) -> Option<DefId> { query trait_of_item(associated_item: DefId) -> Option<DefId> {
desc { |tcx| "finding trait defining `{}`", tcx.def_path_str(associated_item) } desc { |tcx| "finding trait defining `{}`", tcx.def_path_str(associated_item) }
separate_provide_extern
} }
query is_ctfe_mir_available(key: DefId) -> bool { query is_ctfe_mir_available(key: DefId) -> bool {
desc { |tcx| "checking if item has ctfe mir available: `{}`", tcx.def_path_str(key) } desc { |tcx| "checking if item has ctfe mir available: `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
query is_mir_available(key: DefId) -> bool { query is_mir_available(key: DefId) -> bool {
desc { |tcx| "checking if item has mir available: `{}`", tcx.def_path_str(key) } desc { |tcx| "checking if item has mir available: `{}`", tcx.def_path_str(key) }
separate_provide_extern
} }
query own_existential_vtable_entries( query own_existential_vtable_entries(
@ -1137,6 +1180,7 @@ rustc_queries! {
query dylib_dependency_formats(_: CrateNum) query dylib_dependency_formats(_: CrateNum)
-> &'tcx [(CrateNum, LinkagePreference)] { -> &'tcx [(CrateNum, LinkagePreference)] {
desc { "dylib dependency formats of crate" } desc { "dylib dependency formats of crate" }
separate_provide_extern
} }
query dependency_formats(_: ()) -> Lrc<crate::middle::dependency_format::Dependencies> { query dependency_formats(_: ()) -> Lrc<crate::middle::dependency_format::Dependencies> {
@ -1146,41 +1190,50 @@ rustc_queries! {
query is_compiler_builtins(_: CrateNum) -> bool { query is_compiler_builtins(_: CrateNum) -> bool {
fatal_cycle fatal_cycle
desc { "checking if the crate is_compiler_builtins" } desc { "checking if the crate is_compiler_builtins" }
separate_provide_extern
} }
query has_global_allocator(_: CrateNum) -> bool { query has_global_allocator(_: CrateNum) -> bool {
// This query depends on untracked global state in CStore // This query depends on untracked global state in CStore
eval_always eval_always
fatal_cycle fatal_cycle
desc { "checking if the crate has_global_allocator" } desc { "checking if the crate has_global_allocator" }
separate_provide_extern
} }
query has_panic_handler(_: CrateNum) -> bool { query has_panic_handler(_: CrateNum) -> bool {
fatal_cycle fatal_cycle
desc { "checking if the crate has_panic_handler" } desc { "checking if the crate has_panic_handler" }
separate_provide_extern
} }
query is_profiler_runtime(_: CrateNum) -> bool { query is_profiler_runtime(_: CrateNum) -> bool {
fatal_cycle fatal_cycle
desc { "query a crate is `#![profiler_runtime]`" } desc { "query a crate is `#![profiler_runtime]`" }
separate_provide_extern
} }
query panic_strategy(_: CrateNum) -> PanicStrategy { query panic_strategy(_: CrateNum) -> PanicStrategy {
fatal_cycle fatal_cycle
desc { "query a crate's configured panic strategy" } desc { "query a crate's configured panic strategy" }
separate_provide_extern
} }
query panic_in_drop_strategy(_: CrateNum) -> PanicStrategy { query panic_in_drop_strategy(_: CrateNum) -> PanicStrategy {
fatal_cycle fatal_cycle
desc { "query a crate's configured panic-in-drop strategy" } desc { "query a crate's configured panic-in-drop strategy" }
separate_provide_extern
} }
query is_no_builtins(_: CrateNum) -> bool { query is_no_builtins(_: CrateNum) -> bool {
fatal_cycle fatal_cycle
desc { "test whether a crate has `#![no_builtins]`" } desc { "test whether a crate has `#![no_builtins]`" }
separate_provide_extern
} }
query symbol_mangling_version(_: CrateNum) -> SymbolManglingVersion { query symbol_mangling_version(_: CrateNum) -> SymbolManglingVersion {
fatal_cycle fatal_cycle
desc { "query a crate's symbol mangling version" } desc { "query a crate's symbol mangling version" }
separate_provide_extern
} }
query extern_crate(def_id: DefId) -> Option<&'tcx ExternCrate> { query extern_crate(def_id: DefId) -> Option<&'tcx ExternCrate> {
eval_always eval_always
desc { "getting crate's ExternCrateData" } desc { "getting crate's ExternCrateData" }
separate_provide_extern
} }
query specializes(_: (DefId, DefId)) -> bool { query specializes(_: (DefId, DefId)) -> bool {
@ -1197,10 +1250,12 @@ rustc_queries! {
query impl_defaultness(def_id: DefId) -> hir::Defaultness { query impl_defaultness(def_id: DefId) -> hir::Defaultness {
desc { |tcx| "looking up whether `{}` is a default impl", tcx.def_path_str(def_id) } desc { |tcx| "looking up whether `{}` is a default impl", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query impl_constness(def_id: DefId) -> hir::Constness { query impl_constness(def_id: DefId) -> hir::Constness {
desc { |tcx| "looking up whether `{}` is a const impl", tcx.def_path_str(def_id) } desc { |tcx| "looking up whether `{}` is a const impl", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query check_item_well_formed(key: LocalDefId) -> () { query check_item_well_formed(key: LocalDefId) -> () {
@ -1229,9 +1284,11 @@ rustc_queries! {
-> DefIdMap<SymbolExportLevel> { -> DefIdMap<SymbolExportLevel> {
storage(ArenaCacheSelector<'tcx>) storage(ArenaCacheSelector<'tcx>)
desc { "looking up the exported symbols of a crate" } desc { "looking up the exported symbols of a crate" }
separate_provide_extern
} }
query is_reachable_non_generic(def_id: DefId) -> bool { query is_reachable_non_generic(def_id: DefId) -> bool {
desc { |tcx| "checking whether `{}` is an exported symbol", tcx.def_path_str(def_id) } desc { |tcx| "checking whether `{}` is an exported symbol", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query is_unreachable_local_definition(def_id: LocalDefId) -> bool { query is_unreachable_local_definition(def_id: LocalDefId) -> bool {
desc { |tcx| desc { |tcx|
@ -1264,6 +1321,7 @@ rustc_queries! {
"collecting available upstream monomorphizations for `{}`", "collecting available upstream monomorphizations for `{}`",
tcx.def_path_str(def_id), tcx.def_path_str(def_id),
} }
separate_provide_extern
} }
/// Returns the upstream crate that exports drop-glue for the given /// Returns the upstream crate that exports drop-glue for the given
@ -1287,6 +1345,7 @@ rustc_queries! {
query foreign_modules(_: CrateNum) -> Lrc<FxHashMap<DefId, ForeignModule>> { query foreign_modules(_: CrateNum) -> Lrc<FxHashMap<DefId, ForeignModule>> {
desc { "looking up the foreign modules of a linked crate" } desc { "looking up the foreign modules of a linked crate" }
separate_provide_extern
} }
/// Identifies the entry-point (e.g., the `main` function) for a given /// Identifies the entry-point (e.g., the `main` function) for a given
@ -1302,18 +1361,22 @@ rustc_queries! {
query crate_hash(_: CrateNum) -> Svh { query crate_hash(_: CrateNum) -> Svh {
eval_always eval_always
desc { "looking up the hash a crate" } desc { "looking up the hash a crate" }
separate_provide_extern
} }
query crate_host_hash(_: CrateNum) -> Option<Svh> { query crate_host_hash(_: CrateNum) -> Option<Svh> {
eval_always eval_always
desc { "looking up the hash of a host version of a crate" } desc { "looking up the hash of a host version of a crate" }
separate_provide_extern
} }
query extra_filename(_: CrateNum) -> String { query extra_filename(_: CrateNum) -> String {
eval_always eval_always
desc { "looking up the extra filename for a crate" } desc { "looking up the extra filename for a crate" }
separate_provide_extern
} }
query crate_extern_paths(_: CrateNum) -> Vec<PathBuf> { query crate_extern_paths(_: CrateNum) -> Vec<PathBuf> {
eval_always eval_always
desc { "looking up the paths for extern crates" } desc { "looking up the paths for extern crates" }
separate_provide_extern
} }
/// Given a crate and a trait, look up all impls of that trait in the crate. /// Given a crate and a trait, look up all impls of that trait in the crate.
@ -1321,6 +1384,7 @@ rustc_queries! {
query implementations_of_trait(_: (CrateNum, DefId)) query implementations_of_trait(_: (CrateNum, DefId))
-> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] { -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] {
desc { "looking up implementations of a trait in a crate" } desc { "looking up implementations of a trait in a crate" }
separate_provide_extern
} }
/// Given a crate, look up all trait impls in that crate. /// Given a crate, look up all trait impls in that crate.
@ -1328,6 +1392,7 @@ rustc_queries! {
query all_trait_implementations(_: CrateNum) query all_trait_implementations(_: CrateNum)
-> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] { -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] {
desc { "looking up all (?) trait implementations" } desc { "looking up all (?) trait implementations" }
separate_provide_extern
} }
query is_dllimport_foreign_item(def_id: DefId) -> bool { query is_dllimport_foreign_item(def_id: DefId) -> bool {
@ -1384,6 +1449,7 @@ rustc_queries! {
query visibility(def_id: DefId) -> ty::Visibility { query visibility(def_id: DefId) -> ty::Visibility {
desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
/// Computes the set of modules from which this type is visibly uninhabited. /// Computes the set of modules from which this type is visibly uninhabited.
@ -1398,13 +1464,16 @@ rustc_queries! {
query dep_kind(_: CrateNum) -> CrateDepKind { query dep_kind(_: CrateNum) -> CrateDepKind {
eval_always eval_always
desc { "fetching what a dependency looks like" } desc { "fetching what a dependency looks like" }
separate_provide_extern
} }
query crate_name(_: CrateNum) -> Symbol { query crate_name(_: CrateNum) -> Symbol {
eval_always eval_always
desc { "fetching what a crate is named" } desc { "fetching what a crate is named" }
separate_provide_extern
} }
query item_children(def_id: DefId) -> &'tcx [Export] { query item_children(def_id: DefId) -> &'tcx [Export] {
desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
} }
query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> { query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {
desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id.to_def_id()) } desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id.to_def_id()) }
@ -1418,6 +1487,7 @@ rustc_queries! {
query defined_lib_features(_: CrateNum) query defined_lib_features(_: CrateNum)
-> &'tcx [(Symbol, Option<Symbol>)] { -> &'tcx [(Symbol, Option<Symbol>)] {
desc { "calculating the lib features defined in a crate" } desc { "calculating the lib features defined in a crate" }
separate_provide_extern
} }
/// Returns the lang items defined in another crate by loading it from metadata. /// Returns the lang items defined in another crate by loading it from metadata.
query get_lang_items(_: ()) -> LanguageItems { query get_lang_items(_: ()) -> LanguageItems {
@ -1436,16 +1506,19 @@ rustc_queries! {
/// Returns the lang items defined in another crate by loading it from metadata. /// Returns the lang items defined in another crate by loading it from metadata.
query defined_lang_items(_: CrateNum) -> &'tcx [(DefId, usize)] { query defined_lang_items(_: CrateNum) -> &'tcx [(DefId, usize)] {
desc { "calculating the lang items defined in a crate" } desc { "calculating the lang items defined in a crate" }
separate_provide_extern
} }
/// Returns the diagnostic items defined in a crate. /// Returns the diagnostic items defined in a crate.
query diagnostic_items(_: CrateNum) -> rustc_hir::diagnostic_items::DiagnosticItems { query diagnostic_items(_: CrateNum) -> rustc_hir::diagnostic_items::DiagnosticItems {
storage(ArenaCacheSelector<'tcx>) storage(ArenaCacheSelector<'tcx>)
desc { "calculating the diagnostic items map in a crate" } desc { "calculating the diagnostic items map in a crate" }
separate_provide_extern
} }
query missing_lang_items(_: CrateNum) -> &'tcx [LangItem] { query missing_lang_items(_: CrateNum) -> &'tcx [LangItem] {
desc { "calculating the missing lang items in a crate" } desc { "calculating the missing lang items in a crate" }
separate_provide_extern
} }
query visible_parent_map(_: ()) -> DefIdMap<DefId> { query visible_parent_map(_: ()) -> DefIdMap<DefId> {
storage(ArenaCacheSelector<'tcx>) storage(ArenaCacheSelector<'tcx>)
@ -1458,10 +1531,12 @@ rustc_queries! {
query missing_extern_crate_item(_: CrateNum) -> bool { query missing_extern_crate_item(_: CrateNum) -> bool {
eval_always eval_always
desc { "seeing if we're missing an `extern crate` item for this crate" } desc { "seeing if we're missing an `extern crate` item for this crate" }
separate_provide_extern
} }
query used_crate_source(_: CrateNum) -> Lrc<CrateSource> { query used_crate_source(_: CrateNum) -> Lrc<CrateSource> {
eval_always eval_always
desc { "looking at the source for a crate" } desc { "looking at the source for a crate" }
separate_provide_extern
} }
query postorder_cnums(_: ()) -> &'tcx [CrateNum] { query postorder_cnums(_: ()) -> &'tcx [CrateNum] {
eval_always eval_always
@ -1472,6 +1547,7 @@ rustc_queries! {
query is_private_dep(c: CrateNum) -> bool { query is_private_dep(c: CrateNum) -> bool {
eval_always eval_always
desc { "check whether crate {} is a private dependency", c } desc { "check whether crate {} is a private dependency", c }
separate_provide_extern
} }
query allocator_kind(_: ()) -> Option<AllocatorKind> { query allocator_kind(_: ()) -> Option<AllocatorKind> {
eval_always eval_always
@ -1517,6 +1593,7 @@ rustc_queries! {
query exported_symbols(_: CrateNum) query exported_symbols(_: CrateNum)
-> &'tcx [(ExportedSymbol<'tcx>, SymbolExportLevel)] { -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportLevel)] {
desc { "exported_symbols" } desc { "exported_symbols" }
separate_provide_extern
} }
query collect_and_partition_mono_items(_: ()) -> (&'tcx DefIdSet, &'tcx [CodegenUnit<'tcx>]) { query collect_and_partition_mono_items(_: ()) -> (&'tcx DefIdSet, &'tcx [CodegenUnit<'tcx>]) {
@ -1542,6 +1619,7 @@ rustc_queries! {
|tcx| "determining which generic parameters are unused by `{}`", |tcx| "determining which generic parameters are unused by `{}`",
tcx.def_path_str(key.def_id()) tcx.def_path_str(key.def_id())
} }
separate_provide_extern
} }
query backend_optimization_level(_: ()) -> OptLevel { query backend_optimization_level(_: ()) -> OptLevel {
desc { "optimization level used by backend" } desc { "optimization level used by backend" }

View File

@ -123,6 +123,39 @@ macro_rules! query_storage {
}; };
} }
macro_rules! separate_provide_extern_decl {
([][$name:ident]) => {
()
};
([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
for<'tcx> fn(
TyCtxt<'tcx>,
query_keys::$name<'tcx>,
) -> query_values::$name<'tcx>
};
([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
separate_provide_extern_decl!([$($modifiers)*][$($args)*])
};
}
macro_rules! separate_provide_extern_default {
([][$name:ident]) => {
()
};
([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
|_, key| bug!(
"`tcx.{}({:?})` unsupported by its crate; \
perhaps the `{}` query was never assigned a provider function",
stringify!($name),
key,
stringify!($name),
)
};
([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
separate_provide_extern_default!([$($modifiers)*][$($args)*])
};
}
macro_rules! define_callbacks { macro_rules! define_callbacks {
(<$tcx:tt> (<$tcx:tt>
$($(#[$attr:meta])* $($(#[$attr:meta])*
@ -214,6 +247,10 @@ macro_rules! define_callbacks {
) -> query_values::$name<'tcx>,)* ) -> query_values::$name<'tcx>,)*
} }
pub struct ExternProviders {
$(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
}
impl Default for Providers { impl Default for Providers {
fn default() -> Self { fn default() -> Self {
Providers { Providers {
@ -228,11 +265,24 @@ macro_rules! define_callbacks {
} }
} }
impl Default for ExternProviders {
fn default() -> Self {
ExternProviders {
$($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
}
}
}
impl Copy for Providers {} impl Copy for Providers {}
impl Clone for Providers { impl Clone for Providers {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
} }
impl Copy for ExternProviders {}
impl Clone for ExternProviders {
fn clone(&self) -> Self { *self }
}
pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync { pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
fn as_any(&'tcx self) -> &'tcx dyn std::any::Any; fn as_any(&'tcx self) -> &'tcx dyn std::any::Any;

View File

@ -19,7 +19,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_middle::arena::Arena; use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::{self, DepKindStruct, SerializedDepNodeIndex}; use rustc_middle::dep_graph::{self, DepKindStruct, SerializedDepNodeIndex};
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::{ExternProviders, Providers, QueryEngine};
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_span::def_id::LocalDefId; use rustc_span::def_id::LocalDefId;
use rustc_span::Span; use rustc_span::Span;

View File

@ -215,6 +215,22 @@ macro_rules! hash_result {
}; };
} }
macro_rules! get_provider {
([][$tcx:expr, $name:ident, $key:expr]) => {{
$tcx.queries.local_providers.$name
}};
([(separate_provide_extern) $($rest:tt)*][$tcx:expr, $name:ident, $key:expr]) => {{
if $key.query_crate_is_local() {
$tcx.queries.local_providers.$name
} else {
$tcx.queries.extern_providers.$name
}
}};
([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
get_provider!([$($modifiers)*][$($args)*])
};
}
macro_rules! define_queries { macro_rules! define_queries {
(<$tcx:tt> (<$tcx:tt>
$($(#[$attr:meta])* $($(#[$attr:meta])*
@ -310,11 +326,7 @@ macro_rules! define_queries {
fn make_vtable(tcx: QueryCtxt<'tcx>, key: &Self::Key) -> 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 = if key.query_crate_is_local() { let compute = get_provider!([$($modifiers)*][tcx, $name, key]);
tcx.queries.local_providers.$name
} else {
tcx.queries.extern_providers.$name
};
let cache_on_disk = Self::cache_on_disk(tcx.tcx, key); let cache_on_disk = Self::cache_on_disk(tcx.tcx, key);
QueryVtable { QueryVtable {
anon: is_anon!([$($modifiers)*]), anon: is_anon!([$($modifiers)*]),
@ -444,7 +456,7 @@ macro_rules! define_queries_struct {
input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => { input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
pub struct Queries<$tcx> { pub struct Queries<$tcx> {
local_providers: Box<Providers>, local_providers: Box<Providers>,
extern_providers: Box<Providers>, extern_providers: Box<ExternProviders>,
pub on_disk_cache: Option<OnDiskCache<$tcx>>, pub on_disk_cache: Option<OnDiskCache<$tcx>>,
@ -457,7 +469,7 @@ macro_rules! define_queries_struct {
impl<$tcx> Queries<$tcx> { impl<$tcx> Queries<$tcx> {
pub fn new( pub fn new(
local_providers: Providers, local_providers: Providers,
extern_providers: Providers, extern_providers: ExternProviders,
on_disk_cache: Option<OnDiskCache<$tcx>>, on_disk_cache: Option<OnDiskCache<$tcx>>,
) -> Self { ) -> Self {
Queries { Queries {