@@ -649,39 +649,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
649649 }
650650 }
651651
652- fn borrow_pat_suggestion (
653- & self ,
654- err : & mut Diagnostic ,
655- pat : & Pat < ' _ > ,
656- inner : & Pat < ' _ > ,
657- expected : Ty < ' tcx > ,
658- ) {
652+ fn borrow_pat_suggestion ( & self , err : & mut Diagnostic , pat : & Pat < ' _ > , inner : & Pat < ' _ > ) {
659653 let tcx = self . tcx ;
660- if let PatKind :: Binding ( ..) = inner. kind {
654+ if let PatKind :: Ref ( _, mutbl) = pat. kind
655+ && let PatKind :: Binding ( _, _, binding, ..) = inner. kind {
661656 let binding_parent_id = tcx. hir ( ) . get_parent_node ( pat. hir_id ) ;
662657 let binding_parent = tcx. hir ( ) . get ( binding_parent_id) ;
663- debug ! ( "inner {:?} pat {:?} parent {:?}" , inner, pat, binding_parent) ;
658+ debug ! ( ?inner, ?pat, ?binding_parent) ;
659+
660+ let mutability = match mutbl {
661+ ast:: Mutability :: Mut => "mut" ,
662+ ast:: Mutability :: Not => "" ,
663+ } ;
664+
664665 match binding_parent {
665- hir:: Node :: Param ( hir:: Param { span , .. } )
666- if let Ok ( snippet ) = tcx . sess . source_map ( ) . span_to_snippet ( inner . span ) =>
667- {
668- err . span_suggestion (
669- * span,
670- & format ! ( "did you mean `{snippet}`" ) ,
671- format ! ( " &{expected}" ) ,
672- Applicability :: MachineApplicable ,
666+ hir:: Node :: Param ( hir:: Param { ty_span , .. } ) if binding . span . hi ( ) <= ty_span . lo ( ) => {
667+ err . multipart_suggestion_verbose (
668+ format ! ( "to take parameter by ref, move `&{mutability}` to the type" ) ,
669+ vec ! [
670+ ( pat . span. until ( inner . span ) , "" . to_owned ( ) ) ,
671+ ( ty_span . shrink_to_lo ( ) , format!( "&{}" , mutbl . prefix_str ( ) ) ) ,
672+ ] ,
673+ Applicability :: MachineApplicable
673674 ) ;
674675 }
675- hir:: Node :: Arm ( _) | hir:: Node :: Pat ( _) => {
676+ hir:: Node :: Param ( _ ) | hir :: Node :: Arm ( _) | hir:: Node :: Pat ( _) => {
676677 // rely on match ergonomics or it might be nested `&&pat`
677- if let Ok ( snippet) = tcx. sess . source_map ( ) . span_to_snippet ( inner. span ) {
678- err. span_suggestion (
679- pat. span ,
680- "you can probably remove the explicit borrow" ,
681- snippet,
682- Applicability :: MaybeIncorrect ,
683- ) ;
684- }
678+ err. span_suggestion_verbose (
679+ pat. span . until ( inner. span ) ,
680+ format ! ( "consider removing `&{mutability}` from the pattern" ) ,
681+ "" ,
682+ Applicability :: MaybeIncorrect ,
683+ ) ;
685684 }
686685 _ => { } // don't provide suggestions in other cases #55175
687686 }
@@ -1853,7 +1852,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18531852
18541853 // Take region, inner-type from expected type if we can,
18551854 // to avoid creating needless variables. This also helps with
1856- // the bad interactions of the given hack detailed in (note_1).
1855+ // the bad interactions of the given hack detailed in (note_1).
18571856 debug ! ( "check_pat_ref: expected={:?}" , expected) ;
18581857 match * expected. kind ( ) {
18591858 ty:: Ref ( _, r_ty, r_mutbl) if r_mutbl == mutbl => ( expected, r_ty) ,
@@ -1869,7 +1868,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18691868 // Look for a case like `fn foo(&foo: u32)` and suggest
18701869 // `fn foo(foo: &u32)`
18711870 if let Some ( mut err) = err {
1872- self . borrow_pat_suggestion ( & mut err, pat, inner, expected ) ;
1871+ self . borrow_pat_suggestion ( & mut err, pat, inner) ;
18731872 err. emit ( ) ;
18741873 }
18751874 ( rptr_ty, inner_ty)
0 commit comments