From afd38e95208725f6d96730d64a311f6deda07d4e Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sat, 1 Feb 2020 02:05:38 +0100 Subject: [PATCH] Suggest removing `&mut` when encountering mutability error --- .../diagnostics/mutability_errors.rs | 22 ++++++++++++++----- .../ui/borrowck/issue-68697-remove-mut-ref.rs | 15 +++++++++++++ .../issue-68697-remove-mut-ref.stderr | 12 ++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/borrowck/issue-68697-remove-mut-ref.rs create mode 100644 src/test/ui/borrowck/issue-68697-remove-mut-ref.stderr diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index 563ff1112c3a6..bba3bdb3e927a 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -257,12 +257,22 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { assert_eq!(local_decl.mutability, Mutability::Not); err.span_label(span, format!("cannot {ACT}", ACT = act)); - err.span_suggestion( - local_decl.source_info.span, - "consider changing this to be mutable", - format!("mut {}", self.local_names[local].unwrap()), - Applicability::MachineApplicable, - ); + + if let ty::Ref(_, _, Mutability::Mut) = local_decl.ty.kind { + err.span_suggestion( + span, + "remove the unnecessary `&mut` here", + self.local_names[local].unwrap().to_string(), + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestion( + local_decl.source_info.span, + "consider changing this to be mutable", + format!("mut {}", self.local_names[local].unwrap()), + Applicability::MachineApplicable, + ); + } } // Also suggest adding mut for upvars diff --git a/src/test/ui/borrowck/issue-68697-remove-mut-ref.rs b/src/test/ui/borrowck/issue-68697-remove-mut-ref.rs new file mode 100644 index 0000000000000..1cfb5cd2843af --- /dev/null +++ b/src/test/ui/borrowck/issue-68697-remove-mut-ref.rs @@ -0,0 +1,15 @@ +// Regression test for #68697: Suggest removing `&mut x` +// when `x: &mut T` and `&mut T` is expected type + +struct A; + +fn bar(x: &mut A) {} + +fn foo(x: &mut A) { + bar(&mut x); + //~^ ERROR: cannot borrow `x` as mutable + //~| HELP: remove the unnecessary `&mut` here + //~| SUGGESTION: x +} + +fn main() {} diff --git a/src/test/ui/borrowck/issue-68697-remove-mut-ref.stderr b/src/test/ui/borrowck/issue-68697-remove-mut-ref.stderr new file mode 100644 index 0000000000000..fc57a94fdd4cd --- /dev/null +++ b/src/test/ui/borrowck/issue-68697-remove-mut-ref.stderr @@ -0,0 +1,12 @@ +error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable + --> $DIR/issue-68697-remove-mut-ref.rs:6:9 + | +LL | bar(&mut x); + | ^^^^^^ + | | + | cannot borrow as mutable + | help: remove the unnecessary `&mut` here: `x` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`.