@@ -5,7 +5,10 @@ use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
55use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
66use rustc_middle:: {
77 hir:: place:: PlaceBase ,
8- mir:: { self , ClearCrossCrate , Local , LocalDecl , LocalInfo , LocalKind , Location } ,
8+ mir:: {
9+ self , BindingForm , ClearCrossCrate , ImplicitSelfKind , Local , LocalDecl , LocalInfo ,
10+ LocalKind , Location ,
11+ } ,
912} ;
1013use rustc_span:: source_map:: DesugaringKind ;
1114use rustc_span:: symbol:: { kw, Symbol } ;
@@ -241,13 +244,56 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
241244 . map ( |l| mut_borrow_of_mutable_ref ( l, self . local_names [ local] ) )
242245 . unwrap_or ( false ) =>
243246 {
247+ let decl = & self . body . local_decls [ local] ;
244248 err. span_label ( span, format ! ( "cannot {ACT}" , ACT = act) ) ;
245- err. span_suggestion (
246- span,
247- "try removing `&mut` here" ,
248- String :: new ( ) ,
249- Applicability :: MaybeIncorrect ,
250- ) ;
249+ if let Some ( mir:: Statement {
250+ source_info,
251+ kind :
252+ mir:: StatementKind :: Assign ( box (
253+ _,
254+ mir:: Rvalue :: Ref (
255+ _,
256+ mir:: BorrowKind :: Mut { allow_two_phase_borrow : false } ,
257+ _,
258+ ) ,
259+ ) ) ,
260+ ..
261+ } ) = & self . body [ location. block ] . statements . get ( location. statement_index )
262+ {
263+ match decl. local_info {
264+ Some ( box LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: Var (
265+ mir:: VarBindingForm {
266+ binding_mode : ty:: BindingMode :: BindByValue ( Mutability :: Not ) ,
267+ opt_ty_info : Some ( sp) ,
268+ opt_match_place : _,
269+ pat_span : _,
270+ } ,
271+ ) ) ) ) => {
272+ err. span_note ( sp, "the binding is already a mutable borrow" ) ;
273+ }
274+ _ => {
275+ err. span_note (
276+ decl. source_info . span ,
277+ "the binding is already a mutable borrow" ,
278+ ) ;
279+ }
280+ }
281+ err. span_help ( source_info. span , "try removing `&mut` here" ) ;
282+ } else if decl. mutability == Mutability :: Not
283+ && !matches ! (
284+ decl. local_info,
285+ Some ( box LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf (
286+ ImplicitSelfKind :: MutRef
287+ ) ) ) )
288+ )
289+ {
290+ err. span_suggestion_verbose (
291+ decl. source_info . span . shrink_to_lo ( ) ,
292+ "consider making the binding mutable" ,
293+ "mut " . to_string ( ) ,
294+ Applicability :: MachineApplicable ,
295+ ) ;
296+ }
251297 }
252298
253299 // We want to suggest users use `let mut` for local (user
0 commit comments