Skip to content

Commit 1dabacd

Browse files
committed
Don't fake borrow inside a deref pattern
1 parent c623319 commit 1dabacd

File tree

2 files changed

+14
-4
lines changed
  • compiler/rustc_mir_build/src/build/matches
  • tests/ui/pattern/deref-patterns

2 files changed

+14
-4
lines changed

compiler/rustc_mir_build/src/build/matches/mod.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! This also includes code for pattern bindings in `let` statements and
66
//! function parameters.
77
8-
use crate::build::expr::as_place::PlaceBuilder;
8+
use crate::build::expr::as_place::{PlaceBase, PlaceBuilder};
99
use crate::build::scope::DropKind;
1010
use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard};
1111
use crate::build::{BlockAnd, BlockAndExtension, Builder};
@@ -438,7 +438,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
438438
}
439439

440440
if let Some(ref borrows) = fake_borrows {
441-
self.calculate_fake_borrows(borrows, scrutinee_span)
441+
self.calculate_fake_borrows(borrows, scrutinee_place_builder.base(), scrutinee_span)
442442
} else {
443443
Vec::new()
444444
}
@@ -1936,6 +1936,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19361936
fn calculate_fake_borrows<'b>(
19371937
&mut self,
19381938
fake_borrows: &'b FxIndexSet<Place<'tcx>>,
1939+
scrutinee_base: PlaceBase,
19391940
temp_span: Span,
19401941
) -> Vec<(Place<'tcx>, Local)> {
19411942
let tcx = self.tcx;
@@ -1946,6 +1947,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19461947

19471948
// Insert a Shallow borrow of the prefixes of any fake borrows.
19481949
for place in fake_borrows {
1950+
if let PlaceBase::Local(l) = scrutinee_base
1951+
&& l != place.local
1952+
{
1953+
// The base of this place is a temporary created for deref patterns. We don't emit
1954+
// fake borrows for these as they are not initialized in all branches.
1955+
// FIXME(deref_patterns): is this sound?
1956+
continue;
1957+
}
1958+
19491959
let mut cursor = place.projection.as_ref();
19501960
while let [proj_base @ .., elem] = cursor {
19511961
cursor = proj_base;

tests/ui/pattern/deref-patterns/bindings.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
fn simple_vec(vec: Vec<u32>) -> u32 {
66
match vec {
77
deref!([]) => 100,
8-
// FIXME(deref_patterns): fake borrows break guards
9-
// deref!([x]) if x == 4 => x + 4,
8+
deref!([x]) if x == 4 => x + 4,
109
deref!([x]) => x,
1110
deref!([1, x]) => x + 200,
1211
deref!(ref slice) => slice.iter().sum(),
@@ -29,6 +28,7 @@ fn main() {
2928
assert_eq!(simple_vec(vec![1]), 1);
3029
assert_eq!(simple_vec(vec![1, 2]), 202);
3130
assert_eq!(simple_vec(vec![1, 2, 3]), 6);
31+
assert_eq!(simple_vec(vec![4]), 8);
3232

3333
assert_eq!(nested_vec(vec![vec![0, 42]]), 42);
3434
assert_eq!(nested_vec(vec![vec![1, 42]]), 42);

0 commit comments

Comments
 (0)