about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs14
-rw-r--r--tests/ui/pattern/deref-patterns/bindings.rs4
2 files changed, 14 insertions, 4 deletions
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<Place<'tcx>>,
+        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>) -> 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);