Skip to content

Commit 531a68c

Browse files
committed
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`".
1 parent 323df7b commit 531a68c

File tree

5 files changed

+27
-39
lines changed

5 files changed

+27
-39
lines changed

src/librustc_borrowck/borrowck/mod.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use rustc::middle::free_region::RegionRelations;
3939
use rustc::ty::{self, Ty, TyCtxt};
4040
use rustc::ty::query::Providers;
4141
use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
42+
use rustc_mir::util::suggest_ref_mut;
4243
use rustc::util::nodemap::FxHashSet;
4344

4445
use std::cell::RefCell;
@@ -1206,21 +1207,17 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
12061207
self.note_immutable_local(db, error_node_id, node_id)
12071208
}
12081209
Some(ImmutabilityBlame::LocalDeref(node_id)) => {
1209-
let let_span = self.tcx.hir.span(node_id);
12101210
match self.local_binding_mode(node_id) {
12111211
ty::BindByReference(..) => {
1212-
if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(let_span) {
1213-
let replace_str = if snippet.starts_with("ref ") {
1214-
snippet.replacen("ref ", "ref mut ", 1)
1215-
} else {
1216-
snippet
1217-
};
1212+
let let_span = self.tcx.hir.span(node_id);
1213+
let suggestion = suggest_ref_mut(self.tcx, let_span);
1214+
if let Some((let_span, replace_str)) = suggestion {
12181215
db.span_suggestion(
12191216
let_span,
12201217
"use a mutable reference instead",
12211218
replace_str,
12221219
);
1223-
};
1220+
}
12241221
}
12251222
ty::BindByValue(..) => {
12261223
if let (Some(local_ty), is_implicit_self) = self.local_ty(node_id) {

src/librustc_mir/borrow_check/mod.rs

+2-19
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ use rustc_data_structures::indexed_set::IdxSetBuf;
2929
use rustc_data_structures::indexed_vec::Idx;
3030
use rustc_data_structures::small_vec::SmallVec;
3131

32-
use core::unicode::property::Pattern_White_Space;
33-
3432
use std::rc::Rc;
3533

3634
use syntax_pos::Span;
@@ -46,6 +44,7 @@ use dataflow::{EverInitializedPlaces, MovingOutStatements};
4644
use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
4745
use util::borrowck_errors::{BorrowckErrors, Origin};
4846
use util::collect_writes::FindAssignments;
47+
use util::suggest_ref_mut;
4948

5049
use self::borrow_set::{BorrowData, BorrowSet};
5150
use self::flows::Flows;
@@ -1861,7 +1860,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
18611860
ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
18621861
binding_mode: ty::BindingMode::BindByReference(_),
18631862
..
1864-
})) => suggest_ref_mut(self.tcx, local_decl),
1863+
})) => suggest_ref_mut(self.tcx, local_decl.source_info.span),
18651864

18661865
ClearCrossCrate::Clear => bug!("saw cleared local state"),
18671866
};
@@ -1957,22 +1956,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
19571956
assert_eq!(ty_mut.mutbl, hir::MutImmutable);
19581957
(highlight_span, format!("&mut {}", ty_mut.ty))
19591958
}
1960-
1961-
fn suggest_ref_mut<'cx, 'gcx, 'tcx>(
1962-
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
1963-
local_decl: &mir::LocalDecl<'tcx>,
1964-
) -> Option<(Span, String)> {
1965-
let hi_span = local_decl.source_info.span;
1966-
let hi_src = tcx.sess.codemap().span_to_snippet(hi_span).unwrap();
1967-
if hi_src.starts_with("ref")
1968-
&& hi_src["ref".len()..].starts_with(Pattern_White_Space)
1969-
{
1970-
let suggestion = format!("ref mut{}", &hi_src["ref".len()..]);
1971-
Some((hi_span, suggestion))
1972-
} else {
1973-
None
1974-
}
1975-
}
19761959
}
19771960

19781961
/// Adds the place into the used mutable variables set

src/librustc_mir/util/mod.rs

+20
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use core::unicode::property::Pattern_White_Space;
12+
use rustc::ty;
13+
use syntax_pos::Span;
14+
1115
pub mod borrowck_errors;
1216
pub mod elaborate_drops;
1317
pub mod def_use;
@@ -23,3 +27,19 @@ pub use self::alignment::is_disaligned;
2327
pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere};
2428
pub use self::graphviz::{write_mir_graphviz};
2529
pub use self::graphviz::write_node_label as write_graphviz_node_label;
30+
31+
/// If possible, suggest replacing `ref` with `ref mut`.
32+
pub fn suggest_ref_mut<'cx, 'gcx, 'tcx>(
33+
tcx: ty::TyCtxt<'cx, 'gcx, 'tcx>,
34+
pattern_span: Span,
35+
) -> Option<(Span, String)> {
36+
let hi_src = tcx.sess.codemap().span_to_snippet(pattern_span).unwrap();
37+
if hi_src.starts_with("ref")
38+
&& hi_src["ref".len()..].starts_with(Pattern_White_Space)
39+
{
40+
let replacement = format!("ref mut{}", &hi_src["ref".len()..]);
41+
Some((pattern_span, replacement))
42+
} else {
43+
None
44+
}
45+
}

src/test/ui/rfc-2005-default-binding-mode/enum.stderr

-6
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
error[E0594]: cannot assign to immutable borrowed content `*x`
22
--> $DIR/enum.rs:19:5
33
|
4-
LL | let Wrap(x) = &Wrap(3);
5-
| - help: use a mutable reference instead: `x`
64
LL | *x += 1; //~ ERROR cannot assign to immutable
75
| ^^^^^^^ cannot borrow as mutable
86

97
error[E0594]: cannot assign to immutable borrowed content `*x`
108
--> $DIR/enum.rs:23:9
119
|
12-
LL | if let Some(x) = &Some(3) {
13-
| - help: use a mutable reference instead: `x`
1410
LL | *x += 1; //~ ERROR cannot assign to immutable
1511
| ^^^^^^^ cannot borrow as mutable
1612

1713
error[E0594]: cannot assign to immutable borrowed content `*x`
1814
--> $DIR/enum.rs:29:9
1915
|
20-
LL | while let Some(x) = &Some(3) {
21-
| - help: use a mutable reference instead: `x`
2216
LL | *x += 1; //~ ERROR cannot assign to immutable
2317
| ^^^^^^^ cannot borrow as mutable
2418

src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr

-6
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
error[E0594]: cannot assign to immutable borrowed content `*n`
22
--> $DIR/explicit-mut.rs:17:13
33
|
4-
LL | Some(n) => {
5-
| - help: use a mutable reference instead: `n`
64
LL | *n += 1; //~ ERROR cannot assign to immutable
75
| ^^^^^^^ cannot borrow as mutable
86

97
error[E0594]: cannot assign to immutable borrowed content `*n`
108
--> $DIR/explicit-mut.rs:25:13
119
|
12-
LL | Some(n) => {
13-
| - help: use a mutable reference instead: `n`
1410
LL | *n += 1; //~ ERROR cannot assign to immutable
1511
| ^^^^^^^ cannot borrow as mutable
1612

1713
error[E0594]: cannot assign to immutable borrowed content `*n`
1814
--> $DIR/explicit-mut.rs:33:13
1915
|
20-
LL | Some(n) => {
21-
| - help: use a mutable reference instead: `n`
2216
LL | *n += 1; //~ ERROR cannot assign to immutable
2317
| ^^^^^^^ cannot borrow as mutable
2418

0 commit comments

Comments
 (0)