@@ -306,11 +306,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
306306 /// In addition of this check, it also checks between references mutability state. If the
307307 /// expected is mutable but the provided isn't, maybe we could just say "Hey, try with
308308 /// `&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 ) > {
314315 let cm = self . sess ( ) . source_map ( ) ;
315316 let sp = expr. span ;
316317 if !cm. span_to_filename ( sp) . is_real ( ) {
@@ -397,6 +398,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
397398 } else {
398399 String :: new ( )
399400 } ;
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+ }
400424 return Some ( match mutability {
401425 hir:: Mutability :: MutMutable => (
402426 sp,
0 commit comments