Skip to content

Commit 9aafc0b

Browse files
committed
Be precise about usefulness vs reachability
1 parent 4e376cc commit 9aafc0b

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

+9-9
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

+19-18
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,8 @@ pub(crate) struct DeconstructedPat<'p, 'tcx> {
13391339
fields: Fields<'p, 'tcx>,
13401340
ty: Ty<'tcx>,
13411341
span: Span,
1342-
reachable: Cell<bool>,
1342+
/// Whether removing this arm would change the behavior of the match expression.
1343+
useful: Cell<bool>,
13431344
}
13441345

13451346
impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
@@ -1353,7 +1354,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
13531354
ty: Ty<'tcx>,
13541355
span: Span,
13551356
) -> Self {
1356-
DeconstructedPat { ctor, fields, ty, span, reachable: Cell::new(false) }
1357+
DeconstructedPat { ctor, fields, ty, span, useful: Cell::new(false) }
13571358
}
13581359

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

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

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

0 commit comments

Comments
 (0)