@@ -847,20 +847,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
847847 self . add_rust_2024_migration_desugared_pat (
848848 pat_info. top_info . hir_id ,
849849 pat,
850- ident . span ,
850+ 't' , // last char of `mut`
851851 def_br_mutbl,
852852 ) ;
853853 BindingMode ( ByRef :: No , Mutability :: Mut )
854854 }
855855 }
856856 BindingMode ( ByRef :: No , mutbl) => BindingMode ( def_br, mutbl) ,
857- BindingMode ( ByRef :: Yes ( _ ) , _) => {
857+ BindingMode ( ByRef :: Yes ( user_br_mutbl ) , _) => {
858858 if let ByRef :: Yes ( def_br_mutbl) = def_br {
859859 // `ref`/`ref mut` overrides the binding mode on edition <= 2021
860860 self . add_rust_2024_migration_desugared_pat (
861861 pat_info. top_info . hir_id ,
862862 pat,
863- ident. span ,
863+ match user_br_mutbl {
864+ Mutability :: Not => 'f' , // last char of `ref`
865+ Mutability :: Mut => 't' , // last char of `ref mut`
866+ } ,
864867 def_br_mutbl,
865868 ) ;
866869 }
@@ -2440,7 +2443,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24402443 self . add_rust_2024_migration_desugared_pat (
24412444 pat_info. top_info . hir_id ,
24422445 pat,
2443- inner. span ,
2446+ match pat_mutbl {
2447+ Mutability :: Not => '&' , // last char of `&`
2448+ Mutability :: Mut => 't' , // last char of `&mut`
2449+ } ,
24442450 inh_mut,
24452451 )
24462452 }
@@ -2832,18 +2838,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28322838 & self ,
28332839 pat_id : HirId ,
28342840 subpat : & ' tcx Pat < ' tcx > ,
2835- cutoff_span : Span ,
2841+ final_char : char ,
28362842 def_br_mutbl : Mutability ,
28372843 ) {
28382844 // Try to trim the span we're labeling to just the `&` or binding mode that's an issue.
2839- // If the subpattern's span is is from an expansion, the emitted label will not be trimmed.
2840- let source_map = self . tcx . sess . source_map ( ) ;
2841- let cutoff_span = source_map
2842- . span_extend_prev_while ( cutoff_span, |c| c. is_whitespace ( ) || c == '(' )
2843- . unwrap_or ( cutoff_span) ;
2844- // Ensure we use the syntax context and thus edition of `subpat.span`; this will be a hard
2845- // error if the subpattern is of edition >= 2024.
2846- let trimmed_span = subpat. span . until ( cutoff_span) . with_ctxt ( subpat. span . ctxt ( ) ) ;
2845+ let from_expansion = subpat. span . from_expansion ( ) ;
2846+ let trimmed_span = if from_expansion {
2847+ // If the subpattern is from an expansion, highlight the whole macro call instead.
2848+ subpat. span
2849+ } else {
2850+ let trimmed = self . tcx . sess . source_map ( ) . span_through_char ( subpat. span , final_char) ;
2851+ // The edition of the trimmed span should be the same as `subpat.span`; this will be a
2852+ // a hard error if the subpattern is of edition >= 2024. We set it manually to be sure:
2853+ trimmed. with_ctxt ( subpat. span . ctxt ( ) )
2854+ } ;
28472855
28482856 let mut typeck_results = self . typeck_results . borrow_mut ( ) ;
28492857 let mut table = typeck_results. rust_2024_migration_desugared_pats_mut ( ) ;
@@ -2877,7 +2885,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28772885 } ;
28782886 // Only provide a detailed label if the problematic subpattern isn't from an expansion.
28792887 // In the case that it's from a macro, we'll add a more detailed note in the emitter.
2880- let from_expansion = subpat. span . from_expansion ( ) ;
28812888 let primary_label = if from_expansion {
28822889 // We can't suggest eliding modifiers within expansions.
28832890 info. suggest_eliding_modes = false ;
0 commit comments