about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2024-02-20 02:55:40 +0100
committerNadrieril <nadrieril+git@gmail.com>2024-02-21 12:04:39 +0100
commit5e0e5b1efb8a5776231b07c71e7c03ef016654b5 (patch)
tree5b01c28c23a27b7531dc3d9c366c488d863b3558 /compiler
parent7168c13579a550f2c47f7eea22f5e226a436cd00 (diff)
downloadrust-5e0e5b1efb8a5776231b07c71e7c03ef016654b5.tar.gz
rust-5e0e5b1efb8a5776231b07c71e7c03ef016654b5.zip
Fix liveness analysis in the presence of never patterns
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir/src/pat_util.rs11
-rw-r--r--compiler/rustc_passes/src/liveness.rs4
2 files changed, 11 insertions, 4 deletions
diff --git a/compiler/rustc_hir/src/pat_util.rs b/compiler/rustc_hir/src/pat_util.rs
index e6050327186..1eaab3d2aca 100644
--- a/compiler/rustc_hir/src/pat_util.rs
+++ b/compiler/rustc_hir/src/pat_util.rs
@@ -71,14 +71,21 @@ impl hir::Pat<'_> {
     /// Call `f` on every "binding" in a pattern, e.g., on `a` in
     /// `match foo() { Some(a) => (), None => () }`.
     ///
-    /// When encountering an or-pattern `p_0 | ... | p_n` only `p_0` will be visited.
+    /// When encountering an or-pattern `p_0 | ... | p_n` only the first non-never pattern will be
+    /// visited. If they're all never patterns we visit nothing, which is ok since a never pattern
+    /// cannot have bindings.
     pub fn each_binding_or_first(
         &self,
         f: &mut impl FnMut(hir::BindingAnnotation, HirId, Span, Ident),
     ) {
         self.walk(|p| match &p.kind {
             PatKind::Or(ps) => {
-                ps[0].each_binding_or_first(f);
+                for p in *ps {
+                    if !p.is_never_pattern() {
+                        p.each_binding_or_first(f);
+                        break;
+                    }
+                }
                 false
             }
             PatKind::Binding(bm, _, ident, _) => {
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 3a8dc377520..487407014d1 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -526,8 +526,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     }
 
     fn define_bindings_in_pat(&mut self, pat: &hir::Pat<'_>, mut succ: LiveNode) -> LiveNode {
-        // In an or-pattern, only consider the first pattern; any later patterns
-        // must have the same bindings, and we also consider the first pattern
+        // In an or-pattern, only consider the first non-never pattern; any later patterns
+        // must have the same bindings, and we also consider that pattern
         // to be the "authoritative" set of ids.
         pat.each_binding_or_first(&mut |_, hir_id, pat_sp, ident| {
             let ln = self.live_node(hir_id, pat_sp);