@@ -47,7 +47,7 @@ use rustc_middle::ty::{
47
47
} ;
48
48
use rustc_session:: lint;
49
49
use rustc_span:: sym;
50
- use rustc_span:: { BytePos , MultiSpan , Pos , Span , Symbol , DUMMY_SP } ;
50
+ use rustc_span:: { BytePos , MultiSpan , Pos , Span , Symbol } ;
51
51
use rustc_trait_selection:: infer:: InferCtxtExt ;
52
52
53
53
use rustc_data_structures:: stable_map:: FxHashMap ;
@@ -680,15 +680,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
680
680
migrated_variables_concat
681
681
) ;
682
682
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
+ }
690
708
691
- if let Ok ( s) = self . tcx . sess . source_map ( ) . span_to_snippet ( closure_body_span) {
692
709
let mut lines = s. lines ( ) ;
693
710
let line1 = lines. next ( ) . unwrap_or_default ( ) ;
694
711
0 commit comments