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:
parent
323df7b504
commit
531a68cea7
@ -39,6 +39,7 @@ use rustc::middle::free_region::RegionRelations;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
|
||||
use rustc_mir::util::suggest_ref_mut;
|
||||
use rustc::util::nodemap::FxHashSet;
|
||||
|
||||
use std::cell::RefCell;
|
||||
@ -1206,21 +1207,17 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
self.note_immutable_local(db, error_node_id, node_id)
|
||||
}
|
||||
Some(ImmutabilityBlame::LocalDeref(node_id)) => {
|
||||
let let_span = self.tcx.hir.span(node_id);
|
||||
match self.local_binding_mode(node_id) {
|
||||
ty::BindByReference(..) => {
|
||||
if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(let_span) {
|
||||
let replace_str = if snippet.starts_with("ref ") {
|
||||
snippet.replacen("ref ", "ref mut ", 1)
|
||||
} else {
|
||||
snippet
|
||||
};
|
||||
let let_span = self.tcx.hir.span(node_id);
|
||||
let suggestion = suggest_ref_mut(self.tcx, let_span);
|
||||
if let Some((let_span, replace_str)) = suggestion {
|
||||
db.span_suggestion(
|
||||
let_span,
|
||||
"use a mutable reference instead",
|
||||
replace_str,
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
ty::BindByValue(..) => {
|
||||
if let (Some(local_ty), is_implicit_self) = self.local_ty(node_id) {
|
||||
|
@ -29,8 +29,6 @@ use rustc_data_structures::indexed_set::IdxSetBuf;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc_data_structures::small_vec::SmallVec;
|
||||
|
||||
use core::unicode::property::Pattern_White_Space;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use syntax_pos::Span;
|
||||
@ -46,6 +44,7 @@ use dataflow::{EverInitializedPlaces, MovingOutStatements};
|
||||
use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
|
||||
use util::borrowck_errors::{BorrowckErrors, Origin};
|
||||
use util::collect_writes::FindAssignments;
|
||||
use util::suggest_ref_mut;
|
||||
|
||||
use self::borrow_set::{BorrowData, BorrowSet};
|
||||
use self::flows::Flows;
|
||||
@ -1861,7 +1860,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
|
||||
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"),
|
||||
};
|
||||
@ -1957,22 +1956,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
assert_eq!(ty_mut.mutbl, hir::MutImmutable);
|
||||
(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
|
||||
|
@ -8,6 +8,10 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// 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 elaborate_drops;
|
||||
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::graphviz::{write_mir_graphviz};
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,18 @@
|
||||
error[E0594]: cannot assign to immutable borrowed content `*x`
|
||||
--> $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
|
||||
| ^^^^^^^ cannot borrow as mutable
|
||||
|
||||
error[E0594]: cannot assign to immutable borrowed content `*x`
|
||||
--> $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
|
||||
| ^^^^^^^ cannot borrow as mutable
|
||||
|
||||
error[E0594]: cannot assign to immutable borrowed content `*x`
|
||||
--> $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
|
||||
| ^^^^^^^ cannot borrow as mutable
|
||||
|
||||
|
@ -1,24 +1,18 @@
|
||||
error[E0594]: cannot assign to immutable borrowed content `*n`
|
||||
--> $DIR/explicit-mut.rs:17:13
|
||||
|
|
||||
LL | Some(n) => {
|
||||
| - help: use a mutable reference instead: `n`
|
||||
LL | *n += 1; //~ ERROR cannot assign to immutable
|
||||
| ^^^^^^^ cannot borrow as mutable
|
||||
|
||||
error[E0594]: cannot assign to immutable borrowed content `*n`
|
||||
--> $DIR/explicit-mut.rs:25:13
|
||||
|
|
||||
LL | Some(n) => {
|
||||
| - help: use a mutable reference instead: `n`
|
||||
LL | *n += 1; //~ ERROR cannot assign to immutable
|
||||
| ^^^^^^^ cannot borrow as mutable
|
||||
|
||||
error[E0594]: cannot assign to immutable borrowed content `*n`
|
||||
--> $DIR/explicit-mut.rs:33:13
|
||||
|
|
||||
LL | Some(n) => {
|
||||
| - help: use a mutable reference instead: `n`
|
||||
LL | *n += 1; //~ ERROR cannot assign to immutable
|
||||
| ^^^^^^^ cannot borrow as mutable
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user