@@ -144,16 +144,8 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> {
144144                } ) ; 
145145                return ; 
146146            } 
147-             ExprKind :: Match  {  scrutinee,  scrutinee_hir_id,  box ref  arms }  => { 
148-                 let  source = match  ex. span . desugaring_kind ( )  { 
149-                     Some ( DesugaringKind :: ForLoop )  => hir:: MatchSource :: ForLoopDesugar , 
150-                     Some ( DesugaringKind :: QuestionMark )  => { 
151-                         hir:: MatchSource :: TryDesugar ( scrutinee_hir_id) 
152-                     } 
153-                     Some ( DesugaringKind :: Await )  => hir:: MatchSource :: AwaitDesugar , 
154-                     _ => hir:: MatchSource :: Normal , 
155-                 } ; 
156-                 self . check_match ( scrutinee,  arms,  source,  ex. span ) ; 
147+             ExprKind :: Match  {  scrutinee,  scrutinee_hir_id :  _,  box ref  arms,  match_source }  => { 
148+                 self . check_match ( scrutinee,  arms,  match_source,  ex. span ) ; 
157149            } 
158150            ExprKind :: Let  {  box ref  pat,  expr }  => { 
159151                self . check_let ( pat,  Some ( expr) ,  ex. span ) ; 
@@ -505,8 +497,41 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
505497                    None , 
506498                ) ; 
507499            }  else  { 
500+                 // span after scrutinee, or after `.match`. That is, the braces, arms, 
501+                 // and any whitespace preceding the braces. 
502+                 let  braces_span = match  source { 
503+                     hir:: MatchSource :: Normal  => scrut
504+                         . span 
505+                         . find_ancestor_in_same_ctxt ( expr_span) 
506+                         . map ( |scrut_span| scrut_span. shrink_to_hi ( ) . with_hi ( expr_span. hi ( ) ) ) , 
507+                     hir:: MatchSource :: Postfix  => { 
508+                         // This is horrendous, and we should deal with it by just 
509+                         // stashing the span of the braces somewhere (like in the match source). 
510+                         scrut. span . find_ancestor_in_same_ctxt ( expr_span) . and_then ( |scrut_span| { 
511+                             let  sm = self . tcx . sess . source_map ( ) ; 
512+                             let  brace_span = sm. span_extend_to_next_char ( scrut_span,  '{' ,  true ) ; 
513+                             if  sm. span_to_snippet ( sm. next_point ( brace_span) ) . as_deref ( )  == Ok ( "{" )  { 
514+                                 let  sp = brace_span. shrink_to_hi ( ) . with_hi ( expr_span. hi ( ) ) ; 
515+                                 // We also need to extend backwards for whitespace 
516+                                 sm. span_extend_prev_while ( sp,  |c| c. is_whitespace ( ) ) . ok ( ) 
517+                             }  else  { 
518+                                 None 
519+                             } 
520+                         } ) 
521+                     } 
522+                     hir:: MatchSource :: ForLoopDesugar 
523+                     | hir:: MatchSource :: TryDesugar ( _) 
524+                     | hir:: MatchSource :: AwaitDesugar 
525+                     | hir:: MatchSource :: FormatArgs  => None , 
526+                 } ; 
508527                self . error  = Err ( report_non_exhaustive_match ( 
509-                     & cx,  self . thir ,  scrut. ty ,  scrut. span ,  witnesses,  arms,  expr_span, 
528+                     & cx, 
529+                     self . thir , 
530+                     scrut. ty , 
531+                     scrut. span , 
532+                     witnesses, 
533+                     arms, 
534+                     braces_span, 
510535                ) ) ; 
511536            } 
512537        } 
@@ -929,7 +954,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
929954    sp :  Span , 
930955    witnesses :  Vec < WitnessPat < ' p ,  ' tcx > > , 
931956    arms :  & [ ArmId ] , 
932-     expr_span :   Span , 
957+     braces_span :   Option < Span > , 
933958)  -> ErrorGuaranteed  { 
934959    let  is_empty_match = arms. is_empty ( ) ; 
935960    let  non_empty_enum = match  scrut_ty. kind ( )  { 
@@ -941,8 +966,8 @@ fn report_non_exhaustive_match<'p, 'tcx>(
941966    if  is_empty_match && !non_empty_enum { 
942967        return  cx. tcx . dcx ( ) . emit_err ( NonExhaustivePatternsTypeNotEmpty  { 
943968            cx, 
944-             expr_span , 
945-             span :  sp , 
969+             scrut_span :  sp , 
970+             braces_span , 
946971            ty :  scrut_ty, 
947972        } ) ; 
948973    } 
@@ -1028,15 +1053,15 @@ fn report_non_exhaustive_match<'p, 'tcx>(
10281053    let  mut  suggestion = None ; 
10291054    let  sm = cx. tcx . sess . source_map ( ) ; 
10301055    match  arms { 
1031-         [ ]  if  sp . eq_ctxt ( expr_span )  => { 
1056+         [ ]  if  let   Some ( braces_span )  = braces_span  => { 
10321057            // Get the span for the empty match body `{}`. 
10331058            let  ( indentation,  more)  = if  let  Some ( snippet)  = sm. indentation_before ( sp)  { 
10341059                ( format ! ( "\n {snippet}" ) ,  "    " ) 
10351060            }  else  { 
10361061                ( " " . to_string ( ) ,  "" ) 
10371062            } ; 
10381063            suggestion = Some ( ( 
1039-                 sp . shrink_to_hi ( ) . with_hi ( expr_span . hi ( ) ) , 
1064+                 braces_span , 
10401065                format ! ( " {{{indentation}{more}{suggested_arm},{indentation}}}" , ) , 
10411066            ) ) ; 
10421067        } 
0 commit comments