Skip to content

Commit 932b440

Browse files
committed
Be precise about usefulness vs reachability
1 parent 0a9fc53 commit 932b440

File tree

3 files changed

+159
-94
lines changed

3 files changed

+159
-94
lines changed

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::deconstruct_pat::{Constructor, DeconstructedPat, WitnessPat};
22
use super::usefulness::{
3-
compute_match_usefulness, MatchArm, MatchCheckCtxt, Reachability, UsefulnessReport,
3+
compute_match_usefulness, MatchArm, MatchCheckCtxt, Usefulness, UsefulnessReport,
44
};
55

66
use crate::errors::*;
@@ -749,18 +749,18 @@ fn report_arm_reachability<'p, 'tcx>(
749749
);
750750
};
751751

752-
use Reachability::*;
752+
use Usefulness::*;
753753
let mut catchall = None;
754754
for (arm, is_useful) in report.arm_usefulness.iter() {
755755
match is_useful {
756-
Unreachable => report_unreachable_pattern(arm.pat.span(), arm.hir_id, catchall),
757-
Reachable(unreachables) if unreachables.is_empty() => {}
758-
// The arm is reachable, but contains unreachable subpatterns (from or-patterns).
759-
Reachable(unreachables) => {
760-
let mut unreachables = unreachables.clone();
756+
Redundant => report_unreachable_pattern(arm.pat.span(), arm.hir_id, catchall),
757+
Useful(redundant_spans) if redundant_spans.is_empty() => {}
758+
// The arm is reachable, but contains redundant subpatterns (from or-patterns).
759+
Useful(redundant_spans) => {
760+
let mut redundant_spans = redundant_spans.clone();
761761
// Emit lints in the order in which they occur in the file.
762-
unreachables.sort_unstable();
763-
for span in unreachables {
762+
redundant_spans.sort_unstable();
763+
for span in redundant_spans {
764764
report_unreachable_pattern(span, arm.hir_id, None);
765765
}
766766
}

compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,8 @@ pub(crate) struct DeconstructedPat<'p, 'tcx> {
13461346
fields: Fields<'p, 'tcx>,
13471347
ty: Ty<'tcx>,
13481348
span: Span,
1349-
reachable: Cell<bool>,
1349+
/// Whether removing this arm would change the behavior of the match expression.
1350+
useful: Cell<bool>,
13501351
}
13511352

13521353
impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
@@ -1360,7 +1361,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
13601361
ty: Ty<'tcx>,
13611362
span: Span,
13621363
) -> Self {
1363-
DeconstructedPat { ctor, fields, ty, span, reachable: Cell::new(false) }
1364+
DeconstructedPat { ctor, fields, ty, span, useful: Cell::new(false) }
13641365
}
13651366

13661367
/// Note: the input patterns must have been lowered through
@@ -1635,38 +1636,38 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
16351636
}
16361637
}
16371638

1638-
/// We keep track for each pattern if it was ever reachable during the analysis. This is used
1639-
/// with `unreachable_spans` to report unreachable subpatterns arising from or patterns.
1640-
pub(super) fn set_reachable(&self) {
1641-
self.reachable.set(true)
1639+
/// We keep track for each pattern if it was ever useful during the analysis. This is used
1640+
/// with `redundant_spans` to report redundant subpatterns arising from or patterns.
1641+
pub(super) fn set_useful(&self) {
1642+
self.useful.set(true)
16421643
}
1643-
pub(super) fn is_reachable(&self) -> bool {
1644-
if self.reachable.get() {
1644+
pub(super) fn is_useful(&self) -> bool {
1645+
if self.useful.get() {
16451646
true
1646-
} else if self.is_or_pat() && self.iter_fields().any(|f| f.is_reachable()) {
1647+
} else if self.is_or_pat() && self.iter_fields().any(|f| f.is_useful()) {
16471648
// We always expand or patterns in the matrix, so we will never see the actual
16481649
// or-pattern (the one with constructor `Or`) in the column. As such, it will not be
1649-
// marked as reachable itself, only its children will. We recover this information here.
1650-
self.set_reachable();
1650+
// marked as useful itself, only its children will. We recover this information here.
1651+
self.set_useful();
16511652
true
16521653
} else {
16531654
false
16541655
}
16551656
}
16561657

1657-
/// Report the spans of subpatterns that were not reachable, if any.
1658-
pub(super) fn unreachable_spans(&self) -> Vec<Span> {
1658+
/// Report the spans of subpatterns that were not useful, if any.
1659+
pub(super) fn redundant_spans(&self) -> Vec<Span> {
16591660
let mut spans = Vec::new();
1660-
self.collect_unreachable_spans(&mut spans);
1661+
self.collect_redundant_spans(&mut spans);
16611662
spans
16621663
}
1663-
fn collect_unreachable_spans(&self, spans: &mut Vec<Span>) {
1664-
// We don't look at subpatterns if we already reported the whole pattern as unreachable.
1665-
if !self.is_reachable() {
1664+
fn collect_redundant_spans(&self, spans: &mut Vec<Span>) {
1665+
// We don't look at subpatterns if we already reported the whole pattern as redundant.
1666+
if !self.is_useful() {
16661667
spans.push(self.span);
16671668
} else {
16681669
for p in self.iter_fields() {
1669-
p.collect_unreachable_spans(spans);
1670+
p.collect_redundant_spans(spans);
16701671
}
16711672
}
16721673
}

0 commit comments

Comments
 (0)