@@ -5,7 +5,10 @@ use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
5
5
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
6
6
use rustc_middle:: {
7
7
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
+ } ,
9
12
} ;
10
13
use rustc_span:: source_map:: DesugaringKind ;
11
14
use rustc_span:: symbol:: { kw, Symbol } ;
@@ -241,13 +244,56 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
241
244
. map ( |l| mut_borrow_of_mutable_ref ( l, self . local_names [ local] ) )
242
245
. unwrap_or ( false ) =>
243
246
{
247
+ let decl = & self . body . local_decls [ local] ;
244
248
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
+ }
251
297
}
252
298
253
299
// We want to suggest users use `let mut` for local (user
0 commit comments