@@ -306,11 +306,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
306
306
/// In addition of this check, it also checks between references mutability state. If the
307
307
/// expected is mutable but the provided isn't, maybe we could just say "Hey, try with
308
308
/// `&mut`!".
309
- pub fn check_ref ( & self ,
310
- expr : & hir:: Expr ,
311
- checked_ty : Ty < ' tcx > ,
312
- expected : Ty < ' tcx > )
313
- -> Option < ( Span , & ' static str , String ) > {
309
+ pub fn check_ref (
310
+ & self ,
311
+ expr : & hir:: Expr ,
312
+ checked_ty : Ty < ' tcx > ,
313
+ expected : Ty < ' tcx > ,
314
+ ) -> Option < ( Span , & ' static str , String ) > {
314
315
let cm = self . sess ( ) . source_map ( ) ;
315
316
let sp = expr. span ;
316
317
if !cm. span_to_filename ( sp) . is_real ( ) {
@@ -397,6 +398,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
397
398
} else {
398
399
String :: new ( )
399
400
} ;
401
+ if let Some ( hir:: Node :: Expr ( hir:: Expr {
402
+ node : hir:: ExprKind :: Assign ( left_expr, _) ,
403
+ ..
404
+ } ) ) = self . tcx . hir ( ) . find_by_hir_id (
405
+ self . tcx . hir ( ) . get_parent_node_by_hir_id ( expr. hir_id ) ,
406
+ ) {
407
+ if mutability == hir:: Mutability :: MutMutable {
408
+ // Found the following case:
409
+ // fn foo(opt: &mut Option<String>){ opt = None }
410
+ // --- ^^^^
411
+ // | |
412
+ // consider dereferencing here: `*opt` |
413
+ // expected mutable reference, found enum `Option`
414
+ if let Ok ( src) = cm. span_to_snippet ( left_expr. span ) {
415
+ return Some ( (
416
+ left_expr. span ,
417
+ "consider dereferencing here to assign to the mutable \
418
+ borrowed piece of memory",
419
+ format ! ( "*{}" , src) ,
420
+ ) ) ;
421
+ }
422
+ }
423
+ }
400
424
return Some ( match mutability {
401
425
hir:: Mutability :: MutMutable => (
402
426
sp,
0 commit comments