diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 075ef83e456d..77e86fdce38d 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -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. diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 08b262df2f6e..0ab5a792e040 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -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()) diff --git a/tests/ui/reachable/guard_read_for_never.rs b/tests/ui/reachable/guard_read_for_never.rs new file mode 100644 index 000000000000..7061da635301 --- /dev/null +++ b/tests/ui/reachable/guard_read_for_never.rs @@ -0,0 +1,16 @@ +// Regression test for +// +//@ 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; + (); + } +}