[PATCH] rust: macros: support `#[cfg]` properly in `#[vtable]` macro.

Gary Guo posted 1 patch 3 weeks, 4 days ago
There is a newer version of this series
rust/macros/helpers.rs |  6 ++++++
rust/macros/vtable.rs  | 13 ++++---------
2 files changed, 10 insertions(+), 9 deletions(-)
[PATCH] rust: macros: support `#[cfg]` properly in `#[vtable]` macro.
Posted by Gary Guo 3 weeks, 4 days ago
From: Gary Guo <gary@garyguo.net>

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>
---
 rust/macros/helpers.rs |  6 ++++++
 rust/macros/vtable.rs  | 13 ++++---------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs
index adfa60d8f42d8..11117b4c95d25 100644
--- a/rust/macros/helpers.rs
+++ b/rust/macros/helpers.rs
@@ -7,6 +7,7 @@
         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")).cloned()
+}
diff --git a/rust/macros/vtable.rs b/rust/macros/vtable.rs
index 72ae0a1816a04..c6510b0c4ea1d 100644
--- a/rust/macros/vtable.rs
+++ b/rust/macros/vtable.rs
@@ -23,7 +23,6 @@
 
 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);
         }
     }
 

base-commit: 761e1fbc67b122bfe3d58518a9ea9ee668962c92
-- 
2.51.2
Re: [PATCH] rust: macros: support `#[cfg]` properly in `#[vtable]` macro.
Posted by Tamir Duberstein 3 weeks, 4 days ago
On Tue, Jan 13, 2026 at 8:11 AM Gary Guo <gary@kernel.org> wrote:
>
> From: Gary Guo <gary@garyguo.net>
>
> 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>
> ---
>  rust/macros/helpers.rs |  6 ++++++
>  rust/macros/vtable.rs  | 13 ++++---------
>  2 files changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs
> index adfa60d8f42d8..11117b4c95d25 100644
> --- a/rust/macros/helpers.rs
> +++ b/rust/macros/helpers.rs
> @@ -7,6 +7,7 @@
>          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")).cloned()
> +}

There's also no need to clone; `ToTokens::to_tokens` takes `&self`.

https://docs.rs/quote/latest/quote/trait.ToTokens.html#tymethod.to_tokens

> diff --git a/rust/macros/vtable.rs b/rust/macros/vtable.rs
> index 72ae0a1816a04..c6510b0c4ea1d 100644
> --- a/rust/macros/vtable.rs
> +++ b/rust/macros/vtable.rs
> @@ -23,7 +23,6 @@
>
>  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);
>          }
>      }
>
>
> base-commit: 761e1fbc67b122bfe3d58518a9ea9ee668962c92
> --
> 2.51.2
>
Re: [PATCH] rust: macros: support `#[cfg]` properly in `#[vtable]` macro.
Posted by Gary Guo 3 weeks, 4 days ago
On Tue Jan 13, 2026 at 1:39 PM GMT, Tamir Duberstein wrote:
> On Tue, Jan 13, 2026 at 8:11 AM Gary Guo <gary@kernel.org> wrote:
>>
>> From: Gary Guo <gary@garyguo.net>
>>
>> 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>
>> ---
>>  rust/macros/helpers.rs |  6 ++++++
>>  rust/macros/vtable.rs  | 13 ++++---------
>>  2 files changed, 10 insertions(+), 9 deletions(-)
>>
>> diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs
>> index adfa60d8f42d8..11117b4c95d25 100644
>> --- a/rust/macros/helpers.rs
>> +++ b/rust/macros/helpers.rs
>> @@ -7,6 +7,7 @@
>>          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")).cloned()
>> +}
>
> There's also no need to clone; `ToTokens::to_tokens` takes `&self`.
>
> https://docs.rs/quote/latest/quote/trait.ToTokens.html#tymethod.to_tokens

Indeed. In that case I feel like the line is short enough and we can just inline
these and skip the helper function?

Best,
Gary
Re: [PATCH] rust: macros: support `#[cfg]` properly in `#[vtable]` macro.
Posted by Tamir Duberstein 3 weeks, 4 days ago
On Tue, Jan 13, 2026 at 9:09 AM Gary Guo <gary@garyguo.net> wrote:
>
> On Tue Jan 13, 2026 at 1:39 PM GMT, Tamir Duberstein wrote:
> > On Tue, Jan 13, 2026 at 8:11 AM Gary Guo <gary@kernel.org> wrote:
> >>
> >> From: Gary Guo <gary@garyguo.net>
> >>
> >> 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>
> >> ---
> >>  rust/macros/helpers.rs |  6 ++++++
> >>  rust/macros/vtable.rs  | 13 ++++---------
> >>  2 files changed, 10 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs
> >> index adfa60d8f42d8..11117b4c95d25 100644
> >> --- a/rust/macros/helpers.rs
> >> +++ b/rust/macros/helpers.rs
> >> @@ -7,6 +7,7 @@
> >>          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")).cloned()
> >> +}
> >
> > There's also no need to clone; `ToTokens::to_tokens` takes `&self`.
> >
> > https://docs.rs/quote/latest/quote/trait.ToTokens.html#tymethod.to_tokens
>
> Indeed. In that case I feel like the line is short enough and we can just inline
> these and skip the helper function?

I think extracting the duplication is still worthwhile, and we might
need this elsewhere so I'd leave it in the helpers module. I don't
feel strongly though, so go with your preference.

>
> Best,
> Gary
[PATCH v2] rust: macros: support `#[cfg]` properly in `#[vtable]` macro.
Posted by Gary Guo 3 weeks, 4 days ago
From: Gary Guo <gary@garyguo.net>

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>
---
 rust/macros/helpers.rs |  6 ++++++
 rust/macros/vtable.rs  | 13 ++++---------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs
index adfa60d8f42d8..37ef6a6f2c851 100644
--- a/rust/macros/helpers.rs
+++ b/rust/macros/helpers.rs
@@ -7,6 +7,7 @@
         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 72ae0a1816a04..c6510b0c4ea1d 100644
--- a/rust/macros/vtable.rs
+++ b/rust/macros/vtable.rs
@@ -23,7 +23,6 @@
 
 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);
         }
     }
 

base-commit: 761e1fbc67b122bfe3d58518a9ea9ee668962c92
-- 
2.51.2
Re: [PATCH v2] rust: macros: support `#[cfg]` properly in `#[vtable]` macro.
Posted by Benno Lossin 3 weeks ago
On Tue Jan 13, 2026 at 6:05 PM CET, Gary Guo wrote:
> From: Gary Guo <gary@garyguo.net>
>
> 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>

Cheers,
Benno

> ---
>  rust/macros/helpers.rs |  6 ++++++
>  rust/macros/vtable.rs  | 13 ++++---------
>  2 files changed, 10 insertions(+), 9 deletions(-)