Closed
Description
I have the following procedural macro and invocation of the macro. In this code I construct two identical functions f
and g
which simply return stringify!(i32)
, but with a none-delimited group around the i32
(because of #55557). As far as I can tell the function bodies of f
and g
are identical token streams.
But f
returns "i32"
and g
returns " i32 "
.
I believe that as written, both functions should return "i32"
without spaces.
extern crate proc_macro;
use self::proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
use std::iter::FromIterator;
#[proc_macro]
pub fn repro(input: TokenStream) -> TokenStream {
println!("{:#?}", input);
TokenStream::from_iter(vec![
// fn f() -> &'static str { $input }
TokenTree::Ident(Ident::new("fn", Span::call_site())),
TokenTree::Ident(Ident::new("f", Span::call_site())),
TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
TokenTree::Punct(Punct::new('-', Spacing::Joint)),
TokenTree::Punct(Punct::new('>', Spacing::Alone)),
TokenTree::Punct(Punct::new('&', Spacing::Alone)),
TokenTree::Punct(Punct::new('\'', Spacing::Joint)),
TokenTree::Ident(Ident::new("static", Span::call_site())),
TokenTree::Ident(Ident::new("str", Span::call_site())),
TokenTree::Group(Group::new(Delimiter::Brace, input)),
// fn g() -> &'static str { stringify!(i32) }
TokenTree::Ident(Ident::new("fn", Span::call_site())),
TokenTree::Ident(Ident::new("g", Span::call_site())),
TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
TokenTree::Punct(Punct::new('-', Spacing::Joint)),
TokenTree::Punct(Punct::new('>', Spacing::Alone)),
TokenTree::Punct(Punct::new('&', Spacing::Alone)),
TokenTree::Punct(Punct::new('\'', Spacing::Joint)),
TokenTree::Ident(Ident::new("static", Span::call_site())),
TokenTree::Ident(Ident::new("str", Span::call_site())),
TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::from_iter(vec![
TokenTree::Ident(Ident::new("stringify", Span::call_site())),
TokenTree::Punct(Punct::new('!', Spacing::Alone)),
TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::from_iter(vec![
TokenTree::Group(Group::new(Delimiter::None, TokenStream::from_iter(vec![
TokenTree::Ident(Ident::new("i32", Span::call_site())),
]))),
]))),
])))
])
}
macro_rules! m {
($id:ident) => {
repro::repro! {
stringify!($id)
}
}
}
m!(i32);
fn main() {
assert_eq!(f(), "i32", "f()");
assert_eq!(g(), "i32", "g()"); // broken, is `" i32 "`
}
Metadata
Metadata
Assignees
Labels
Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..)Category: This is a bug.Status: A Minimal Complete and Verifiable Example has been found for this issueRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.