-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=58e18e1a59570b289fca4a2b015cf638
macro_rules! rustc_cached_queries {
($macro:ident!) => {
$macro!(A B C D);
}
}
macro_rules! define_dep_nodes {
( $($name:ident)* ) => {
$( #[allow(dead_code)] fn $name() {} )*
}
}
rustc_cached_queries!(define_dep_nodes!);
The current output is:
warning: function `A` should have a snake case name
--> tmp.rs:3:17
|
1 | / macro_rules! rustc_cached_queries {
2 | | ($macro:ident!) => {
3 | | $macro!(A B C D);
| | ^ help: convert the identifier to snake case: `a`
4 | | }
5 | | }
| |_- in this expansion of `rustc_cached_queries!`
...
13 | rustc_cached_queries!(define_dep_nodes!);
| ---------------------------------------- in this macro invocation
|
= note: `#[warn(non_snake_case)]` on by default
Ideally the output should look like:
warning: function `A` should have a snake case name
--> tmp.rs:3:17
|
1 | / macro_rules! rustc_cached_queries {
2 | | ($macro:ident!) => {
3 | | $macro!(A B C D);
| | ^ help: convert the identifier to snake case: `a`
4 | | }
5 | | }
| |_- in this expansion of `rustc_cached_queries!`
...
9 $( #[allow(dead_code)] fn $name() {} )*
^^^^ in this expansion of `define_dep_nodes`
...
13 | rustc_cached_queries!(define_dep_nodes!);
| ---------------------------------------- in this macro invocation
|
= note: `#[warn(non_snake_case)]` on by default
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
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>>;)* | |
} | |
}; | |
} |
TaKO8Ki
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.