From a6af6d6506e0420f2a62ce519db029c97f8cdd0b Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Mon, 9 Aug 2021 11:05:50 +0000 Subject: [PATCH] Provide structured suggestion for removal of `&mut` --- .../diagnostics/mutability_errors.rs | 22 +++++++++++++++++-- .../ui/borrowck/mut-borrow-of-mut-ref.stderr | 15 +++++-------- src/test/ui/did_you_mean/issue-34126.stderr | 5 ++--- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs index f8a1b05f063..4e079ed865a 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs @@ -12,7 +12,7 @@ use rustc_middle::{ }; use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::{kw, Symbol}; -use rustc_span::Span; +use rustc_span::{BytePos, Span}; use crate::borrow_check::diagnostics::BorrowedContentSource; use crate::borrow_check::MirBorrowckCtxt; @@ -278,7 +278,25 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); } } - err.span_help(source_info.span, "try removing `&mut` here"); + if let Ok(snippet) = + self.infcx.tcx.sess.source_map().span_to_snippet(source_info.span) + { + if snippet.starts_with("&mut ") { + // We don't have access to the HIR to get accurate spans, but we can + // give a best effort structured suggestion. + err.span_suggestion_verbose( + source_info.span.with_hi(source_info.span.lo() + BytePos(5)), + "try removing `&mut` here", + String::new(), + Applicability::MachineApplicable, + ); + } else { + // This can occur with things like `(&mut self).foo()`. + err.span_help(source_info.span, "try removing `&mut` here"); + } + } else { + err.span_help(source_info.span, "try removing `&mut` here"); + } } else if decl.mutability == Mutability::Not && !matches!( decl.local_info, diff --git a/src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr b/src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr index 3ed54179b98..aa7771a736c 100644 --- a/src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr +++ b/src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr @@ -10,10 +10,9 @@ note: the binding is already a mutable borrow LL | pub fn f(b: &mut i32) { | ^^^^^^^^ help: try removing `&mut` here - --> $DIR/mut-borrow-of-mut-ref.rs:7:7 | -LL | h(&mut b); - | ^^^^^^ +LL | h(b); + | -- error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable --> $DIR/mut-borrow-of-mut-ref.rs:11:12 @@ -27,10 +26,9 @@ note: the binding is already a mutable borrow LL | pub fn f(b: &mut i32) { | ^^^^^^^^ help: try removing `&mut` here - --> $DIR/mut-borrow-of-mut-ref.rs:11:12 | -LL | g(&mut &mut b); - | ^^^^^^ +LL | g(&mut b); + | -- error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable --> $DIR/mut-borrow-of-mut-ref.rs:18:12 @@ -44,10 +42,9 @@ note: the binding is already a mutable borrow LL | pub fn g(b: &mut i32) { | ^^^^^^^^ help: try removing `&mut` here - --> $DIR/mut-borrow-of-mut-ref.rs:18:12 | -LL | h(&mut &mut b); - | ^^^^^^ +LL | h(&mut b); + | -- error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable --> $DIR/mut-borrow-of-mut-ref.rs:35:5 diff --git a/src/test/ui/did_you_mean/issue-34126.stderr b/src/test/ui/did_you_mean/issue-34126.stderr index a8c031686c0..86bc27106a9 100644 --- a/src/test/ui/did_you_mean/issue-34126.stderr +++ b/src/test/ui/did_you_mean/issue-34126.stderr @@ -10,10 +10,9 @@ note: the binding is already a mutable borrow LL | fn start(&mut self) { | ^^^^^^^^^ help: try removing `&mut` here - --> $DIR/issue-34126.rs:6:18 | -LL | self.run(&mut self); - | ^^^^^^^^^ +LL | self.run(self); + | -- error[E0502]: cannot borrow `self` as mutable because it is also borrowed as immutable --> $DIR/issue-34126.rs:6:18