rust
rust copied to clipboard
Don't give "no rules expected the token" errors for macros that failed to parse
Given the following code: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=293168337d6a7ce2c74a82461e536bad
macro_rules! foo {
($t:type) => {};
}
foo! { Option<bool> }
The current output is:
error: invalid fragment specifier `type`
--> src/lib.rs:2:6
|
2 | ($t:type) => {};
| ^^^^^^^
|
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
error: no rules expected the token `<`
--> src/lib.rs:5:14
|
1 | macro_rules! foo {
| ---------------- when calling this macro
...
5 | foo! { Option<bool> }
| ^ no rules expected this token in macro call
error: could not compile `playground` due to 2 previous errors
Ideally the output should look like:
error: invalid fragment specifier `type`
--> src/lib.rs:2:6
|
2 | ($t:type) => {};
| ^^^^^^^
|
= help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`
error: could not compile `playground` due to previous error
Because telling me the call to the macro is invalid doesn't make much sense when that's impossible to fix without fixing the macro first.
Non-minimized mistake I made that inspired me to open this issue: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=aa7ce077f0b05e2af987f72539983e87
macro_rules! impl_for_optional_bool {
($($t:type,)+) => {$(
unsafe impl IsZero for $t {
fn is_zero(&self) -> bool {
// SAFETY: This is *not* a stable layout guarantee, but
// inside `core` we're allowed to rely on the current rustc
// behaviour that options of bools will be one byte with
// no padding, so long as they're nested less than 254 deep.
let raw: u8 = unsafe { core::mem::transmute(*self) };
raw == 0
}
}
)+};
}
impl_for_optional_bool! {
Option<bool>,
Option<Option<bool>>,
Option<Option<Option<bool>>>,
// Could go further, but not worth the trait lookup overhead
}