This makes things like concat_idents!(bindings::foo, bar) work.
Otherwise, there is no way to concatenate two idents and then use the
result as part of a type path.
Signed-off-by: Asahi Lina <lina@asahilina.net>
---
rust/macros/concat_idents.rs | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/rust/macros/concat_idents.rs b/rust/macros/concat_idents.rs
index 6d955d65016e..d6614b900aa2 100644
--- a/rust/macros/concat_idents.rs
+++ b/rust/macros/concat_idents.rs
@@ -14,10 +14,28 @@ fn expect_ident(it: &mut token_stream::IntoIter) -> Ident {
pub(crate) fn concat_idents(ts: TokenStream) -> TokenStream {
let mut it = ts.into_iter();
- let a = expect_ident(&mut it);
- assert_eq!(expect_punct(&mut it).as_char(), ',');
+ let mut out = TokenStream::new();
+ let a = loop {
+ let ident = expect_ident(&mut it);
+ let punct = expect_punct(&mut it);
+ match punct.as_char() {
+ ',' => break ident,
+ ':' => {
+ let punct2 = expect_punct(&mut it);
+ assert_eq!(punct2.as_char(), ':');
+ out.extend([
+ TokenTree::Ident(ident),
+ TokenTree::Punct(punct),
+ TokenTree::Punct(punct2),
+ ]);
+ }
+ _ => panic!("Expected , or ::"),
+ }
+ };
+
let b = expect_ident(&mut it);
assert!(it.next().is_none(), "only two idents can be concatenated");
let res = Ident::new(&format!("{a}{b}"), b.span());
- TokenStream::from_iter([TokenTree::Ident(res)])
+ out.extend([TokenTree::Ident(res)]);
+ out
}
--
2.35.1
> This makes things like concat_idents!(bindings::foo, bar) work. > Otherwise, there is no way to concatenate two idents and then use the > result as part of a type path. > > Signed-off-by: Asahi Lina <lina@asahilina.net> > --- Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
On Fri, 24 Feb 2023 16:25:56 +0900 Asahi Lina <lina@asahilina.net> wrote: > This makes things like concat_idents!(bindings::foo, bar) work. > Otherwise, there is no way to concatenate two idents and then use the > result as part of a type path. It seems weird to me that this is called `concat_idents` despite working for more things than just idents. How about just implement a simple version of the `paste` macro instead? Best, Gary > > Signed-off-by: Asahi Lina <lina@asahilina.net> > --- > rust/macros/concat_idents.rs | 24 +++++++++++++++++++++--- > 1 file changed, 21 insertions(+), 3 deletions(-) > > diff --git a/rust/macros/concat_idents.rs b/rust/macros/concat_idents.rs > index 6d955d65016e..d6614b900aa2 100644 > --- a/rust/macros/concat_idents.rs > +++ b/rust/macros/concat_idents.rs > @@ -14,10 +14,28 @@ fn expect_ident(it: &mut token_stream::IntoIter) -> Ident { > > pub(crate) fn concat_idents(ts: TokenStream) -> TokenStream { > let mut it = ts.into_iter(); > - let a = expect_ident(&mut it); > - assert_eq!(expect_punct(&mut it).as_char(), ','); > + let mut out = TokenStream::new(); > + let a = loop { > + let ident = expect_ident(&mut it); > + let punct = expect_punct(&mut it); > + match punct.as_char() { > + ',' => break ident, > + ':' => { > + let punct2 = expect_punct(&mut it); > + assert_eq!(punct2.as_char(), ':'); > + out.extend([ > + TokenTree::Ident(ident), > + TokenTree::Punct(punct), > + TokenTree::Punct(punct2), > + ]); > + } > + _ => panic!("Expected , or ::"), > + } > + }; > + > let b = expect_ident(&mut it); > assert!(it.next().is_none(), "only two idents can be concatenated"); > let res = Ident::new(&format!("{a}{b}"), b.span()); > - TokenStream::from_iter([TokenTree::Ident(res)]) > + out.extend([TokenTree::Ident(res)]); > + out > } >
On Sat, Feb 25, 2023 at 1:32 AM Gary Guo <gary@garyguo.net> wrote: > > It seems weird to me that this is called `concat_idents` despite > working for more things than just idents. > > How about just implement a simple version of the `paste` macro instead? We discussed this in our latest meeting: what about a change of name to `concat_paths`? That addresses the concern plus it avoids sharing the name with the unstable `concat_idents` which could be even more confusing after this patch. Cheers, Miguel
On Sat, Feb 25, 2023 at 1:32 AM Gary Guo <gary@garyguo.net> wrote: > > It seems weird to me that this is called `concat_idents` despite > working for more things than just idents. > > How about just implement a simple version of the `paste` macro instead? Opened https://github.com/Rust-for-Linux/linux/issues/983 in case we end up applying the patch. Cheers, Miguel
© 2016 - 2025 Red Hat, Inc.