Skip to content

Commit 0da9d3e

Browse files
committed
Let WitnessMatrix decide which witnesses to keep
1 parent 76c6d5f commit 0da9d3e

File tree

1 file changed

+33
-30
lines changed

1 file changed

+33
-30
lines changed

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

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -692,23 +692,35 @@ impl<'p, 'tcx> WitnessMatrix<'p, 'tcx> {
692692
if self.is_empty() {
693693
return;
694694
}
695-
if !matches!(ctor, Constructor::Missing { .. }) {
696-
for witness in self.0.iter_mut() {
697-
witness.apply_constructor(pcx, ctor)
695+
if matches!(ctor, Constructor::Wildcard) {
696+
self.push_wild_ctor(pcx, Constructor::Wildcard);
697+
} else if matches!(ctor, Constructor::Missing { .. }) {
698+
if missing_ctors.iter().any(|c| c.is_non_exhaustive()) {
699+
// Here we don't want the user to try to list all variants, we want them to add a
700+
// wildcard, so we only suggest that.
701+
self.push_wild_ctor(pcx, Constructor::NonExhaustive);
702+
} else {
703+
// We got the special `Missing` constructor, so each of the missing constructors gives a
704+
// new pattern that is not caught by the match. We list those patterns and push them
705+
// onto our current witnesses.
706+
let old_witnesses = std::mem::replace(self, Self::new_empty());
707+
for missing_ctor in missing_ctors {
708+
let mut witnesses_with_missing_ctor = old_witnesses.clone();
709+
witnesses_with_missing_ctor.push_wild_ctor(pcx, missing_ctor.clone());
710+
self.extend(witnesses_with_missing_ctor)
711+
}
698712
}
699-
} else if missing_ctors.iter().any(|c| c.is_non_exhaustive()) {
700-
// Here we don't want the user to try to list all variants, we want them to add a
701-
// wildcard, so we only suggest that.
702-
self.push_wild_ctor(pcx, Constructor::NonExhaustive);
703713
} else {
704-
// We got the special `Missing` constructor, so each of the missing constructors gives a
705-
// new pattern that is not caught by the match. We list those patterns and push them
706-
// onto our current witnesses.
707-
let old_witnesses = std::mem::replace(self, Self::new_empty());
708-
for missing_ctor in missing_ctors {
709-
let mut witnesses_with_missing_ctor = old_witnesses.clone();
710-
witnesses_with_missing_ctor.push_wild_ctor(pcx, missing_ctor.clone());
711-
self.extend(witnesses_with_missing_ctor)
714+
// If some ctors are missing we want to only report them (so we discard non-missing
715+
// ones). This is guaranteed to report *some* witnesses because
716+
// `!missing_ctors.is_empty()` implies there is a `Missing` or `Wildcard` in
717+
// `split_ctors`.
718+
if !missing_ctors.is_empty() {
719+
*self = Self::new_empty();
720+
} else {
721+
for witness in self.0.iter_mut() {
722+
witness.apply_constructor(pcx, ctor)
723+
}
712724
}
713725
}
714726
}
@@ -745,7 +757,6 @@ impl<'p, 'tcx> WitnessMatrix<'p, 'tcx> {
745757
fn compute_usefulness<'p, 'tcx>(
746758
cx: &MatchCheckCtxt<'p, 'tcx>,
747759
matrix: &mut Matrix<'p, 'tcx>,
748-
collect_witnesses: bool,
749760
lint_root: HirId,
750761
is_top_level: bool,
751762
) -> WitnessMatrix<'p, 'tcx> {
@@ -762,7 +773,7 @@ fn compute_usefulness<'p, 'tcx>(
762773
break;
763774
}
764775
}
765-
if useful && collect_witnesses {
776+
if useful {
766777
return WitnessMatrix::new_unit();
767778
} else {
768779
return WitnessMatrix::new_empty();
@@ -782,20 +793,12 @@ fn compute_usefulness<'p, 'tcx>(
782793
let mut ret = WitnessMatrix::new_empty();
783794
let orig_column_count = matrix.column_count();
784795
for ctor in split_ctors {
785-
// If some ctors are missing we only report those. Could report all if that's useful for
786-
// some applications.
787-
let collect_witnesses = collect_witnesses
788-
&& (missing_ctors.is_empty()
789-
|| matches!(ctor, Constructor::Wildcard | Constructor::Missing));
790796
debug!("specialize({:?})", ctor);
791797
let mut spec_matrix = matrix.specialize_constructor(pcx, &ctor);
792-
let mut witnesses = ensure_sufficient_stack(|| {
793-
compute_usefulness(cx, &mut spec_matrix, collect_witnesses, lint_root, false)
794-
});
795-
if collect_witnesses {
796-
witnesses.apply_constructor(pcx, &missing_ctors, &ctor);
797-
ret.extend(witnesses);
798-
}
798+
let mut witnesses =
799+
ensure_sufficient_stack(|| compute_usefulness(cx, &mut spec_matrix, lint_root, false));
800+
witnesses.apply_constructor(pcx, &missing_ctors, &ctor);
801+
ret.extend(witnesses);
799802

800803
// Lint on likely incorrect range patterns (#63987)
801804
if spec_matrix.rows().len() >= 2 {
@@ -920,7 +923,7 @@ pub(crate) fn compute_match_usefulness<'p, 'tcx>(
920923
matrix.push(v);
921924
}
922925

923-
let non_exhaustiveness_witnesses = compute_usefulness(cx, &mut matrix, true, lint_root, true);
926+
let non_exhaustiveness_witnesses = compute_usefulness(cx, &mut matrix, lint_root, true);
924927
let non_exhaustiveness_witnesses: Vec<_> = non_exhaustiveness_witnesses.single_column();
925928
let arm_usefulness: Vec<_> = arms
926929
.iter()

0 commit comments

Comments
 (0)