Factor out suggest_ref_mut; use it in rustc_borrowck

Also teach rustc_borrowck not to show useless help messages like
"use a mutable reference instead: `x`".
This commit is contained in:
ashtneoi 2018-07-12 15:39:36 -07:00
parent 323df7b504
commit 531a68cea7
5 changed files with 27 additions and 39 deletions

View File

@ -39,6 +39,7 @@ use rustc::middle::free_region::RegionRelations;
use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::query::Providers; use rustc::ty::query::Providers;
use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin}; use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
use rustc_mir::util::suggest_ref_mut;
use rustc::util::nodemap::FxHashSet; use rustc::util::nodemap::FxHashSet;
use std::cell::RefCell; use std::cell::RefCell;
@ -1206,21 +1207,17 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
self.note_immutable_local(db, error_node_id, node_id) self.note_immutable_local(db, error_node_id, node_id)
} }
Some(ImmutabilityBlame::LocalDeref(node_id)) => { Some(ImmutabilityBlame::LocalDeref(node_id)) => {
let let_span = self.tcx.hir.span(node_id);
match self.local_binding_mode(node_id) { match self.local_binding_mode(node_id) {
ty::BindByReference(..) => { ty::BindByReference(..) => {
if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(let_span) { let let_span = self.tcx.hir.span(node_id);
let replace_str = if snippet.starts_with("ref ") { let suggestion = suggest_ref_mut(self.tcx, let_span);
snippet.replacen("ref ", "ref mut ", 1) if let Some((let_span, replace_str)) = suggestion {
} else {
snippet
};
db.span_suggestion( db.span_suggestion(
let_span, let_span,
"use a mutable reference instead", "use a mutable reference instead",
replace_str, replace_str,
); );
}; }
} }
ty::BindByValue(..) => { ty::BindByValue(..) => {
if let (Some(local_ty), is_implicit_self) = self.local_ty(node_id) { if let (Some(local_ty), is_implicit_self) = self.local_ty(node_id) {

View File

@ -29,8 +29,6 @@ use rustc_data_structures::indexed_set::IdxSetBuf;
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::small_vec::SmallVec; use rustc_data_structures::small_vec::SmallVec;
use core::unicode::property::Pattern_White_Space;
use std::rc::Rc; use std::rc::Rc;
use syntax_pos::Span; use syntax_pos::Span;
@ -46,6 +44,7 @@ use dataflow::{EverInitializedPlaces, MovingOutStatements};
use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
use util::borrowck_errors::{BorrowckErrors, Origin}; use util::borrowck_errors::{BorrowckErrors, Origin};
use util::collect_writes::FindAssignments; use util::collect_writes::FindAssignments;
use util::suggest_ref_mut;
use self::borrow_set::{BorrowData, BorrowSet}; use self::borrow_set::{BorrowData, BorrowSet};
use self::flows::Flows; use self::flows::Flows;
@ -1861,7 +1860,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm { ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
binding_mode: ty::BindingMode::BindByReference(_), binding_mode: ty::BindingMode::BindByReference(_),
.. ..
})) => suggest_ref_mut(self.tcx, local_decl), })) => suggest_ref_mut(self.tcx, local_decl.source_info.span),
ClearCrossCrate::Clear => bug!("saw cleared local state"), ClearCrossCrate::Clear => bug!("saw cleared local state"),
}; };
@ -1957,22 +1956,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
assert_eq!(ty_mut.mutbl, hir::MutImmutable); assert_eq!(ty_mut.mutbl, hir::MutImmutable);
(highlight_span, format!("&mut {}", ty_mut.ty)) (highlight_span, format!("&mut {}", ty_mut.ty))
} }
fn suggest_ref_mut<'cx, 'gcx, 'tcx>(
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
local_decl: &mir::LocalDecl<'tcx>,
) -> Option<(Span, String)> {
let hi_span = local_decl.source_info.span;
let hi_src = tcx.sess.codemap().span_to_snippet(hi_span).unwrap();
if hi_src.starts_with("ref")
&& hi_src["ref".len()..].starts_with(Pattern_White_Space)
{
let suggestion = format!("ref mut{}", &hi_src["ref".len()..]);
Some((hi_span, suggestion))
} else {
None
}
}
} }
/// Adds the place into the used mutable variables set /// Adds the place into the used mutable variables set

View File

