@@ -649,39 +649,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
649
649
}
650
650
}
651
651
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 < ' _ > ) {
659
653
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 {
661
656
let binding_parent_id = tcx. hir ( ) . get_parent_node ( pat. hir_id ) ;
662
657
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
+
664
665
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
673
674
) ;
674
675
}
675
- hir:: Node :: Arm ( _) | hir:: Node :: Pat ( _) => {
676
+ hir:: Node :: Param ( _ ) | hir :: Node :: Arm ( _) | hir:: Node :: Pat ( _) => {
676
677
// 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
+ ) ;
685
684
}
686
685
_ => { } // don't provide suggestions in other cases #55175
687
686
}
@@ -1853,7 +1852,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1853
1852
1854
1853
// Take region, inner-type from expected type if we can,
1855
1854
// 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).
1857
1856
debug ! ( "check_pat_ref: expected={:?}" , expected) ;
1858
1857
match * expected. kind ( ) {
1859
1858
ty:: Ref ( _, r_ty, r_mutbl) if r_mutbl == mutbl => ( expected, r_ty) ,
@@ -1869,7 +1868,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1869
1868
// Look for a case like `fn foo(&foo: u32)` and suggest
1870
1869
// `fn foo(foo: &u32)`
1871
1870
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) ;
1873
1872
err. emit ( ) ;
1874
1873
}
1875
1874
( rptr_ty, inner_ty)
0 commit comments