1
Fork 0

Avoid cloning Place in describe_place_for_conflicting_borrow

This commit is contained in:
Santiago Pastorino 2019-07-19 19:04:01 +02:00
parent 46f81fc53d
commit 75c0c8c6dc
5 changed files with 42 additions and 37 deletions

View file

@ -275,11 +275,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
"report_move_out_while_borrowed: location={:?} place={:?} span={:?} borrow={:?}", "report_move_out_while_borrowed: location={:?} place={:?} span={:?} borrow={:?}",
location, place, span, borrow location, place, span, borrow
); );
let value_msg = match self.describe_place(place) { let value_msg = match self.describe_place(place.as_place_ref()) {
Some(name) => format!("`{}`", name), Some(name) => format!("`{}`", name),
None => "value".to_owned(), None => "value".to_owned(),
}; };
let borrow_msg = match self.describe_place(&borrow.borrowed_place) { let borrow_msg = match self.describe_place(borrow.borrowed_place.as_place_ref()) {
Some(name) => format!("`{}`", name), Some(name) => format!("`{}`", name),
None => "value".to_owned(), None => "value".to_owned(),
}; };
@ -292,7 +292,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut err = self.cannot_move_when_borrowed( let mut err = self.cannot_move_when_borrowed(
span, span,
&self.describe_place(place).unwrap_or_else(|| "_".to_owned()), &self.describe_place(place.as_place_ref()).unwrap_or_else(|| "_".to_owned()),
); );
err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg)); err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg));
err.span_label(span, format!("move out of {} occurs here", value_msg)); err.span_label(span, format!("move out of {} occurs here", value_msg));
@ -331,15 +331,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut err = self.cannot_use_when_mutably_borrowed( let mut err = self.cannot_use_when_mutably_borrowed(
span, span,
&self.describe_place(place).unwrap_or_else(|| "_".to_owned()), &self.describe_place(place.as_place_ref()).unwrap_or_else(|| "_".to_owned()),
borrow_span, borrow_span,
&self.describe_place(&borrow.borrowed_place) &self.describe_place(borrow.borrowed_place.as_place_ref())
.unwrap_or_else(|| "_".to_owned()), .unwrap_or_else(|| "_".to_owned()),
); );
borrow_spans.var_span_label(&mut err, { borrow_spans.var_span_label(&mut err, {
let place = &borrow.borrowed_place; let place = &borrow.borrowed_place;
let desc_place = self.describe_place(place).unwrap_or_else(|| "_".to_owned()); let desc_place =
self.describe_place(place.as_place_ref()).unwrap_or_else(|| "_".to_owned());
format!("borrow occurs due to use of `{}`{}", desc_place, borrow_spans.describe()) format!("borrow occurs due to use of `{}`{}", desc_place, borrow_spans.describe())
}); });
@ -516,7 +517,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
); );
} else { } else {
let borrow_place = &issued_borrow.borrowed_place; let borrow_place = &issued_borrow.borrowed_place;
let borrow_place_desc = self.describe_place(borrow_place) let borrow_place_desc = self.describe_place(borrow_place.as_place_ref())
.unwrap_or_else(|| "_".to_owned()); .unwrap_or_else(|| "_".to_owned());
issued_spans.var_span_label( issued_spans.var_span_label(
&mut err, &mut err,
@ -615,9 +616,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
while let Some(box Projection { base: base_proj, elem }) = current { while let Some(box Projection { base: base_proj, elem }) = current {
match elem { match elem {
ProjectionElem::Field(field, _) if union_ty(base, base_proj).is_some() => { ProjectionElem::Field(field, _) if union_ty(base, base_proj).is_some() => {
return Some((Place { return Some((PlaceRef {
base: base.clone(), base: base,
projection: base_proj.clone(), projection: base_proj,
}, field)); }, field));
}, },
_ => current = base_proj, _ => current = base_proj,
@ -639,18 +640,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let ProjectionElem::Field(field, _) = elem { if let ProjectionElem::Field(field, _) = elem {
if let Some(union_ty) = union_ty(base, proj_base) { if let Some(union_ty) = union_ty(base, proj_base) {
if field != target_field if field != target_field
&& *base == target_base.base && base == target_base.base
&& *proj_base == target_base.projection { && proj_base == target_base.projection {
// FIXME when we avoid clone reuse describe_place closure // FIXME when we avoid clone reuse describe_place closure
let describe_base_place = self.describe_place(&Place { let describe_base_place = self.describe_place(PlaceRef {
base: base.clone(), base: base,
projection: proj_base.clone(), projection: proj_base,
}).unwrap_or_else(|| "_".to_owned()); }).unwrap_or_else(|| "_".to_owned());
return Some(( return Some((
describe_base_place, describe_base_place,
describe_place(first_borrowed_place), describe_place(first_borrowed_place.as_place_ref()),
describe_place(second_borrowed_place), describe_place(second_borrowed_place.as_place_ref()),
union_ty.to_string(), union_ty.to_string(),
)); ));
} }
@ -665,7 +666,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// If we didn't find a field access into a union, or both places match, then // If we didn't find a field access into a union, or both places match, then
// only return the description of the first place. // only return the description of the first place.
( (
describe_place(first_borrowed_place), describe_place(first_borrowed_place.as_place_ref()),
"".to_string(), "".to_string(),
"".to_string(), "".to_string(),
"".to_string(), "".to_string(),
@ -743,7 +744,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
} }
let place_desc = self.describe_place(&borrow.borrowed_place); let place_desc = self.describe_place(borrow.borrowed_place.as_place_ref());
let kind_place = kind.filter(|_| place_desc.is_some()).map(|k| (k, place_span.0)); let kind_place = kind.filter(|_| place_desc.is_some()).map(|k| (k, place_span.0));
let explanation = self.explain_why_borrow_contains_point(location, &borrow, kind_place); let explanation = self.explain_why_borrow_contains_point(location, &borrow, kind_place);
@ -950,12 +951,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut err = self.cannot_borrow_across_destructor(borrow_span); let mut err = self.cannot_borrow_across_destructor(borrow_span);
let what_was_dropped = match self.describe_place(place) { let what_was_dropped = match self.describe_place(place.as_place_ref()) {
Some(name) => format!("`{}`", name.as_str()), Some(name) => format!("`{}`", name.as_str()),
None => String::from("temporary value"), None => String::from("temporary value"),
}; };
let label = match self.describe_place(&borrow.borrowed_place) { let label = match self.describe_place(borrow.borrowed_place.as_place_ref()) {
Some(borrowed) => format!( Some(borrowed) => format!(
"here, drop of {D} needs exclusive access to `{B}`, \ "here, drop of {D} needs exclusive access to `{B}`, \
because the type `{T}` implements the `Drop` trait", because the type `{T}` implements the `Drop` trait",
@ -1389,7 +1390,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut err = self.cannot_mutate_in_match_guard( let mut err = self.cannot_mutate_in_match_guard(
span, span,
loan_span, loan_span,
&self.describe_place(place).unwrap_or_else(|| "_".to_owned()), &self.describe_place(place.as_place_ref()).unwrap_or_else(|| "_".to_owned()),
"assign", "assign",
); );
loan_spans.var_span_label( loan_spans.var_span_label(
@ -1405,7 +1406,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut err = self.cannot_assign_to_borrowed( let mut err = self.cannot_assign_to_borrowed(
span, span,
loan_span, loan_span,
&self.describe_place(place).unwrap_or_else(|| "_".to_owned()), &self.describe_place(place.as_place_ref()).unwrap_or_else(|| "_".to_owned()),
); );
loan_spans.var_span_label( loan_spans.var_span_label(
@ -1465,8 +1466,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
is_user_variable: None, is_user_variable: None,
.. ..
}) })
| None => (self.describe_place(place), assigned_span), | None => (self.describe_place(place.as_place_ref()), assigned_span),
Some(decl) => (self.describe_place(err_place), decl.source_info.span), Some(decl) => (self.describe_place(err_place.as_place_ref()), decl.source_info.span),
}; };
let mut err = self.cannot_reassign_immutable( let mut err = self.cannot_reassign_immutable(

View file

@ -121,8 +121,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// End-user visible description of `place` if one can be found. If the /// End-user visible description of `place` if one can be found. If the
/// place is a temporary for instance, None will be returned. /// place is a temporary for instance, None will be returned.
pub(super) fn describe_place(&self, place: &Place<'tcx>) -> Option<String> { pub(super) fn describe_place(&self, place_ref: PlaceRef<'cx, 'tcx>) -> Option<String> {
self.describe_place_with_options(place.as_place_ref(), IncludingDowncast(false)) self.describe_place_with_options(place_ref, IncludingDowncast(false))
} }
/// End-user visible description of `place` if one can be found. If the /// End-user visible description of `place` if one can be found. If the

View file

@ -277,7 +277,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
span: Span span: Span
) -> DiagnosticBuilder<'a> { ) -> DiagnosticBuilder<'a> {
let description = if place.projection.is_none() { let description = if place.projection.is_none() {
format!("static item `{}`", self.describe_place(place).unwrap()) format!("static item `{}`", self.describe_place(place.as_place_ref()).unwrap())
} else { } else {
let mut base_static = &place.projection; let mut base_static = &place.projection;
while let Some(box Projection { base: Some(ref proj), .. }) = base_static { while let Some(box Projection { base: Some(ref proj), .. }) = base_static {
@ -290,8 +290,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
format!( format!(
"`{:?}` as `{:?}` is a static item", "`{:?}` as `{:?}` is a static item",
self.describe_place(place).unwrap(), self.describe_place(place.as_place_ref()).unwrap(),
self.describe_place(&base_static).unwrap(), self.describe_place(base_static.as_place_ref()).unwrap(),
) )
}; };
@ -363,7 +363,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let upvar_name = upvar.name; let upvar_name = upvar.name;
let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id); let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id);
let place_name = self.describe_place(move_place).unwrap(); let place_name = self.describe_place(move_place.as_place_ref()).unwrap();
let place_description = if self let place_description = if self
.is_upvar_field_projection(move_place.as_place_ref()) .is_upvar_field_projection(move_place.as_place_ref())
@ -392,7 +392,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} }
_ => { _ => {
let source = self.borrowed_content_source(&deref_base); let source = self.borrowed_content_source(&deref_base);
match (self.describe_place(move_place), source.describe_for_named_place()) { match (
self.describe_place(move_place.as_place_ref()),
source.describe_for_named_place(),
) {
(Some(place_desc), Some(source_desc)) => { (Some(place_desc), Some(source_desc)) => {
self.cannot_move_out_of( self.cannot_move_out_of(
span, span,
@ -452,7 +455,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if binds_to.is_empty() { if binds_to.is_empty() {
let place_ty = move_from.ty(self.body, self.infcx.tcx).ty; let place_ty = move_from.ty(self.body, self.infcx.tcx).ty;
let place_desc = match self.describe_place(&move_from) { let place_desc = match self.describe_place(move_from.as_place_ref()) {
Some(desc) => format!("`{}`", desc), Some(desc) => format!("`{}`", desc),
None => format!("value"), None => format!("value"),
}; };
@ -480,7 +483,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
GroupedMoveError::OtherIllegalMove { ref original_path, use_spans, .. } => { GroupedMoveError::OtherIllegalMove { ref original_path, use_spans, .. } => {
let span = use_spans.var_or_use(); let span = use_spans.var_or_use();
let place_ty = original_path.ty(self.body, self.infcx.tcx).ty; let place_ty = original_path.ty(self.body, self.infcx.tcx).ty;
let place_desc = match self.describe_place(original_path) { let place_desc = match self.describe_place(original_path.as_place_ref()) {
Some(desc) => format!("`{}`", desc), Some(desc) => format!("`{}`", desc),
None => format!("value"), None => format!("value"),
}; };

View file

@ -40,7 +40,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let item_msg; let item_msg;
let reason; let reason;
let mut opt_source = None; let mut opt_source = None;
let access_place_desc = self.describe_place(access_place); let access_place_desc = self.describe_place(access_place.as_place_ref());
debug!("report_mutability_error: access_place_desc={:?}", access_place_desc); debug!("report_mutability_error: access_place_desc={:?}", access_place_desc);
match the_place_err { match the_place_err {
@ -236,7 +236,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
format!( format!(
"mutable borrow occurs due to use of `{}` in closure", "mutable borrow occurs due to use of `{}` in closure",
// always Some() if the message is printed. // always Some() if the message is printed.
self.describe_place(access_place).unwrap_or_default(), self.describe_place(access_place.as_place_ref()).unwrap_or_default(),
) )
); );
borrow_span borrow_span

View file

@ -304,7 +304,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
region, region,
); );
if let Some(region_name) = region_name { if let Some(region_name) = region_name {
let opt_place_desc = self.describe_place(&borrow.borrowed_place); let opt_place_desc =
self.describe_place(borrow.borrowed_place.as_place_ref());
BorrowExplanation::MustBeValidFor { BorrowExplanation::MustBeValidFor {
category, category,
from_closure, from_closure,