@ -8,6 +8,10 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use core::unicode::property::Pattern_White_Space;
use rustc::ty;
use syntax_pos::Span;
pub mod borrowck_errors; pub mod borrowck_errors;
pub mod elaborate_drops; pub mod elaborate_drops;
pub mod def_use; pub mod def_use;
@ -23,3 +27,19 @@ pub use self::alignment::is_disaligned;
pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere}; pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere};
pub use self::graphviz::{write_mir_graphviz}; pub use self::graphviz::{write_mir_graphviz};
pub use self::graphviz::write_node_label as write_graphviz_node_label; pub use self::graphviz::write_node_label as write_graphviz_node_label;
/// If possible, suggest replacing `ref` with `ref mut`.
pub fn suggest_ref_mut<'cx, 'gcx, 'tcx>(
tcx: ty::TyCtxt<'cx, 'gcx, 'tcx>,
pattern_span: Span,
) -> Option<(Span, String)> {
let hi_src = tcx.sess.codemap().span_to_snippet(pattern_span).unwrap();
if hi_src.starts_with("ref")
&& hi_src["ref".len()..].starts_with(Pattern_White_Space)
{
let replacement = format!("ref mut{}", &hi_src["ref".len()..]);
Some((pattern_span, replacement))
} else {
None
}
}

View File

@ -1,24 +1,18 @@
error[E0594]: cannot assign to immutable borrowed content `*x` error[E0594]: cannot assign to immutable borrowed content `*x`
--> $DIR/enum.rs:19:5 --> $DIR/enum.rs:19:5
| |
LL | let Wrap(x) = &Wrap(3);
| - help: use a mutable reference instead: `x`
LL | *x += 1; //~ ERROR cannot assign to immutable LL | *x += 1; //~ ERROR cannot assign to immutable
| ^^^^^^^ cannot borrow as mutable | ^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to immutable borrowed content `*x` error[E0594]: cannot assign to immutable borrowed content `*x`
--> $DIR/enum.rs:23:9 --> $DIR/enum.rs:23:9
| |
LL | if let Some(x) = &Some(3) {
| - help: use a mutable reference instead: `x`
LL | *x += 1; //~ ERROR cannot assign to immutable LL | *x += 1; //~ ERROR cannot assign to immutable
| ^^^^^^^ cannot borrow as mutable | ^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to immutable borrowed content `*x` error[E0594]: cannot assign to immutable borrowed content `*x`
--> $DIR/enum.rs:29:9 --> $DIR/enum.rs:29:9
| |
LL | while let Some(x) = &Some(3) {
| - help: use a mutable reference instead: `x`
LL | *x += 1; //~ ERROR cannot assign to immutable LL | *x += 1; //~ ERROR cannot assign to immutable
| ^^^^^^^ cannot borrow as mutable | ^^^^^^^ cannot borrow as mutable

View File

@ -1,24 +1,18 @@
error[E0594]: cannot assign to immutable borrowed content `*n` error[E0594]: cannot assign to immutable borrowed content `*n`
--> $DIR/explicit-mut.rs:17:13 --> $DIR/explicit-mut.rs:17:13
| |
LL | Some(n) => {
| - help: use a mutable reference instead: `n`
LL | *n += 1; //~ ERROR cannot assign to immutable LL | *n += 1; //~ ERROR cannot assign to immutable
| ^^^^^^^ cannot borrow as mutable | ^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to immutable borrowed content `*n` error[E0594]: cannot assign to immutable borrowed content `*n`
--> $DIR/explicit-mut.rs:25:13 --> $DIR/explicit-mut.rs:25:13
| |
LL | Some(n) => {
| - help: use a mutable reference instead: `n`
LL | *n += 1; //~ ERROR cannot assign to immutable LL | *n += 1; //~ ERROR cannot assign to immutable
| ^^^^^^^ cannot borrow as mutable | ^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to immutable borrowed content `*n` error[E0594]: cannot assign to immutable borrowed content `*n`
--> $DIR/explicit-mut.rs:33:13 --> $DIR/explicit-mut.rs:33:13
| |
LL | Some(n) => {
| - help: use a mutable reference instead: `n`
LL | *n += 1; //~ ERROR cannot assign to immutable LL | *n += 1; //~ ERROR cannot assign to immutable
| ^^^^^^^ cannot borrow as mutable | ^^^^^^^ cannot borrow as mutable