Skip to content

Commit

Permalink
Added help message for missing IndexMut impl.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidtwco committed Aug 30, 2018
1 parent ef6851c commit 1ad2f5c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/librustc_mir/borrow_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1601,8 +1601,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
if let Some(&init_index) = first_init_index {
// And, if so, report an error.
let init = &self.move_data.inits[init_index];
let span = init.span(&self.mir);
self.report_illegal_reassignment(
context, place_span, init.span(&self.mir), place_span.0
context, place_span, span, place_span.0
);
}
}
Expand Down
50 changes: 46 additions & 4 deletions src/librustc_mir/borrow_check/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@

use rustc::hir;
use rustc::hir::Node;
use rustc::mir::{self, BindingForm, ClearCrossCrate, Local, Location, Mir};
use rustc::mir::{Mutability, Place, Projection, ProjectionElem, Static};
use rustc::ty::{self, TyCtxt};
use rustc::mir::{self, BindingForm, Constant, ClearCrossCrate, Local, Location, Mir};
use rustc::mir::{Mutability, Operand, Place, Projection, ProjectionElem, Static, Terminator};
use rustc::mir::TerminatorKind;
use rustc::ty::{self, Const, DefIdTree, TyS, TyKind, TyCtxt};
use rustc_data_structures::indexed_vec::Idx;
use syntax_pos::Span;

Expand All @@ -22,7 +23,7 @@ use util::borrowck_errors::{BorrowckErrors, Origin};
use util::collect_writes::FindAssignments;
use util::suggest_ref_mut;

#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(super) enum AccessKind {
MutableBorrow,
Mutate,
Expand Down Expand Up @@ -394,6 +395,47 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
);
}

Place::Projection(box Projection {
base: Place::Local(local),
elem: ProjectionElem::Deref,
}) if error_access == AccessKind::MutableBorrow => {
err.span_label(span, format!("cannot {ACT}", ACT = act));

let mpi = self.move_data.rev_lookup.find_local(*local);
for i in self.move_data.init_path_map[mpi].iter() {
if let InitLocation::Statement(location) = self.move_data.inits[*i].location {
if let Some(
Terminator {
kind: TerminatorKind::Call {
func: Operand::Constant(box Constant {
literal: Const {
ty: &TyS {
sty: TyKind::FnDef(id, substs),
..
},
..
},
..
}),
..
},
..
}
) = &self.mir.basic_blocks()[location.block].terminator {
if self.tcx.parent(id) == self.tcx.lang_items().index_trait() {
err.help(
&format!(
"trait `IndexMut` is required to modify indexed content, \
but it is not implemented for `{}`",
substs.type_at(0),
),
);
}
}
}
}
}

_ => {
err.span_label(span, format!("cannot {ACT}", ACT = act));
}
Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/borrowck/index-mut-help.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ error[E0596]: cannot borrow data in a `&` reference as mutable
|
LL | map["peter"].clear(); //~ ERROR
| ^^^^^^^^^^^^ cannot borrow as mutable
|
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<&str, std::string::String>`

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

error: aborting due to 3 previous errors

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-41726.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ error[E0596]: cannot borrow data in a `&` reference as mutable
|
LL | things[src.as_str()].sort(); //~ ERROR cannot borrow immutable
| ^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
|
= 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>>`

error: aborting due to previous error

Expand Down

0 comments on commit 1ad2f5c

Please sign in to comment.