fix guard patterns interaction with never type

This commit is contained in:
Waffle Lapkin 2025-12-03 15:04:32 +01:00
parent bf0970f0fa
commit e4f02e40b6
No known key found for this signature in database
3 changed files with 21 additions and 3 deletions

View file

@ -1807,8 +1807,9 @@ impl<'hir> Pat<'hir> {
// Does not constitute a read.
PatKind::Wild => false,
// Might not constitute a read, since the condition might be false.
PatKind::Guard(_, _) => true,
// The guard cannot affect if we make a read or not (it runs after the inner pattern
// has matched), therefore it's irrelevant.
PatKind::Guard(pat, _) => pat.is_guaranteed_to_constitute_read_for_never(),
// This is unnecessarily restrictive when the pattern that doesn't
// constitute a read is unreachable.

View file

@ -259,7 +259,8 @@ impl<'tcx> TyCtxt<'tcx> {
expr.hir_id != lhs.hir_id
}
// See note on `PatKind::Or` below for why this is `all`.
// See note on `PatKind::Or` in `Pat::is_guaranteed_to_constitute_read_for_never`
// for why this is `all`.
ExprKind::Match(scrutinee, arms, _) => {
assert_eq!(scrutinee.hir_id, expr.hir_id);
arms.iter().all(|arm| arm.pat.is_guaranteed_to_constitute_read_for_never())

View file

@ -0,0 +1,16 @@
// Regression test for <https://github.com/rust-lang/rust/pull/149545#discussion_r2585205872>
//
//@ check-pass
#![feature(guard_patterns, never_type)]
#![expect(incomplete_features, unused_parens)]
#![deny(unreachable_code)]
fn main() {
unsafe {
let x = std::ptr::null::<!>();
// This should not constitute a read for never, therefore no code here is unreachable
let (_ if false): ! = *x;
();
}
}