Skip to content

Commit 87ad668

Browse files
committed
Distinguish borrows of copies from other borrows
1 parent ac804f2 commit 87ad668

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,31 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
114114
.borrowed
115115
.insert(TrackedValue::from_place_with_projections_allowed(place_with_id));
116116

117-
// XXX -- we need to distinguish "consuming a copy" from other borrows
117+
// Keep track of whether this is a borrowed temporary (i.e. a borrow of an RValue)
118+
// so that later in generator_interior we can use the correct scope.
118119
//
119-
// XXX -- we need to distinguish `&*E` where `E: &T` which is not creating a temporary
120-
// even though the place-base E is an rvalue
120+
// We ignore borrows that are the result of an autoref because these will be
121+
// immediately consumed and should not extend the temporary's lifetime.
121122
if let (false, PlaceBase::Rvalue) = (is_autoref, place_with_id.place.base) {
122123
self.places.borrowed_temporaries.insert(place_with_id.hir_id);
123124
}
124125
}
125126

127+
fn copy(
128+
&mut self,
129+
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
130+
_diag_expr_id: HirId,
131+
) {
132+
debug!("copy: place_with_id = {place_with_id:?}");
133+
134+
self.places
135+
.borrowed
136+
.insert(TrackedValue::from_place_with_projections_allowed(place_with_id));
137+
138+
// For copied we treat this mostly like a borrow except that we don't add the place
139+
// to borrowed_temporaries because the copy is consumed.
140+
}
141+
126142
fn mutate(
127143
&mut self,
128144
assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>,

compiler/rustc_typeck/src/expr_use_visitor.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ pub trait Delegate<'tcx> {
4848
is_autoref: bool,
4949
);
5050

51+
/// The value found at `place` is being copied.
52+
/// `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
53+
fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) {
54+
// In most cases, treating a copy as a borrow is the right thing, so we forward
55+
// this to the borrow callback by default.
56+
self.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow, false)
57+
}
58+
5159
/// The path at `assignee_place` is being assigned to.
5260
/// `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
5361
fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId);
@@ -598,7 +606,12 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
598606
adjustment::AutoBorrow::RawPtr(m) => {
599607
debug!("walk_autoref: expr.hir_id={} base_place={:?}", expr.hir_id, base_place);
600608

601-
self.delegate.borrow(base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m), true);
609+
self.delegate.borrow(
610+
base_place,
611+
base_place.hir_id,
612+
ty::BorrowKind::from_mutbl(m),
613+
true,
614+
);
602615
}
603616
}
604617
}
@@ -839,9 +852,7 @@ fn delegate_consume<'a, 'tcx>(
839852

840853
match mode {
841854
ConsumeMode::Move => delegate.consume(place_with_id, diag_expr_id),
842-
ConsumeMode::Copy => {
843-
delegate.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow, false)
844-
}
855+
ConsumeMode::Copy => delegate.copy(place_with_id, diag_expr_id),
845856
}
846857
}
847858

0 commit comments

Comments
 (0)