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::{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) {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user