mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:24:45 +01:00
rust: macros: support #[cfg] properly in #[vtable] macro.
Currently, we generate `HAS_` constants as long as the definition exists in the source, regardless if it is cfg-ed out or not. Currently, uses of `#[cfg]` present in both trait and impl, so it is not a problem; however if only the impl side uses `#[cfg]` then `HAS_` constants will incorrectly be true while it shouldnt't. With `syn` support, we can now implement `#[cfg]` handling properly by propagating the `#[cfg]` attributes to the constants. Signed-off-by: Gary Guo <gary@garyguo.net> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://patch.msgid.link/20260113170529.2240744-1-gary@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
parent
be97f3c820
commit
779f6e3e1c
2 changed files with 10 additions and 9 deletions
|
|
@ -7,6 +7,7 @@ use syn::{
|
|||
Parse,
|
||||
ParseStream, //
|
||||
},
|
||||
Attribute,
|
||||
Error,
|
||||
LitStr,
|
||||
Result, //
|
||||
|
|
@ -53,3 +54,8 @@ pub(crate) fn file() -> String {
|
|||
proc_macro::Span::call_site().file()
|
||||
}
|
||||
}
|
||||
|
||||
/// Obtain all `#[cfg]` attributes.
|
||||
pub(crate) fn gather_cfg_attrs(attr: &[Attribute]) -> impl Iterator<Item = &Attribute> + '_ {
|
||||
attr.iter().filter(|a| a.path().is_ident("cfg"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ use syn::{
|
|||
|
||||
fn handle_trait(mut item: ItemTrait) -> Result<ItemTrait> {
|
||||
let mut gen_items = Vec::new();
|
||||
let mut gen_consts = HashSet::new();
|
||||
|
||||
gen_items.push(parse_quote! {
|
||||
/// A marker to prevent implementors from forgetting to use [`#[vtable]`](vtable)
|
||||
|
|
@ -38,22 +37,17 @@ fn handle_trait(mut item: ItemTrait) -> Result<ItemTrait> {
|
|||
&format!("HAS_{}", name.to_string().to_uppercase()),
|
||||
name.span(),
|
||||
);
|
||||
// Skip if it's declared already -- this can happen if `#[cfg]` is used to selectively
|
||||
// define functions.
|
||||
// FIXME: `#[cfg]` should be copied and propagated to the generated consts.
|
||||
if gen_consts.contains(&gen_const_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We don't know on the implementation-site whether a method is required or provided
|
||||
// so we have to generate a const for all methods.
|
||||
let cfg_attrs = crate::helpers::gather_cfg_attrs(&fn_item.attrs);
|
||||
let comment =
|
||||
format!("Indicates if the `{name}` method is overridden by the implementor.");
|
||||
gen_items.push(parse_quote! {
|
||||
#(#cfg_attrs)*
|
||||
#[doc = #comment]
|
||||
const #gen_const_name: bool = false;
|
||||
});
|
||||
gen_consts.insert(gen_const_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,10 +81,11 @@ fn handle_impl(mut item: ItemImpl) -> Result<ItemImpl> {
|
|||
if defined_consts.contains(&gen_const_name) {
|
||||
continue;
|
||||
}
|
||||
let cfg_attrs = crate::helpers::gather_cfg_attrs(&fn_item.attrs);
|
||||
gen_items.push(parse_quote! {
|
||||
#(#cfg_attrs)*
|
||||
const #gen_const_name: bool = true;
|
||||
});
|
||||
defined_consts.insert(gen_const_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue