@@ -47,7 +47,7 @@ use rustc_middle::ty::{
4747} ;
4848use rustc_session:: lint;
4949use rustc_span:: sym;
50- use rustc_span:: { BytePos , MultiSpan , Pos , Span , Symbol , DUMMY_SP } ;
50+ use rustc_span:: { BytePos , MultiSpan , Pos , Span , Symbol } ;
5151use rustc_trait_selection:: infer:: InferCtxtExt ;
5252
5353use rustc_data_structures:: stable_map:: FxHashMap ;
@@ -680,15 +680,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
680680 migrated_variables_concat
681681 ) ;
682682
683- // If the body was entirely expanded from a macro
684- // invocation, i.e. the body is not contained inside the
685- // closure span, then we walk up the expansion until we
686- // find the span before the expansion.
687- let closure_body_span = self . tcx . hir ( ) . span ( body_id. hir_id )
688- . find_ancestor_inside ( closure_span)
689- . unwrap_or ( DUMMY_SP ) ;
683+ let mut closure_body_span = {
684+ // If the body was entirely expanded from a macro
685+ // invocation, i.e. the body is not contained inside the
686+ // closure span, then we walk up the expansion until we
687+ // find the span before the expansion.
688+ let s = self . tcx . hir ( ) . span ( body_id. hir_id ) ;
689+ s. find_ancestor_inside ( closure_span) . unwrap_or ( s)
690+ } ;
691+
692+ if let Ok ( mut s) = self . tcx . sess . source_map ( ) . span_to_snippet ( closure_body_span) {
693+ if s. starts_with ( '$' ) {
694+ // Looks like a macro fragment. Try to find the real block.
695+ if let Some ( hir:: Node :: Expr ( & hir:: Expr {
696+ kind : hir:: ExprKind :: Block ( block, ..) , ..
697+ } ) ) = self . tcx . hir ( ) . find ( body_id. hir_id ) {
698+ // If the body is a block (with `{..}`), we use the span of that block.
699+ // E.g. with a `|| $body` expanded from a `m!({ .. })`, we use `{ .. }`, and not `$body`.
700+ // Since we know it's a block, we know we can insert the `let _ = ..` without
701+ // breaking the macro syntax.
702+ if let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( block. span ) {
703+ closure_body_span = block. span ;
704+ s = snippet;
705+ }
706+ }
707+ }
690708
691- if let Ok ( s) = self . tcx . sess . source_map ( ) . span_to_snippet ( closure_body_span) {
692709 let mut lines = s. lines ( ) ;
693710 let line1 = lines. next ( ) . unwrap_or_default ( ) ;
694711
0 commit comments