Skip to content

Commit 5bdaff4

Browse files
committed
Match query key types as $K:tt instead of $($K:tt)*
The trick to making this work is to have the proc-macro surround every key type with parentheses, so that it remains a valid type but also matches as a single token tree. Due to how macro fragment specifiers work, matching as `$K:ty` would prevent us from inspecting the key type in `maybe_into_query_param!`.
1 parent b8d38ea commit 5bdaff4

File tree

4 files changed

+67
-37
lines changed

4 files changed

+67
-37
lines changed

compiler/rustc_macros/src/query.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,11 +483,13 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
483483
let span = name.span();
484484
let modifiers_stream = quote_spanned! { span => #(#modifiers_out),* };
485485

486-
// Add the query to the group
486+
// Add the query to the group.
487+
// Surround `key_ty` with parentheses so it can be matched as a single
488+
// token tree `$K:tt`, instead of the clunkier `$($K:tt)*`.
487489
query_stream.extend(quote! {
488490
#(#doc_comments)*
489491
[#modifiers_stream]
490-
fn #name(#key_ty) #return_ty,
492+
fn #name((#key_ty)) #return_ty,
491493
});
492494

493495
if let Some(feedable) = &modifiers.feedable {
@@ -503,7 +505,7 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
503505
);
504506
feedable_queries.extend(quote! {
505507
[#modifiers_stream]
506-
fn #name(#key_ty) #return_ty,
508+
fn #name((#key_ty)) #return_ty,
507509
});
508510
}
509511

compiler/rustc_middle/src/dep_graph/dep_node.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,8 @@ macro_rules! define_dep_nodes {
360360
(
361361
$(
362362
$(#[$attr:meta])*
363-
[$($modifiers:tt)*] fn $variant:ident($($K:tt)*) -> $V:ty,
363+
[$($modifiers:tt)*]
364+
fn $variant:ident($K:tt) -> $V:ty,
364365
)*
365366
) => {
366367

@@ -430,15 +431,15 @@ macro_rules! define_dep_nodes {
430431
// that aren't queries.
431432
rustc_with_all_queries!(define_dep_nodes![
432433
/// We use this for most things when incr. comp. is turned off.
433-
[] fn Null() -> (),
434+
[] fn Null(()) -> (),
434435
/// We use this to create a forever-red node.
435-
[] fn Red() -> (),
436-
[] fn SideEffect() -> (),
437-
[] fn AnonZeroDeps() -> (),
438-
[] fn TraitSelect() -> (),
439-
[] fn CompileCodegenUnit() -> (),
440-
[] fn CompileMonoItem() -> (),
441-
[] fn Metadata() -> (),
436+
[] fn Red(()) -> (),
437+
[] fn SideEffect(()) -> (),
438+
[] fn AnonZeroDeps(()) -> (),
439+
[] fn TraitSelect(()) -> (),
440+
[] fn CompileCodegenUnit(()) -> (),
441+
[] fn CompileMonoItem(()) -> (),
442+
[] fn Metadata(()) -> (),
442443
]);
443444

444445
// WARNING: `construct` is generic and does not know that `CompileCodegenUnit` takes `Symbol`s as keys.

compiler/rustc_middle/src/query/plumbing.rs

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,16 @@ macro_rules! query_ensure_select {
276276
};
277277
}
278278

279-
macro_rules! query_helper_param_ty {
280-
(DefId) => { impl $crate::query::IntoQueryParam<DefId> };
281-
(LocalDefId) => { impl $crate::query::IntoQueryParam<LocalDefId> };
279+
/// Expands to `impl IntoQueryParam<$K>` for a small allowlist of key types
280+
/// that benefit from the implicit conversion, or otherwise expands to `$K`
281+
/// itself.
282+
///
283+
/// This macro is why `define_callbacks!` needs to parse the key type as
284+
/// `$K:tt` and not `$K:ty`, because otherwise it would be unable to inspect
285+
/// the tokens inside `$K`.
286+
macro_rules! maybe_into_query_param {
287+
((DefId)) => { impl $crate::query::IntoQueryParam<DefId> };
288+
((LocalDefId)) => { impl $crate::query::IntoQueryParam<LocalDefId> };
282289
($K:ty) => { $K };
283290
}
284291

@@ -297,14 +304,12 @@ macro_rules! query_if_arena {
297304
/// If `separate_provide_extern`, then the key can be projected to its
298305
/// local key via `<$K as AsLocalKey>::LocalKey`.
299306
macro_rules! local_key_if_separate_extern {
300-
([] $($K:tt)*) => {
301-
$($K)*
302-
};
303-
([(separate_provide_extern) $($rest:tt)*] $($K:tt)*) => {
304-
<$($K)* as $crate::query::AsLocalKey>::LocalKey
307+
([] $K:ty) => { $K };
308+
([(separate_provide_extern) $($rest:tt)*] $K:ty) => {
309+
<$K as $crate::query::AsLocalKey>::LocalKey
305310
};
306-
([$other:tt $($modifiers:tt)*] $($K:tt)*) => {
307-
local_key_if_separate_extern!([$($modifiers)*] $($K)*)
311+
([$other:tt $($modifiers:tt)*] $K:ty) => {
312+
local_key_if_separate_extern!([$($modifiers)*] $K)
308313
};
309314
}
310315

@@ -349,19 +354,26 @@ macro_rules! separate_provide_extern_default {
349354

350355
macro_rules! define_callbacks {
351356
(
357+
// Match the key type as `tt` so that we can inspect its tokens.
358+
// (See `maybe_into_query_param`.)
359+
//
360+
// We don't need to write `$($K:tt)*` because `rustc_macros::query`
361+
// takes care to wrap the key type in an extra set of parentheses,
362+
// so it's always a single token tree.
352363
$(
353364
$(#[$attr:meta])*
354-
[$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,
365+
[$($modifiers:tt)*]
366+
fn $name:ident($K:tt) -> $V:ty,
355367
)*
356368
) => {
357369
$(#[allow(unused_lifetimes)] pub mod $name {
358370
use super::*;
359371
use $crate::query::erase::{self, Erased};
360372

361-
pub type Key<'tcx> = $($K)*;
373+
pub type Key<'tcx> = $K;
362374
pub type Value<'tcx> = $V;
363375

364-
pub type LocalKey<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*);
376+
pub type LocalKey<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $K);
365377

366378
/// This type alias specifies the type returned from query providers and the type
367379
/// used for decoding. For regular queries this is the declared returned type `V`,
@@ -397,7 +409,7 @@ macro_rules! define_callbacks {
397409
erase::erase_val(value)
398410
}
399411

400-
pub type Storage<'tcx> = <$($K)* as $crate::query::Key>::Cache<Erased<$V>>;
412+
pub type Storage<'tcx> = <$K as $crate::query::Key>::Cache<Erased<$V>>;
401413

402414
// Ensure that keys grow no larger than 88 bytes by accident.
403415
// Increase this limit if necessary, but do try to keep the size low if possible
@@ -408,7 +420,7 @@ macro_rules! define_callbacks {
408420
"the query `",
409421
stringify!($name),
410422
"` has a key type `",
411-
stringify!($($K)*),
423+
stringify!($K),
412424
"` that is too large"
413425
));
414426
}
@@ -455,7 +467,7 @@ macro_rules! define_callbacks {
455467
#[inline(always)]
456468
pub fn $name(
457469
self,
458-
key: query_helper_param_ty!($($K)*),
470+
key: maybe_into_query_param!($K),
459471
) -> ensure_ok_result!([$($modifiers)*]) {
460472
query_ensure_select!(
461473
[$($modifiers)*]
@@ -471,7 +483,10 @@ macro_rules! define_callbacks {
471483
impl<'tcx> $crate::query::TyCtxtEnsureDone<'tcx> {
472484
$($(#[$attr])*
473485
#[inline(always)]
474-
pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
486+
pub fn $name(
487+
self,
488+
key: maybe_into_query_param!($K),
489+
) {
475490
crate::query::inner::query_ensure(
476491
self.tcx,
477492
self.tcx.query_system.fns.engine.$name,
@@ -486,17 +501,22 @@ macro_rules! define_callbacks {
486501
$($(#[$attr])*
487502
#[inline(always)]
488503
#[must_use]
489-
pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
490-
{
504+
pub fn $name(
505+
self,
506+
key: maybe_into_query_param!($K),
507+
) -> $V {
508+
let key = $crate::query::IntoQueryParam::into_query_param(key);
491509
self.at(DUMMY_SP).$name(key)
492510
})*
493511
}
494512

495513
impl<'tcx> $crate::query::TyCtxtAt<'tcx> {
496514
$($(#[$attr])*
497515
#[inline(always)]
498-
pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
499-
{
516+
pub fn $name(
517+
self,
518+
key: maybe_into_query_param!($K),
519+
) -> $V {
500520
use $crate::query::{erase, inner};
501521

502522
erase::restore_val::<$V>(inner::query_get_at(
@@ -521,7 +541,7 @@ macro_rules! define_callbacks {
521541
#[derive(Default)]
522542
pub struct QueryStates<'tcx> {
523543
$(
524-
pub $name: $crate::query::QueryState<'tcx, $($K)*>,
544+
pub $name: $crate::query::QueryState<'tcx, $K>,
525545
)*
526546
}
527547

@@ -578,8 +598,14 @@ macro_rules! define_callbacks {
578598
}
579599

580600
macro_rules! define_feedable {
581-
($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
582-
$(impl<'tcx, K: $crate::query::IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
601+
(
602+
$(
603+
$(#[$attr:meta])*
604+
[$($modifiers:tt)*]
605+
fn $name:ident($K:tt) -> $V:ty,
606+
)*
607+
) => {
608+
$(impl<'tcx, K: $crate::query::IntoQueryParam<$K> + Copy> TyCtxtFeed<'tcx, K> {
583609
$(#[$attr])*
584610
#[inline(always)]
585611
pub fn $name(self, value: $name::ProvidedValue<'tcx>) {

compiler/rustc_query_impl/src/plumbing.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,8 @@ macro_rules! define_queries {
479479
(
480480
$(
481481
$(#[$attr:meta])*
482-
[$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,
482+
[$($modifiers:tt)*]
483+
fn $name:ident($K:tt) -> $V:ty,
483484
)*
484485
) => {
485486

0 commit comments

Comments
 (0)