@@ -41,7 +41,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4141 return_ty
4242 } ;
4343
44- self . check_lhs_assignable ( lhs, "E0067" , op. span , |_| { } ) ;
44+ self . check_lhs_assignable ( lhs, "E0067" , op. span , |err| {
45+ if let Ref ( _, rty, hir:: Mutability :: Mut ) = lhs_ty. kind ( ) {
46+ if self
47+ . lookup_op_method ( * rty, Some ( rhs_ty) , Some ( rhs) , Op :: Binary ( op, IsAssign :: Yes ) )
48+ . is_ok ( )
49+ {
50+ // Suppress this error, since we already emitted
51+ // a deref suggestion in check_overloaded_binop
52+ err. delay_as_bug ( ) ;
53+ }
54+ }
55+ } ) ;
4556
4657 ty
4758 }
@@ -404,8 +415,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
404415 ( err, missing_trait, use_output)
405416 }
406417 } ;
407- if let Ref ( _, rty, _) = lhs_ty. kind ( ) {
408- if self . infcx . type_is_copy_modulo_regions ( self . param_env , * rty, lhs_expr. span )
418+ if let Ref ( _, rty, mutability) = lhs_ty. kind ( ) {
419+ let is_copy =
420+ self . infcx . type_is_copy_modulo_regions ( self . param_env , * rty, lhs_expr. span ) ;
421+ // We should suggest `a + b` => `*a + b` if `a` is copy, and suggest
422+ // `a += b` => `*a += b` if a is a mut ref.
423+ // FIXME: This could be done any time lhs_ty is DerefMut into something that
424+ // is compatible with rhs_ty, and not _just_ `&mut` (for IsAssign::Yes).
425+ if ( ( is_assign == IsAssign :: No && is_copy)
426+ || ( is_assign == IsAssign :: Yes && * mutability == hir:: Mutability :: Mut ) )
409427 && self
410428 . lookup_op_method (
411429 * rty,
0 commit comments