Added help message for missing IndexMut impl.

This commit is contained in:
David Wood 2018-08-30 19:46:27 +02:00
parent ef6851cdb2
commit 1ad2f5cec4
No known key found for this signature in database
GPG key ID: 01760B4F9F53F154
4 changed files with 54 additions and 5 deletions

View file

@ -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
);
}
}

View file

@ -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;
@ -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,
@ -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));
}

View file

@ -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
@ -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

View file

@ -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