Skip to content

Commit bd10ffa

Browse files
authored
Handle Groups with Delimiter::None (#50)
Currently, rustc does not pass the exact original `TokenStream` to proc-macros in several cases. This has many undesirable effects, such as losing correct location information in error message. See rust-lang/rust#43081 for more details In the future, rustc will begin passing the correct `TokenStream` to proc-macros. As a result, some tokens may be wrapped in a `TokenTree::Group` with `Delimiter::None` (when the tokens originally came from a `macro_rules!`) macro expansion. I've determined that this change will cause your crate to stop working on some inputs. This PR updates `hex-literal-impl` to be compatible with both the old and new `TokenStream` contents. If you have any questions, feel free to ask me. See rust-lang/rust#72622 for more details
1 parent a0e4801 commit bd10ffa

File tree

1 file changed

+23
-2
lines changed
  • hex-literal/hex-literal-impl/src

1 file changed

+23
-2
lines changed

hex-literal/hex-literal-impl/src/lib.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
extern crate proc_macro;
22

3-
use proc_macro::{TokenStream, TokenTree};
3+
use proc_macro::{TokenStream, TokenTree, Delimiter};
44
use proc_macro_hack::proc_macro_hack;
55

66
fn is_hex_char(c: &char) -> bool {
@@ -17,8 +17,29 @@ fn is_format_char(c: &char) -> bool {
1717
}
1818
}
1919

20+
21+
/// Strips any outer `Delimiter::None` groups from the input,
22+
/// returning a `TokenStream` consisting of the innermost
23+
/// non-empty-group `TokenTree`.
24+
/// This is used to handle a proc macro being invoked
25+
/// by a `macro_rules!` expansion.
26+
/// See https://github.com/rust-lang/rust/issues/72545 for background
27+
fn ignore_groups(mut input: TokenStream) -> TokenStream {
28+
let mut tokens = input.clone().into_iter();
29+
loop {
30+
if let Some(TokenTree::Group(group)) = tokens.next() {
31+
if group.delimiter() == Delimiter::None {
32+
input = group.stream();
33+
continue;
34+
}
35+
}
36+
return input;
37+
}
38+
}
39+
2040
#[proc_macro_hack]
21-
pub fn hex(input: TokenStream) -> TokenStream {
41+
pub fn hex(mut input: TokenStream) -> TokenStream {
42+
input = ignore_groups(input);
2243
let mut ts = input.into_iter();
2344
let input = match (ts.next(), ts.next()) {
2445
(Some(TokenTree::Literal(literal)), None) => literal.to_string(),

0 commit comments

Comments
 (0)