From 1ad2f5cec45869311f3a51731f77bbed009a66e9 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 30 Aug 2018 19:46:27 +0200 Subject: [PATCH] Added help message for missing IndexMut impl. --- src/librustc_mir/borrow_check/mod.rs | 3 +- .../borrow_check/mutability_errors.rs | 50 +++++++++++++++++-- .../ui/borrowck/index-mut-help.nll.stderr | 4 ++ src/test/ui/issues/issue-41726.nll.stderr | 2 + 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index b06a1e0e19f6a..a04d202efcfb0 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -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 ); } } diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 645cce8dd793b..38cdd17a7273c 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -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)); } diff --git a/src/test/ui/borrowck/index-mut-help.nll.stderr b/src/test/ui/borrowck/index-mut-help.nll.stderr index cc058f1fde5da..a15f37684e738 100644 --- a/src/test/ui/borrowck/index-mut-help.nll.stderr +++ b/src/test/ui/borrowck/index-mut-help.nll.stderr @@ -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 diff --git a/src/test/ui/issues/issue-41726.nll.stderr b/src/test/ui/issues/issue-41726.nll.stderr index 06ff743a0f5ed..9f727881beaf2 100644 --- a/src/test/ui/issues/issue-41726.nll.stderr +++ b/src/test/ui/issues/issue-41726.nll.stderr @@ -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>` error: aborting due to previous error