|
macro_rules! define_callbacks { |
|
( |
|
$($(#[$attr:meta])* |
|
[$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { |
|
|
|
// HACK(eddyb) this is like the `impl QueryConfig for queries::$name` |
|
// below, but using type aliases instead of associated types, to bypass |
|
// the limitations around normalizing under HRTB - for example, this: |
|
// `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value` |
|
// doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`. |
|
// This is primarily used by the `provide!` macro in `rustc_metadata`. |
|
#[allow(nonstandard_style, unused_lifetimes)] |
|
pub mod query_keys { |
|
use super::*; |
|
|
|
$(pub type $name<'tcx> = $($K)*;)* |
|
} |
|
#[allow(nonstandard_style, unused_lifetimes)] |
|
pub mod query_values { |
|
use super::*; |
|
|
|
$(pub type $name<'tcx> = $V;)* |
|
} |
|
#[allow(nonstandard_style, unused_lifetimes)] |
|
pub mod query_storage { |
|
use super::*; |
|
|
|
$(pub type $name<'tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)* |
|
} |
|
#[allow(nonstandard_style, unused_lifetimes)] |
|
pub mod query_stored { |
|
use super::*; |
|
|
|
$(pub type $name<'tcx> = <query_storage::$name<'tcx> as QueryStorage>::Stored;)* |
|
} |
|
|
|
#[derive(Default)] |
|
pub struct QueryCaches<'tcx> { |
|
$($(#[$attr])* pub $name: query_storage::$name<'tcx>,)* |
|
} |
|
|
|
impl<'tcx> TyCtxtEnsure<'tcx> { |
|
$($(#[$attr])* |
|
#[inline(always)] |
|
pub fn $name(self, key: query_helper_param_ty!($($K)*)) { |
|
let key = key.into_query_param(); |
|
opt_remap_env_constness!([$($modifiers)*][key]); |
|
|
|
let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop); |
|
|
|
match cached { |
|
Ok(()) => return, |
|
Err(()) => (), |
|
} |
|
|
|
self.tcx.queries.$name(self.tcx, DUMMY_SP, key, QueryMode::Ensure); |
|
})* |
|
} |
|
|
|
impl<'tcx> TyCtxt<'tcx> { |
|
$($(#[$attr])* |
|
#[inline(always)] |
|
#[must_use] |
|
pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx> |
|
{ |
|
self.at(DUMMY_SP).$name(key) |
|
})* |
|
} |
|
|
|
impl<'tcx> TyCtxtAt<'tcx> { |
|
$($(#[$attr])* |
|
#[inline(always)] |
|
pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx> |
|
{ |
|
let key = key.into_query_param(); |
|
opt_remap_env_constness!([$($modifiers)*][key]); |
|
|
|
let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, copy); |
|
|
|
match cached { |
|
Ok(value) => return value, |
|
Err(()) => (), |
|
} |
|
|
|
self.tcx.queries.$name(self.tcx, self.span, key, QueryMode::Get).unwrap() |
|
})* |
|
} |
|
|
|
pub struct Providers { |
|
$(pub $name: for<'tcx> fn( |
|
TyCtxt<'tcx>, |
|
query_keys::$name<'tcx>, |
|
) -> query_values::$name<'tcx>,)* |
|
} |
|
|
|
pub struct ExternProviders { |
|
$(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)* |
|
} |
|
|
|
impl Default for Providers { |
|
fn default() -> Self { |
|
Providers { |
|
$($name: |_, key| bug!( |
|
"`tcx.{}({:?})` unsupported by its crate; \ |
|
perhaps the `{}` query was never assigned a provider function", |
|
stringify!($name), |
|
key, |
|
stringify!($name), |
|
),)* |
|
} |
|
} |
|
} |
|
|
|
impl Default for ExternProviders { |
|
fn default() -> Self { |
|
ExternProviders { |
|
$($name: separate_provide_extern_default!([$($modifiers)*][$name]),)* |
|
} |
|
} |
|
} |
|
|
|
impl Copy for Providers {} |
|
impl Clone for Providers { |
|
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 { |
|
fn as_any(&'tcx self) -> &'tcx dyn std::any::Any; |
|
|
|
fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool; |
|
|
|
$($(#[$attr])* |
|
fn $name( |
|
&'tcx self, |
|
tcx: TyCtxt<'tcx>, |
|
span: Span, |
|
key: query_keys::$name<'tcx>, |
|
mode: QueryMode, |
|
) -> Option<query_stored::$name<'tcx>>;)* |
|
} |
|
}; |
|
} |
Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=58e18e1a59570b289fca4a2b015cf638
The current output is:
Ideally the output should look like:
In this small macro, the problem isn't too hard to figure out, but I gave up on figuring it out for the original code before the minimization:
rust/compiler/rustc_middle/src/ty/query.rs
Lines 175 to 321 in 7b8e2a5