diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 10c9a439bf70f..5f61ed151c0d6 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -4,9 +4,9 @@ use rustc::hir::def_id::DefId; use rustc::mir::{ AggregateKind, Constant, Field, Local, LocalKind, Location, Operand, Place, PlaceBase, ProjectionElem, Rvalue, Statement, StatementKind, Static, - StaticKind, TerminatorKind, + StaticKind, Terminator, TerminatorKind, }; -use rustc::ty::{self, DefIdTree, Ty}; +use rustc::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc::ty::layout::VariantIdx; use rustc::ty::print::Print; use rustc_errors::DiagnosticBuilder; @@ -15,6 +15,7 @@ use syntax::symbol::sym; use super::borrow_set::BorrowData; use super::{MirBorrowckCtxt}; +use crate::dataflow::move_paths::{InitLocation, LookupResult}; pub(super) struct IncludingDowncast(pub(super) bool); @@ -401,6 +402,70 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.note(&message); } } + + pub(super) fn borrowed_content_source( + &self, + deref_base: &Place<'tcx>, + ) -> BorrowedContentSource<'tcx> { + let tcx = self.infcx.tcx; + + // Look up the provided place and work out the move path index for it, + // we'll use this to check whether it was originally from an overloaded + // operator. + match self.move_data.rev_lookup.find(deref_base) { + LookupResult::Exact(mpi) | LookupResult::Parent(Some(mpi)) => { + debug!("borrowed_content_source: mpi={:?}", mpi); + + for i in &self.move_data.init_path_map[mpi] { + let init = &self.move_data.inits[*i]; + debug!("borrowed_content_source: init={:?}", init); + // We're only interested in statements that initialized a value, not the + // initializations from arguments. + let loc = match init.location { + InitLocation::Statement(stmt) => stmt, + _ => continue, + }; + + let bbd = &self.body[loc.block]; + let is_terminator = bbd.statements.len() == loc.statement_index; + debug!( + "borrowed_content_source: loc={:?} is_terminator={:?}", + loc, + is_terminator, + ); + if !is_terminator { + continue; + } else if let Some(Terminator { + kind: TerminatorKind::Call { + ref func, + from_hir_call: false, + .. + }, + .. + }) = bbd.terminator { + if let Some(source) + = BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx) + { + return source; + } + } + } + } + // Base is a `static` so won't be from an overloaded operator + _ => (), + }; + + // If we didn't find an overloaded deref or index, then assume it's a + // built in deref and check the type of the base. + let base_ty = deref_base.ty(self.body, tcx).ty; + if base_ty.is_unsafe_ptr() { + BorrowedContentSource::DerefRawPointer + } else if base_ty.is_mutable_pointer() { + BorrowedContentSource::DerefMutableRef + } else { + BorrowedContentSource::DerefSharedRef + } + } } impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { @@ -547,6 +612,90 @@ impl UseSpans { } } +pub(super) enum BorrowedContentSource<'tcx> { + DerefRawPointer, + DerefMutableRef, + DerefSharedRef, + OverloadedDeref(Ty<'tcx>), + OverloadedIndex(Ty<'tcx>), +} + +impl BorrowedContentSource<'tcx> { + pub(super) fn describe_for_unnamed_place(&self) -> String { + match *self { + BorrowedContentSource::DerefRawPointer => format!("a raw pointer"), + BorrowedContentSource::DerefSharedRef => format!("a shared reference"), + BorrowedContentSource::DerefMutableRef => { + format!("a mutable reference") + } + BorrowedContentSource::OverloadedDeref(ty) => { + if ty.is_rc() { + format!("an `Rc`") + } else if ty.is_arc() { + format!("an `Arc`") + } else { + format!("dereference of `{}`", ty) + } + } + BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{}`", ty), + } + } + + pub(super) fn describe_for_named_place(&self) -> Option<&'static str> { + match *self { + BorrowedContentSource::DerefRawPointer => Some("raw pointer"), + BorrowedContentSource::DerefSharedRef => Some("shared reference"), + BorrowedContentSource::DerefMutableRef => Some("mutable reference"), + // Overloaded deref and index operators should be evaluated into a + // temporary. So we don't need a description here. + BorrowedContentSource::OverloadedDeref(_) + | BorrowedContentSource::OverloadedIndex(_) => None + } + } + + pub(super) fn describe_for_immutable_place(&self) -> String { + match *self { + BorrowedContentSource::DerefRawPointer => format!("a `*const` pointer"), + BorrowedContentSource::DerefSharedRef => format!("a `&` reference"), + BorrowedContentSource::DerefMutableRef => { + bug!("describe_for_immutable_place: DerefMutableRef isn't immutable") + }, + BorrowedContentSource::OverloadedDeref(ty) => { + if ty.is_rc() { + format!("an `Rc`") + } else if ty.is_arc() { + format!("an `Arc`") + } else { + format!("a dereference of `{}`", ty) + } + } + BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{}`", ty), + } + } + + fn from_call(func: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option { + match func.sty { + ty::FnDef(def_id, substs) => { + let trait_id = tcx.trait_of_item(def_id)?; + + let lang_items = tcx.lang_items(); + if Some(trait_id) == lang_items.deref_trait() + || Some(trait_id) == lang_items.deref_mut_trait() + { + Some(BorrowedContentSource::OverloadedDeref(substs.type_at(0))) + } else if Some(trait_id) == lang_items.index_trait() + || Some(trait_id) == lang_items.index_mut_trait() + { + Some(BorrowedContentSource::OverloadedIndex(substs.type_at(0))) + } else { + None + } + } + _ => None, + } + } +} + impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Finds the spans associated to a move or copy of move_place at location. pub(super) fn move_spans( diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs index d15229367251a..3130b7cec5b4a 100644 --- a/src/librustc_mir/borrow_check/move_errors.rs +++ b/src/librustc_mir/borrow_check/move_errors.rs @@ -1,7 +1,7 @@ use core::unicode::property::Pattern_White_Space; use rustc::mir::*; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty; use rustc_errors::{DiagnosticBuilder,Applicability}; use syntax_pos::Span; @@ -9,7 +9,7 @@ use crate::borrow_check::MirBorrowckCtxt; use crate::borrow_check::prefixes::PrefixSet; use crate::borrow_check::error_reporting::UseSpans; use crate::dataflow::move_paths::{ - IllegalMoveOrigin, IllegalMoveOriginKind, InitLocation, + IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex, }; use crate::util::borrowck_errors::{BorrowckErrors, Origin}; @@ -55,70 +55,6 @@ enum GroupedMoveError<'tcx> { }, } -enum BorrowedContentSource<'tcx> { - DerefRawPointer, - DerefMutableRef, - DerefSharedRef, - OverloadedDeref(Ty<'tcx>), - OverloadedIndex(Ty<'tcx>), -} - -impl BorrowedContentSource<'tcx> { - fn describe_for_unnamed_place(&self) -> String { - match *self { - BorrowedContentSource::DerefRawPointer => format!("a raw pointer"), - BorrowedContentSource::DerefSharedRef => format!("a shared reference"), - BorrowedContentSource::DerefMutableRef => { - format!("a mutable reference") - } - BorrowedContentSource::OverloadedDeref(ty) => { - if ty.is_rc() { - format!("an `Rc`") - } else if ty.is_arc() { - format!("an `Arc`") - } else { - format!("dereference of `{}`", ty) - } - } - BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{}`", ty), - } - } - - fn describe_for_named_place(&self) -> Option<&'static str> { - match *self { - BorrowedContentSource::DerefRawPointer => Some("raw pointer"), - BorrowedContentSource::DerefSharedRef => Some("shared reference"), - BorrowedContentSource::DerefMutableRef => Some("mutable reference"), - // Overloaded deref and index operators should be evaluated into a - // temporary. So we don't need a description here. - BorrowedContentSource::OverloadedDeref(_) - | BorrowedContentSource::OverloadedIndex(_) => None - } - } - - fn from_call(func: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option { - match func.sty { - ty::FnDef(def_id, substs) => { - let trait_id = tcx.trait_of_item(def_id)?; - - let lang_items = tcx.lang_items(); - if Some(trait_id) == lang_items.deref_trait() - || Some(trait_id) == lang_items.deref_mut_trait() - { - Some(BorrowedContentSource::OverloadedDeref(substs.type_at(0))) - } else if Some(trait_id) == lang_items.index_trait() - || Some(trait_id) == lang_items.index_mut_trait() - { - Some(BorrowedContentSource::OverloadedIndex(substs.type_at(0))) - } else { - None - } - } - _ => None, - } - } -} - impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { pub(crate) fn report_move_errors(&mut self, move_errors: Vec<(Place<'tcx>, MoveError<'tcx>)>) { let grouped_errors = self.group_move_errors(move_errors); @@ -646,65 +582,4 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); } } - - fn borrowed_content_source(&self, deref_base: &Place<'tcx>) -> BorrowedContentSource<'tcx> { - let tcx = self.infcx.tcx; - - // Look up the provided place and work out the move path index for it, - // we'll use this to check whether it was originally from an overloaded - // operator. - match self.move_data.rev_lookup.find(deref_base) { - LookupResult::Exact(mpi) | LookupResult::Parent(Some(mpi)) => { - debug!("borrowed_content_source: mpi={:?}", mpi); - - for i in &self.move_data.init_path_map[mpi] { - let init = &self.move_data.inits[*i]; - debug!("borrowed_content_source: init={:?}", init); - // We're only interested in statements that initialized a value, not the - // initializations from arguments. - let loc = match init.location { - InitLocation::Statement(stmt) => stmt, - _ => continue, - }; - - let bbd = &self.body[loc.block]; - let is_terminator = bbd.statements.len() == loc.statement_index; - debug!( - "borrowed_content_source: loc={:?} is_terminator={:?}", - loc, - is_terminator, - ); - if !is_terminator { - continue; - } else if let Some(Terminator { - kind: TerminatorKind::Call { - ref func, - from_hir_call: false, - .. - }, - .. - }) = bbd.terminator { - if let Some(source) - = BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx) - { - return source; - } - } - } - } - // Base is a `static` so won't be from an overloaded operator - _ => (), - }; - - // If we didn't find an overloaded deref or index, then assume it's a - // built in deref and check the type of the base. - let base_ty = deref_base.ty(self.body, tcx).ty; - if base_ty.is_unsafe_ptr() { - BorrowedContentSource::DerefRawPointer - } else if base_ty.is_mutable_pointer() { - BorrowedContentSource::DerefMutableRef - } else { - BorrowedContentSource::DerefSharedRef - } - } } diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 92c2e4e01f760..04814a15c626b 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -1,17 +1,14 @@ use rustc::hir; use rustc::hir::Node; -use rustc::mir::{self, BindingForm, Constant, ClearCrossCrate, Local, Location, Body}; -use rustc::mir::{ - Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static, StaticKind, -}; -use rustc::mir::{Terminator, TerminatorKind}; -use rustc::ty::{self, Const, DefIdTree, Ty, TyS, TyCtxt}; +use rustc::mir::{self, BindingForm, ClearCrossCrate, Local, Location, Body}; +use rustc::mir::{Mutability, Place, PlaceBase, Projection, ProjectionElem, Static, StaticKind}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc_data_structures::indexed_vec::Idx; use syntax_pos::Span; use syntax_pos::symbol::kw; -use crate::dataflow::move_paths::InitLocation; use crate::borrow_check::MirBorrowckCtxt; +use crate::borrow_check::error_reporting::BorrowedContentSource; use crate::util::borrowck_errors::{BorrowckErrors, Origin}; use crate::util::collect_writes::FindAssignments; use crate::util::suggest_ref_mut; @@ -43,6 +40,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let mut err; let item_msg; let reason; + let mut opt_source = None; let access_place_desc = self.describe_place(access_place); debug!("report_mutability_error: access_place_desc={:?}", access_place_desc); @@ -103,23 +101,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { item_msg = format!("`{}`", access_place_desc.unwrap()); reason = ", as it is immutable for the pattern guard".to_string(); } else { - let pointer_type = - if base.ty(self.body, self.infcx.tcx).ty.is_region_ptr() { - "`&` reference" - } else { - "`*const` pointer" - }; + let source = self.borrowed_content_source(base); + let pointer_type = source.describe_for_immutable_place(); + opt_source = Some(source); if let Some(desc) = access_place_desc { item_msg = format!("`{}`", desc); reason = match error_access { AccessKind::Move | - AccessKind::Mutate => format!(" which is behind a {}", pointer_type), + AccessKind::Mutate => format!(" which is behind {}", pointer_type), AccessKind::MutableBorrow => { - format!(", as it is behind a {}", pointer_type) + format!(", as it is behind {}", pointer_type) } } } else { - item_msg = format!("data in a {}", pointer_type); + item_msg = format!("data in {}", pointer_type); reason = String::new(); } } @@ -457,59 +452,31 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } Place::Projection(box Projection { - base: Place::Base(PlaceBase::Local(local)), + base: _, 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: ty::FnDef(id, substs), - .. - }, - .. - }, - .. - }), - .. - }, - .. - } - ) = &self.body.basic_blocks()[location.block].terminator { - let index_trait = self.infcx.tcx.lang_items().index_trait(); - if self.infcx.tcx.parent(id) == index_trait { - let mut found = false; - self.infcx.tcx.for_each_relevant_impl( - self.infcx.tcx.lang_items().index_mut_trait().unwrap(), - substs.type_at(0), - |_relevant_impl| { - found = true; - } - ); - - let extra = if found { - String::new() - } else { - format!(", but it is not implemented for `{}`", - substs.type_at(0)) - }; - - err.help( - &format!( - "trait `IndexMut` is required to modify indexed content{}", - extra, - ), - ); - } - } + match opt_source { + Some(BorrowedContentSource::OverloadedDeref(ty)) => { + err.help( + &format!( + "trait `DerefMut` is required to modify through a dereference, \ + but it is not implemented for `{}`", + ty, + ), + ); + }, + Some(BorrowedContentSource::OverloadedIndex(ty)) => { + err.help( + &format!( + "trait `IndexMut` is required to modify indexed content, \ + but it is not implemented for `{}`", + ty, + ), + ); } + _ => (), } } diff --git a/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs b/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs index 01dc0af855052..83eab7fdeab6a 100644 --- a/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs +++ b/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs @@ -2,18 +2,7 @@ // Deref and not DerefMut is implemented. use std::ops::Deref; - -struct Rc { - value: *const T -} - -impl Deref for Rc { - type Target = T; - - fn deref(&self) -> &T { - unsafe { &*self.value } - } -} +use std::rc::Rc; struct Point { x: isize, diff --git a/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.stderr b/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.stderr index dc52685363e39..d262c578843a0 100644 --- a/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.stderr +++ b/src/test/ui/borrowck/borrowck-borrow-overloaded-auto-deref.stderr @@ -1,86 +1,114 @@ -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:47:19 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:36:19 | LL | let __isize = &mut x.y; | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:51:19 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:40:19 | LL | let __isize = &mut x.y; | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:59:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:48:5 | LL | &mut x.y | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:63:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:52:5 | LL | &mut x.y | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:67:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:56:5 | LL | x.y = 3; | ^^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:71:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:60:5 | LL | x.y = 3; | ^^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:75:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:64:5 | LL | x.y = 3; | ^^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:83:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:72:5 | LL | x.set(0, 0); | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:87:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:76:5 | LL | x.set(0, 0); | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:95:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:84:5 | LL | x.y_mut() | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:99:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:88:5 | LL | x.y_mut() | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:103:6 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:92:6 | LL | *x.y_mut() = 3; | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:107:6 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:96:6 | LL | *x.y_mut() = 3; | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:111:6 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-auto-deref.rs:100:6 | LL | *x.y_mut() = 3; | ^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` error: aborting due to 14 previous errors diff --git a/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.rs b/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.rs index 39fa70c4e59ef..2b98a7b9483b2 100644 --- a/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.rs +++ b/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.rs @@ -2,18 +2,7 @@ // Deref and not DerefMut is implemented. use std::ops::Deref; - -struct Rc { - value: *const T -} - -impl Deref for Rc { - type Target = T; - - fn deref<'a>(&'a self) -> &'a T { - unsafe { &*self.value } - } -} +use std::rc::Rc; fn deref_imm(x: Rc) { let __isize = &*x; diff --git a/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.stderr b/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.stderr index 1755b22f59dc2..8cacc29414d75 100644 --- a/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.stderr +++ b/src/test/ui/borrowck/borrowck-borrow-overloaded-deref.stderr @@ -1,44 +1,58 @@ -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-deref.rs:23:19 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-deref.rs:12:19 | LL | let __isize = &mut *x; | ^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-deref.rs:27:19 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-deref.rs:16:19 | LL | let __isize = &mut *x; | ^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-deref.rs:35:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-deref.rs:24:5 | LL | &mut **x | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-borrow-overloaded-deref.rs:39:5 +error[E0596]: cannot borrow data in an `Rc` as mutable + --> $DIR/borrowck-borrow-overloaded-deref.rs:28:5 | LL | &mut **x | ^^^^^^^^ cannot borrow as mutable + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-deref.rs:43:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-deref.rs:32:5 | LL | *x = 3; | ^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-deref.rs:47:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-deref.rs:36:5 | LL | **x = 3; | ^^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` -error[E0594]: cannot assign to data in a `&` reference - --> $DIR/borrowck-borrow-overloaded-deref.rs:51:5 +error[E0594]: cannot assign to data in an `Rc` + --> $DIR/borrowck-borrow-overloaded-deref.rs:40:5 | LL | **x = 3; | ^^^^^^^ cannot assign + | + = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::rc::Rc` error: aborting due to 7 previous errors diff --git a/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.rs b/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.rs index cb20873432b7c..8adafaa8e938c 100644 --- a/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.rs +++ b/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.rs @@ -54,6 +54,6 @@ fn main() { x: 1, }; s[2] = 20; - //~^ ERROR cannot assign to data in a `&` reference + //~^ ERROR cannot assign to data in an index of `Bar` drop(rs); } diff --git a/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.stderr b/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.stderr index fcbfe72a34b96..84fe17d85448e 100644 --- a/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.stderr +++ b/src/test/ui/borrowck/borrowck-overloaded-index-ref-index.stderr @@ -21,11 +21,13 @@ LL | f[&s] = 10; LL | drop(rs); | -- mutable borrow later used here -error[E0594]: cannot assign to data in a `&` reference +error[E0594]: cannot assign to data in an index of `Bar` --> $DIR/borrowck-overloaded-index-ref-index.rs:56:5 | LL | s[2] = 20; | ^^^^^^^^^ cannot assign + | + = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `Bar` error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/index-mut-help-with-impl.stderr b/src/test/ui/borrowck/index-mut-help-with-impl.stderr index 4b29beb02b35e..89391f4099a21 100644 --- a/src/test/ui/borrowck/index-mut-help-with-impl.stderr +++ b/src/test/ui/borrowck/index-mut-help-with-impl.stderr @@ -3,8 +3,6 @@ error[E0596]: cannot borrow data in a `&` reference as mutable | LL | Index::index(&v, 1..2).make_ascii_uppercase(); | ^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable - | - = help: trait `IndexMut` is required to modify indexed content error: aborting due to previous error diff --git a/src/test/ui/borrowck/index-mut-help.stderr b/src/test/ui/borrowck/index-mut-help.stderr index fbc427a6e6d09..47f2171f88c86 100644 --- a/src/test/ui/borrowck/index-mut-help.stderr +++ b/src/test/ui/borrowck/index-mut-help.stderr @@ -1,4 +1,4 @@ -error[E0596]: cannot borrow data in a `&` reference as mutable +error[E0596]: cannot borrow data in an index of `std::collections::HashMap<&str, std::string::String>` as mutable --> $DIR/index-mut-help.rs:11:5 | LL | map["peter"].clear(); @@ -6,13 +6,15 @@ LL | map["peter"].clear(); | = 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 +error[E0594]: cannot assign to data in an index of `std::collections::HashMap<&str, std::string::String>` --> $DIR/index-mut-help.rs:12:5 | LL | map["peter"] = "0".to_string(); | ^^^^^^^^^^^^ cannot assign + | + = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<&str, std::string::String>` -error[E0596]: cannot borrow data in a `&` reference as mutable +error[E0596]: cannot borrow data in an index of `std::collections::HashMap<&str, std::string::String>` as mutable --> $DIR/index-mut-help.rs:13:13 | LL | let _ = &mut map["peter"]; diff --git a/src/test/ui/issues/issue-41726.rs b/src/test/ui/issues/issue-41726.rs index ed05629389005..39631912c00e7 100644 --- a/src/test/ui/issues/issue-41726.rs +++ b/src/test/ui/issues/issue-41726.rs @@ -2,6 +2,6 @@ use std::collections::HashMap; fn main() { let things: HashMap> = HashMap::new(); for src in things.keys() { - things[src.as_str()].sort(); //~ ERROR cannot borrow data in a `&` reference as mutable + things[src.as_str()].sort(); //~ ERROR cannot borrow data in an index of } } diff --git a/src/test/ui/issues/issue-41726.stderr b/src/test/ui/issues/issue-41726.stderr index c92753d6e3dbf..aa7f23511dd82 100644 --- a/src/test/ui/issues/issue-41726.stderr +++ b/src/test/ui/issues/issue-41726.stderr @@ -1,4 +1,4 @@ -error[E0596]: cannot borrow data in a `&` reference as mutable +error[E0596]: cannot borrow data in an index of `std::collections::HashMap>` as mutable --> $DIR/issue-41726.rs:5:9 | LL | things[src.as_str()].sort();