Description
It used to be the case that attribute macros would only ever be invoked with syntactically valid input. Rustc would snip out or otherwise fix up invalid syntax prior to dispatching the macro invocation. This ensures that rustc's recovery from the invalid syntax, and any diagnostics emitted by rustc to that effect, are consistent with any subsequent diagnostics emitted by the macro, rather than requiring both to perform independent and inconsistent heuristics to recover from the invalid input.
However, it looks like recent rustc versions (1.51+) have begun invoking attribute macros on invalid syntax. Can we find out whether this behavior is intended or a regression from recent Span-related work (#43081 — @Aaron1011)? IMO the newfangled behavior is not necessarily desirable so I have filed this as a regression.
// src/lib.rs
use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn repro(_args: TokenStream, input: TokenStream) -> TokenStream {
eprintln!("{:#?}", input);
TokenStream::new()
}
// src/main.rs
#[repro::repro]
trait T {
fn run(&);
}
fn main() {}
# Cargo.toml
[package]
name = "repro"
version = "0.0.0"
edition = "2018"
publish = false
[lib]
proc-macro = true
- 1.31 through 1.39: macro is invoked with
trait T {}
as input. Invalid syntax has been snipped out. - 1.40 through 1.50: macro is invoked with
trait T { fn run(); }
as input, invalid syntax snipped out with finer granularity. - 1.51+: macro is invoked with
trait T { fn run(&); }
which is invalid syntax and not necessarily desirable.