rust-lang / rust-lang/rust

Suboptimal diagnostic spans for macros that regurgitate attributes

Open
#146,567 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-attributes A-diagnostics A-macros D-imprecise-spans T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code
macro_rules! tuple_const {
    ($(#[$attr:meta])* $vis:vis const $NAME:ident: $ty:ty = $expr:expr;) => {
        $(#[$attr])* $vis const $NAME: ($ty,) = ($expr,);
    }
}

tuple_const! {
    #[inline]
    pub const FOO: u32 = 17;
}
Current output
error[E0518]: attribute should be applied to function or closure
  --> src/lib.rs:3:11
   |
3  |           $(#[$attr])* $vis const $NAME: ($ty,) = ($expr,);
   |             ^^^^^^^^   ------------------------------------ not a function or closure
...
7  | / tuple_const! {
8  | |     #[inline]
9  | |     pub const FOO: u32 = 17;
10 | | }
   | |_- in this macro invocation
   |
   = note: this error originates in the macro `tuple_const` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0518`.
Desired output
error: `#[inline]` attribute cannot be used on constants
 --> src/lib.rs:8:5
  |
8 |     #[inline]
  |       ^^^^^^
  |
  = help: `#[inline]` can only be applied to functions
Rationale and extra context

It’s common for macro_rules! macros that parse and emit items to contain a matcher of the form $(#[$attr:meta])* in order to parse the attributes, and then to re-emit the attributes using $(#[$attr])* in the macro body. The standard library’s thread_local! is an example of such a macro.

Diagnostic messages involving attributes generally point to the entire attribute span, including the surrounding #[]. However, for invocations of macros that use the technique described above, the #[ and ] are considered to originate from the macro. This means that diagnostic messages relating to these macro invocations will point to the entire macro invocation, not the specific attribute that the diagnostic is concerned with.

If the compiler were to use a slightly smaller span for attribute diagnostics (excluding the outer #[]`) whenever possible, or at least in cases like this one, that would resolve the issue.

Rust Version
rustc 1.91.0-nightly (02c7b1a7a 2025-09-13)
binary: rustc
commit-hash: 02c7b1a7ac1d739663878030510508372e46f254
commit-date: 2025-09-13
host: x86_64-unknown-linux-gnu
release: 1.91.0-nightly
LLVM version: 21.1.1

@rustbot label A-attributes A-macros D-imprecise-spans

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the diagnostic using the macro_rules! example in src/lib.rs, then trace the compiler's attribute diagnostic span handling for attributes regurgitated by macros. Done means the error points to the invocation's #[inline] attribute and reports that it cannot be used on constants, rather than pointing to the macro definition.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.