Skip to content

Commit 1ad2f5c

Browse files
committed
Added help message for missing IndexMut impl.
1 parent ef6851c commit 1ad2f5c

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed

src/librustc_mir/borrow_check/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1601,8 +1601,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16011601
if let Some(&init_index) = first_init_index {
16021602
// And, if so, report an error.
16031603
let init = &self.move_data.inits[init_index];
1604+
let span = init.span(&self.mir);
16041605
self.report_illegal_reassignment(
1605-
context, place_span, init.span(&self.mir), place_span.0
1606+
context, place_span, span, place_span.0
16061607
);
16071608
}
16081609
}

src/librustc_mir/borrow_check/mutability_errors.rs

+46-4
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010

1111
use rustc::hir;
1212
use rustc::hir::Node;
13-
use rustc::mir::{self, BindingForm, ClearCrossCrate, Local, Location, Mir};
14-
use rustc::mir::{Mutability, Place, Projection, ProjectionElem, Static};
15-
use rustc::ty::{self, TyCtxt};
13+
use rustc::mir::{self, BindingForm, Constant, ClearCrossCrate, Local, Location, Mir};
14+
use rustc::mir::{Mutability, Operand, Place, Projection, ProjectionElem, Static, Terminator};
15+
use rustc::mir::TerminatorKind;
16+
use rustc::ty::{self, Const, DefIdTree, TyS, TyKind, TyCtxt};
1617
use rustc_data_structures::indexed_vec::Idx;
1718
use syntax_pos::Span;
1819

@@ -22,7 +23,7 @@ use util::borrowck_errors::{BorrowckErrors, Origin};
2223
use util::collect_writes::FindAssignments;
2324
use util::suggest_ref_mut;
2425

25-
#[derive(Copy, Clone, Debug)]
26+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
2627
pub(super) enum AccessKind {
2728
MutableBorrow,
2829
Mutate,
@@ -394,6 +395,47 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
394395
);
395396
}
396397

398+
Place::Projection(box Projection {
399+
base: Place::Local(local),
400+
elem: ProjectionElem::Deref,
401+
}) if error_access == AccessKind::MutableBorrow => {
402+
err.span_label(span, format!("cannot {ACT}", ACT = act));
403+
404+
let mpi = self.move_data.rev_lookup.find_local(*local);
405+
for i in self.move_data.init_path_map[mpi].iter() {
406+
if let InitLocation::Statement(location) = self.move_data.inits[*i].location {
407+
if let Some(
408+
Terminator {
409+
kind: TerminatorKind::Call {
410+
func: Operand::Constant(box Constant {
411+
literal: Const {
412+
ty: &TyS {
413+
sty: TyKind::FnDef(id, substs),
414+
..
415+
},
416+
..
417+
},
418+
..
419+
}),
420+
..
421+
},
422+
..
423+
}
424+
) = &self.mir.basic_blocks()[location.block].terminator {
425+
if self.tcx.parent(id) == self.tcx.lang_items().index_trait() {
426+
err.help(
427+
&format!(
428+
"trait `IndexMut` is required to modify indexed content, \
429+
but it is not implemented for `{}`",
430+
substs.type_at(0),
431+
),
432+
);
433+
}
434+
}
435+
}
436+
}
437+
}
438+
397439
_ => {
398440
err.span_label(span, format!("cannot {ACT}", ACT = act));
399441
}

src/test/ui/borrowck/index-mut-help.nll.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ error[E0596]: cannot borrow data in a `&` reference as mutable
33
|
44
LL | map["peter"].clear(); //~ ERROR
55
| ^^^^^^^^^^^^ cannot borrow as mutable
6+
|
7+
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<&str, std::string::String>`
68

79
error[E0594]: cannot assign to data in a `&` reference
810
--> $DIR/index-mut-help.rs:22:5
@@ -15,6 +17,8 @@ error[E0596]: cannot borrow data in a `&` reference as mutable
1517
|
1618
LL | let _ = &mut map["peter"]; //~ ERROR
1719
| ^^^^^^^^^^^^^^^^^ cannot borrow as mutable
20+
|
21+
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<&str, std::string::String>`
1822

1923
error: aborting due to 3 previous errors
2024

src/test/ui/issues/issue-41726.nll.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ error[E0596]: cannot borrow data in a `&` reference as mutable
33
|
44
LL | things[src.as_str()].sort(); //~ ERROR cannot borrow immutable
55
| ^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
6+
|
7+
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<std::string::String, std::vec::Vec<std::string::String>>`
68

79
error: aborting due to previous error
810

0 commit comments

Comments
 (0)