On Fri, Feb 28, 2025 at 7:42 AM Alice Ryhl <aliceryhl@xxxxxxxxxx> wrote: > > This gives the quote! macro support for the following additional tokens: > > * The = token. > * The _ token. > * Using #my_var with variables of type Ident. > > Additionally, some type annotations are added to allow cases where > groups are empty. For example, quote! does support () in the input, but > only when it is *not* empty. When it is empty, the compiler cannot infer > the item type of `tokens`. > > These additional quote! features are used by a new proc macro that > generates code looking like this: > > const _: () = { > if true { > ::kernel::bindings::#name > } else { > #name > }; > }; > > where #name has type Ident. > > Signed-off-by: Alice Ryhl <aliceryhl@xxxxxxxxxx> > --- > rust/macros/quote.rs | 21 +++++++++++++++++++-- > 1 file changed, 19 insertions(+), 2 deletions(-) > > diff --git a/rust/macros/quote.rs b/rust/macros/quote.rs > index 33a199e4f176..c18960a91082 100644 > --- a/rust/macros/quote.rs > +++ b/rust/macros/quote.rs > @@ -20,6 +20,12 @@ fn to_tokens(&self, tokens: &mut TokenStream) { > } > } > > +impl ToTokens for proc_macro::Ident { > + fn to_tokens(&self, tokens: &mut TokenStream) { > + tokens.extend([TokenTree::from(self.clone())]); > + } > +} > + > impl ToTokens for TokenTree { > fn to_tokens(&self, tokens: &mut TokenStream) { > tokens.extend([self.clone()]); > @@ -40,7 +46,7 @@ fn to_tokens(&self, tokens: &mut TokenStream) { > /// `quote` crate but provides only just enough functionality needed by the current `macros` crate. > macro_rules! quote_spanned { > ($span:expr => $($tt:tt)*) => {{ > - let mut tokens; > + let mut tokens: ::std::vec::Vec<::proc_macro::TokenTree>; > #[allow(clippy::vec_init_then_push)] > { > tokens = ::std::vec::Vec::new(); > @@ -65,7 +71,8 @@ macro_rules! quote_spanned { > quote_spanned!(@proc $v $span $($tt)*); > }; > (@proc $v:ident $span:ident ( $($inner:tt)* ) $($tt:tt)*) => { > - let mut tokens = ::std::vec::Vec::new(); > + #[allow(unused_mut)] It'd be nice to mention the need for this attribute in the commit message along with the added type annotations. > + let mut tokens = ::std::vec::Vec::<::proc_macro::TokenTree>::new(); > quote_spanned!(@proc tokens $span $($inner)*); > $v.push(::proc_macro::TokenTree::Group(::proc_macro::Group::new( > ::proc_macro::Delimiter::Parenthesis, > @@ -136,6 +143,16 @@ macro_rules! quote_spanned { > )); > quote_spanned!(@proc $v $span $($tt)*); > }; > + (@proc $v:ident $span:ident = $($tt:tt)*) => { > + $v.push(::proc_macro::TokenTree::Punct( > + ::proc_macro::Punct::new('=', ::proc_macro::Spacing::Alone) > + )); > + quote_spanned!(@proc $v $span $($tt)*); > + }; > + (@proc $v:ident $span:ident _ $($tt:tt)*) => { > + $v.push(::proc_macro::TokenTree::Ident(::proc_macro::Ident::new("_", $span))); > + quote_spanned!(@proc $v $span $($tt)*); > + }; > (@proc $v:ident $span:ident $id:ident $($tt:tt)*) => { > $v.push(::proc_macro::TokenTree::Ident(::proc_macro::Ident::new(stringify!($id), $span))); > quote_spanned!(@proc $v $span $($tt)*); > > -- > 2.48.1.711.g2feabab25a-goog Reviewed-by: Tamir Duberstein <tamird@xxxxxxxxx>