Skip to content

Commit d454b6f

Browse files
authored
Unrolled build for rust-lang#121391
Rollup merge of rust-lang#121391 - Nadrieril:fix-liveness, r=compiler-errors never patterns: Fix liveness analysis in the presence of never patterns There's a bunch of code that only looks at the first alternative of an or-pattern, under the assumption that all alternatives have the same set of bindings. This is true except for never pattern alternatives (e.g. `Ok(x) | Err(!)`), so we skip these. I expect there's other code with this problem, I'll have to check that later. I don't have tests for this yet because mir lowering causes other issues; I'll have some in the next PR. r? ``@compiler-errors``
2 parents 3406ada + 5e0e5b1 commit d454b6f

File tree

2 files changed

+11
-4
lines changed

2 files changed

+11
-4
lines changed

compiler/rustc_hir/src/pat_util.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,21 @@ impl hir::Pat<'_> {
7171
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
7272
/// `match foo() { Some(a) => (), None => () }`.
7373
///
74-
/// When encountering an or-pattern `p_0 | ... | p_n` only `p_0` will be visited.
74+
/// When encountering an or-pattern `p_0 | ... | p_n` only the first non-never pattern will be
75+
/// visited. If they're all never patterns we visit nothing, which is ok since a never pattern
76+
/// cannot have bindings.
7577
pub fn each_binding_or_first(
7678
&self,
7779
f: &mut impl FnMut(hir::BindingAnnotation, HirId, Span, Ident),
7880
) {
7981
self.walk(|p| match &p.kind {
8082
PatKind::Or(ps) => {
81-
ps[0].each_binding_or_first(f);
83+
for p in *ps {
84+
if !p.is_never_pattern() {
85+
p.each_binding_or_first(f);
86+
break;
87+
}
88+
}
8289
false
8390
}
8491
PatKind::Binding(bm, _, ident, _) => {

compiler/rustc_passes/src/liveness.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -526,8 +526,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
526526
}
527527

528528
fn define_bindings_in_pat(&mut self, pat: &hir::Pat<'_>, mut succ: LiveNode) -> LiveNode {
529-
// In an or-pattern, only consider the first pattern; any later patterns
530-
// must have the same bindings, and we also consider the first pattern
529+
// In an or-pattern, only consider the first non-never pattern; any later patterns
530+
// must have the same bindings, and we also consider that pattern
531531
// to be the "authoritative" set of ids.
532532
pat.each_binding_or_first(&mut |_, hir_id, pat_sp, ident| {
533533
let ln = self.live_node(hir_id, pat_sp);

0 commit comments

Comments
 (0)