-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Panic iterating over proc_macro::TokenStream #55640
Comments
cc @petrochenkov Looks like |
Don't split it, allow macro_rules! is_ident {
($i:ident) => {};
}
macro_rules! check {
() => {
is_ident!($crate);
};
}
check!(); Otherwise all proc macro parsing code will need separate cases for many places that an ident is parsed or stored to also accept |
This is a tricky case, yes. |
Derive macro infra currently does a horrible thing called @dtolnay |
I believe we don't currently have any code in any proc macro library specifically for accommodating |
There's one thing I'm sure in - If we introduced a new keyword, say |
I would be fine with accepting "$crate" in Ident::new. Lots of things don't survive stringification and reparsing so that shouldn't be a requirement. |
Some status update: the ICE no longer happens because #49219 removed all the validation for tokens coming to proc macros from the compiler, but the underlying issue is still there. |
@petrochenkov Wait there was validation? Where exactly, I might've missed it? |
|
Input from the compiler is kind of controlled, so validation there is not so important as for the user-facing |
Before: Ident(ident, false) => tt!(self::Ident::new(&ident.as_str(), Span(span))),
Ident(ident, true) => tt!(self::Ident::new_raw(&ident.as_str(), Span(span))), After: Ident(ident, is_raw) => tt!(Ident {
sym: ident.name,
is_raw
}), Just looking at this, without remembering exactly what happened, I suspect a rebase killed this accidentally. I don't remember noticing reinterning was happening. I guess my version also preserves gensyms when it shouldn't? |
Yes.
I'm not sure what should happen here. |
Fixed in #56647 |
Rework treatment of `$crate` in procedural macros Important clarification: `$crate` below means "processed `$crate`" or "output `$crate`". In the input of a decl macro `$crate` is just two separate tokens, but in the *output of a decl macro* `$crate` is a single keyword identifier (#55640 (comment)). First of all, this PR removes the `eliminate_crate_var` hack. `$crate::foo` is no longer replaced with `::foo` or `::crate_name::foo` in the input of derive proc macros, it's passed to the macro instead with its precise span and hygiene data, and can be treated as any other path segment keyword (like `crate` or `self`) after that. (Note: `eliminate_crate_var` was never used for non-derive proc macros.) This creates an annoying problem - derive macros still may stringify their input before processing and expect `$crate` survive that stringification and refer to the same crate (the Rust 1.15-1.29 way of doing things). Moreover, the input of proc macro attributes and derives (but not fn-like proc macros) also effectively survives stringification before being passed to the macro (also for legacy implementation reasons). So we kind of resurrect the `eliminate_crate_var` hack in reduced form, but apply it only to AST pretty-printing. If an AST fragment is pretty-printed, the resulting *text* will have `$crate` replaced with `crate` or `::crate_name`. This should be enough to keep all the legacy cases working. Closes #55640 Closes #56622 r? @ghost
In the following proc macro invocation the compiler passes in the input
$crate
as a TokenStream but panics when iterating over that TokenStream. Specifically the panic happens innext()
.rustc 1.31.0-nightly (de9666f 2018-10-31)
repro/src/lib.rs
testing/src/lib.rs
Originally reported in dtolnay/paste#3. Mentioning @softprops.
The text was updated successfully, but these errors were encountered: