about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2025-03-14 01:37:35 -0400
committerGitHub <noreply@github.com>2025-03-14 01:37:35 -0400
commitf5055722b65682815d5f18dd7e08a0e9ee7218aa (patch)
tree3e283cf7ff6d1357021724936f11857ac7dadd86
parent7de35c8bb85170e885c34e2fdb45f95d4125e8f2 (diff)
parent36ff87e90e7f39cffb508292a63792cc0dcfbd6e (diff)
downloadrust-f5055722b65682815d5f18dd7e08a0e9ee7218aa.tar.gz
rust-f5055722b65682815d5f18dd7e08a0e9ee7218aa.zip
Rollup merge of #138442 - dianne:deref-pat-euv-fix, r=compiler-errors
EUV: fix place of deref pattern's interior's scrutinee

The place previously used here was that of the temporary holding the reference returned by `Deref::deref` or `DerefMut::deref_mut`. However, since the inner pattern of `deref!(inner)` expects the deref-target type itself, this would ICE when that type was inspected (e.g. by the EUV case for slice patterns). This adds a deref projection to fix that.

Since current in-tree consumers of EUV (upvar inference and clippy) don't care about Rvalues, the place could be simplified to `self.cat_rvalue(pat.hir_id, self.pat_ty_adjusted(subpat)?)` to save some cycles. I personally find EUV to be a bit fragile, so I've opted for pedantic correctness. Maybe a `HACK` comment would suffice though?

Fixes #125059

r? `@compiler-errors`
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs3
-rw-r--r--tests/crashes/125059.rs12
-rw-r--r--tests/ui/pattern/deref-patterns/dont-ice-on-slice-in-deref-pat-in-closure.rs15
3 files changed, 17 insertions, 13 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index 63e4a8fb44b..35e687f2b0f 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -1840,7 +1840,8 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                 let ty = self.pat_ty_adjusted(subpat)?;
                 let ty = Ty::new_ref(self.cx.tcx(), re_erased, ty, mutability);
                 // A deref pattern generates a temporary.
-                let place = self.cat_rvalue(pat.hir_id, ty);
+                let base = self.cat_rvalue(pat.hir_id, ty);
+                let place = self.cat_deref(pat.hir_id, base)?;
                 self.cat_pattern(place, subpat, op)?;
             }
 
diff --git a/tests/crashes/125059.rs b/tests/crashes/125059.rs
deleted file mode 100644
index 7e9f7414816..00000000000
--- a/tests/crashes/125059.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: rust-lang/rust#125059
-#![feature(deref_patterns)]
-#![allow(incomplete_features)]
-
-fn simple_vec(vec: Vec<u32>) -> u32 {
-   (|| match Vec::<u32>::new() {
-        deref!([]) => 100,
-        _ => 2000,
-    })()
-}
-
-fn main() {}
diff --git a/tests/ui/pattern/deref-patterns/dont-ice-on-slice-in-deref-pat-in-closure.rs b/tests/ui/pattern/deref-patterns/dont-ice-on-slice-in-deref-pat-in-closure.rs
new file mode 100644
index 00000000000..e1a37b9c65f
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/dont-ice-on-slice-in-deref-pat-in-closure.rs
@@ -0,0 +1,15 @@
+//@ check-pass
+//! Regression test for ICE in `rustc_hir_typeck::expr_use_visitor` on nesting a slice pattern
+//! inside a deref pattern inside a closure: rust-lang/rust#125059
+
+#![feature(deref_patterns)]
+#![allow(incomplete_features, unused)]
+
+fn simple_vec(vec: Vec<u32>) -> u32 {
+   (|| match Vec::<u32>::new() {
+        deref!([]) => 100,
+        _ => 2000,
+    })()
+}
+
+fn main() {}