Change:
produces: It expanded the macro. This only happens when the macro invocation is the entire body of the closure.
cc
Working on a fix.

Discussion:
}; use rustc_session::lint; use rustc_span::sym; <del> use rustc_span::{MultiSpan, Span, Symbol}; </del> <ins> use rustc_span::{MultiSpan, Span, Symbol, DUMMY_SP}; </ins> use rustc_trait_selection::infer::InferCtxtExt; use rustc_data_structures::stable_map::FxHashMap;

} } diagnostics_builder.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>"); <del> let closure_body_span = self.tcx.hir().span(body_id.hir_id); let (sugg, app) = </del> <ins> let mut closure_body_span = self.tcx.hir().span(body_id.hir_id); // If the body was entirely expanded from a macro // invocation, i.e. the body is not contained inside the // closure span, then we walk up the expansion until we // find the span before the expansion. while !closure_body_span.is_dummy() && !closure_span.contains(closure_body_span) { closure_body_span = closure_body_span.parent().unwrap_or(DUMMY_SP); } let (span, sugg, app) = </ins> match self.tcx.sess.source_map().span_to_snippet(closure_body_span) { Ok(s) => { let trimmed = s.trim_start();

} else { format!("{{ {}; {} }}", migration_string, s) }; <del> (sugg, Applicability::MachineApplicable) </del> <ins> (closure_body_span, sugg, Applicability::MachineApplicable) </ins> } <del> Err(_) => (migration_string.clone(), Applicability::HasPlaceholders), </del> <ins> Err(_) => (closure_span, migration_string.clone(), Applicability::HasPlaceholders), </ins> }; let diagnostic_msg = format!(

); diagnostics_builder.span_suggestion( <del> closure_body_span, </del> <ins> span, </ins> &diagnostic_msg, sugg, app,

<ins> // run-rustfix // See https://github.com/rust-lang/rust/issues/87955 #![deny(rust_2021_incompatible_closure_captures)] //~^ NOTE: the lint level is defined here fn main() { let a = ("hey".to_string(), "123".to_string()); let _ = || { let _ = &a; dbg!(a.0) }; //~^ ERROR: drop order //~| NOTE: only captures `a.0` //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `a` to be fully captured } //~^ NOTE: dropped here </ins>

<ins> // run-rustfix // See https://github.com/rust-lang/rust/issues/87955 #![deny(rust_2021_incompatible_closure_captures)] //~^ NOTE: the lint level is defined here fn main() { let a = ("hey".to_string(), "123".to_string()); let _ = || dbg!(a.0); //~^ ERROR: drop order //~| NOTE: only captures `a.0` //~| NOTE: for more information, see //~| HELP: add a dummy let to cause `a` to be fully captured } //~^ NOTE: dropped here </ins>

<ins> error: changes to closure capture in Rust 2021 will affect drop order --> $DIR/macro.rs:10:13 | LL |     let _ = || dbg!(a.0); |             ^^^^^^^^---^ |                     | |                     in Rust 2018, closure captures all of `a`, but in Rust 2021, it only captures `a.0` ... LL | } | - in Rust 2018, `a` would be dropped here, but in Rust 2021, only `a.0` would be dropped here alongside the closure | note: the lint level is defined here --> $DIR/macro.rs:5:9 | LL | #![deny(rust_2021_incompatible_closure_captures)] |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> help: add a dummy let to cause `a` to be fully captured | LL |     let _ = || { let _ = &a; dbg!(a.0) }; |                ~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error </ins>