Fix liveness analysis in the presence of never patterns
This commit is contained in:
parent
7168c13579
commit
5e0e5b1efb
@ -71,14 +71,21 @@ impl hir::Pat<'_> {
|
|||||||
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
|
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
|
||||||
/// `match foo() { Some(a) => (), None => () }`.
|
/// `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(
|
pub fn each_binding_or_first(
|
||||||
&self,
|
&self,
|
||||||
f: &mut impl FnMut(hir::BindingAnnotation, HirId, Span, Ident),
|
f: &mut impl FnMut(hir::BindingAnnotation, HirId, Span, Ident),
|
||||||
) {
|
) {
|
||||||
self.walk(|p| match &p.kind {
|
self.walk(|p| match &p.kind {
|
||||||
PatKind::Or(ps) => {
|
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
|
false
|
||||||
}
|
}
|
||||||
PatKind::Binding(bm, _, ident, _) => {
|
PatKind::Binding(bm, _, ident, _) => {
|
||||||
|
@ -526,8 +526,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn define_bindings_in_pat(&mut self, pat: &hir::Pat<'_>, mut succ: LiveNode) -> LiveNode {
|
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
|
// In an or-pattern, only consider the first non-never pattern; any later patterns
|
||||||
// must have the same bindings, and we also consider the first pattern
|
// must have the same bindings, and we also consider that pattern
|
||||||
// to be the "authoritative" set of ids.
|
// to be the "authoritative" set of ids.
|
||||||
pat.each_binding_or_first(&mut |_, hir_id, pat_sp, ident| {
|
pat.each_binding_or_first(&mut |_, hir_id, pat_sp, ident| {
|
||||||
let ln = self.live_node(hir_id, pat_sp);
|
let ln = self.live_node(hir_id, pat_sp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user