rust-lang / rust-lang/rust

E0499 mentions "previous iteration of the loop" in proc macro code without any loops.

Open
#135,403 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics A-macros A-proc-macros T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code
use quote::quote;

#[proc_macro]
pub fn my_macro(_: proc_macro::TokenStream) -> proc_macro::TokenStream {
    quote! {
        struct Thing<'a>(&'a mut i32);
        impl Drop for Thing<'_> {
            fn drop(&mut self) {}
        }
        #[allow(unused)]
        fn test() {
            let mut foo = 1;
            if let Some(thing) = Some(Thing(&mut foo)) {
            } else {
                let x = &mut foo;
            }
        }
    }
    .into()
}
Current output
error[E0499]: cannot borrow `foo` as mutable more than once at a time
 --> src/lib.rs:1:1
  |
1 | bar::my_macro!();
  | ^^^^^^^^^^^^^^^-
  | |              |
  | |              ... and the first borrow might be used here, when that temporary is dropped and runs the destructor for type `Option<Thing<'_>>`
  | `foo` was mutably borrowed here in the previous iteration of the loop
  | a temporary with access to the first borrow is created here ...
  |
  = note: this error originates in the macro `bar::my_macro` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0499`.
error: could not compile `foo` (lib) due to 1 previous error
Desired output
Something not mentioning loops
Rationale and extra context

I was poking around to see how the rust 2024 "if let temporary scope" changes interact with different spans from proc macros, and I discovered this issue.

The error output above occurs when the macro is called from another crate with no arguments. Both the calling crate and the proc macro crate use edition 2021.

Full code for reproducing the issue: foo.zip

Other cases

Rust Version
rustc 1.86.0-nightly (eb54a5083 2025-01-11)
binary: rustc
commit-hash: eb54a50837ad4bcc9842924f27e7287ca66e294c
commit-date: 2025-01-11
host: aarch64-apple-darwin
release: 1.86.0-nightly
LLVM version: 19.1.6
Anything else?

No response

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

Start with the supplied proc-macro reproduction and the E0499 diagnostic output, focusing on how the compiler produces the note referring to a previous loop iteration. Done means the same example no longer mentions loops when no loop is present, with a regression test covering the diagnostic.

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.