about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs14
1 files changed, 12 insertions, 2 deletions
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index 013cb2a49b2..862b650efd7 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -47,7 +47,7 @@ use rustc_middle::ty::{
 };
 use rustc_session::lint;
 use rustc_span::sym;
-use rustc_span::{MultiSpan, Span, Symbol};
+use rustc_span::{MultiSpan, Span, Symbol, DUMMY_SP};
 use rustc_trait_selection::infer::InferCtxtExt;
 
 use rustc_data_structures::stable_map::FxHashMap;
@@ -644,7 +644,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                     diagnostics_builder.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>");
-                    let closure_body_span = self.tcx.hir().span(body_id.hir_id);
+
+                    let mut closure_body_span = self.tcx.hir().span(body_id.hir_id);
+
+                    // If the body was entirely expanded from a macro
+                    // invocation, as the body is not contained inside the
+                    // closure span. In that case, 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 (sugg, app) =
                         match self.tcx.sess.source_map().span_to_snippet(closure_body_span) {
                             Ok(s) => {