Improve the error message when forwarding a matched fragment to another macro
Adds a link to [Forwarding a matched fragment](https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment) section of the Rust Reference, and suggests a possible fix (using `:tt` instead in the macro definition).
Also removes typos from the original message, it should be `:lifetime` instead of `$lifetime`.
## Motivation
When trying to write a macro which uses a literal in the matcher from the outer macro, like the following one, using a fragment specified that isn't one of `:ident`, `:lifetime`, or `:tt` currently results in a hard to understand message.
```rs
macro_rules! make_t_for_all_tokens {
($($name:literal as $variant:expr,)*) => {
macro_rules! t {
$(
($name) => {
$variant
};
)*
}
};
}
make_t_for_all_tokens! {
"fn" as Token::Fn,
"return" as Token::Return,
"let" as Token::Let,
}
// This creates
//
// macro_rules! t {
// ("fn") => {
// Token::Fn
// };
// ("return") => {
// Token::Return
// };
// ("let") => {
// Token::Let
// };
// }
t!["fn"];
```
### Before
```
error: no rules expected the token `"fn"`
--> src/main.rs:103:10
|
32 | macro_rules! t {
| -------------- when calling this macro
...
103 | t!["fn"];
| ^^^^ no rules expected this token in macro call
|
note: while trying to match `"fn"`
--> src/main.rs:34:6
|
34 | ($name) => {
| ^^^^^
...
58 | / make_t_for_all_tokens! {
59 | | "fn" as Token::Fn,
60 | | "return" as Token::Return,
61 | | "let" as Token::Let,
62 | | }
| |_- in this macro invocation
= note: captured metavariables except for `$tt`, `$ident` and `$lifetime` cannot be compared to other tokens
= note: this error originates in the macro `make_t_for_all_tokens` (in Nightly builds, run with -Z macro-backtrace for more info)
```
### After
```
error: no rules expected the token `"fn"`
--> src/main.rs:103:10
|
32 | macro_rules! t {
| -------------- when calling this macro
...
103 | t!["fn"];
| ^^^^ no rules expected this token in macro call
|
note: while trying to match `"fn"`
--> src/main.rs:34:6
|
34 | ($name) => {
| ^^^^^
...
58 | / make_t_for_all_tokens! {
59 | | "fn" as Token::Fn,
60 | | "return" as Token::Return,
61 | | "let" as Token::Let,
62 | | }
| |_- in this macro invocation
= note: captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens
= note: see https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment for more information
= help: try using `:tt` instead in the macro definition
= note: this error originates in the macro `make_t_for_all_tokens` (in Nightly builds, run with -Z macro-backtrace for more info)
```
## Unresolved questions
- Preferrably the suggestion should be attached to the `$name:literal` part of the outer macro, instead of being in the notes section at the end. But I'm not familiar with how the compiler works at all, and I have no idea how to approach this kind of solution.
- `@Nilstrieb` raised a question that the suggestion of adding `:tt` isn't accurate when there's more than `tt` being matched, for example when the input is an `item`.