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?
This commit is contained in:
dianne 2025-03-12 23:08:37 -07:00
parent 0e76f8b7e0
commit 36ff87e90e
3 changed files with 17 additions and 13 deletions

View file

@ -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)?;
}

View file

@ -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() {}

View file

@ -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() {}