summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorGary Guo <gary@garyguo.net>2026-01-13 17:05:21 +0000
committerMiguel Ojeda <ojeda@kernel.org>2026-01-28 13:44:17 +0100
commit779f6e3e1cef07cb0c1241d483ed364e522bd280 (patch)
treead94f222d67567427984a0424af98078cc60e73d /rust
parentbe97f3c82021239476ce32cddde32948c597753e (diff)
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>
Diffstat (limited to 'rust')
-rw-r--r--rust/macros/helpers.rs6
-rw-r--r--rust/macros/vtable.rs13
2 files changed, 10 insertions, 9 deletions
diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs
index adfa60d8f42d..37ef6a6f2c85 100644
--- a/rust/macros/helpers.rs
+++ b/rust/macros/helpers.rs
@@ -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"))
+}
diff --git a/rust/macros/vtable.rs b/rust/macros/vtable.rs
index 72ae0a1816a0..c6510b0c4ea1 100644
--- a/rust/macros/vtable.rs
+++ b/rust/macros/vtable.rs
@@ -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);
}
}