提交 531a68ce 编写于 作者: A ashtneoi

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`".
上级 323df7b5
......@@ -39,6 +39,7 @@
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 @@ fn note_immutability_blame(&self,
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_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::{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 @@ enum AccessKind {
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 @@ fn suggest_ampmut<'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::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
}
}
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
......
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册