diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index f16dddeaa68..6094c8e759c 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -5,7 +5,7 @@ //! This also includes code for pattern bindings in `let` statements and //! function parameters. -use crate::build::expr::as_place::PlaceBuilder; +use crate::build::expr::as_place::{PlaceBase, PlaceBuilder}; use crate::build::scope::DropKind; use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; @@ -438,7 +438,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } if let Some(ref borrows) = fake_borrows { - self.calculate_fake_borrows(borrows, scrutinee_span) + self.calculate_fake_borrows(borrows, scrutinee_place_builder.base(), scrutinee_span) } else { Vec::new() } @@ -1936,6 +1936,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn calculate_fake_borrows<'b>( &mut self, fake_borrows: &'b FxIndexSet>, + scrutinee_base: PlaceBase, temp_span: Span, ) -> Vec<(Place<'tcx>, Local)> { let tcx = self.tcx; @@ -1946,6 +1947,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Insert a Shallow borrow of the prefixes of any fake borrows. for place in fake_borrows { + if let PlaceBase::Local(l) = scrutinee_base + && l != place.local + { + // The base of this place is a temporary created for deref patterns. We don't emit + // fake borrows for these as they are not initialized in all branches. + // FIXME(deref_patterns): is this sound? + continue; + } + let mut cursor = place.projection.as_ref(); while let [proj_base @ .., elem] = cursor { cursor = proj_base; diff --git a/tests/ui/pattern/deref-patterns/bindings.rs b/tests/ui/pattern/deref-patterns/bindings.rs index 75d59c1967a..c0c8a70dbf0 100644 --- a/tests/ui/pattern/deref-patterns/bindings.rs +++ b/tests/ui/pattern/deref-patterns/bindings.rs @@ -5,8 +5,7 @@ fn simple_vec(vec: Vec) -> u32 { match vec { deref!([]) => 100, - // FIXME(deref_patterns): fake borrows break guards - // deref!([x]) if x == 4 => x + 4, + deref!([x]) if x == 4 => x + 4, deref!([x]) => x, deref!([1, x]) => x + 200, deref!(ref slice) => slice.iter().sum(), @@ -29,6 +28,7 @@ fn main() { assert_eq!(simple_vec(vec![1]), 1); assert_eq!(simple_vec(vec![1, 2]), 202); assert_eq!(simple_vec(vec![1, 2, 3]), 6); + assert_eq!(simple_vec(vec![4]), 8); assert_eq!(nested_vec(vec![vec![0, 42]]), 42); assert_eq!(nested_vec(vec![vec![1, 42]]), 42);