Skip to content

Commit a0aba33

Browse files
committed
Let WitnessMatrix decide which constructors to report
1 parent 62c1a64 commit a0aba33

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,11 +1072,10 @@ impl ConstructorSet {
10721072
ConstructorSet::Uninhabited => {}
10731073
}
10741074
if !missing.is_empty() {
1075-
let report_when_all_missing = is_top_level && !matches!(self, Self::Integers { .. });
1076-
if !split.is_empty() || report_when_all_missing {
1077-
split.push(Missing);
1078-
} else {
1075+
if split.is_empty() {
10791076
split.push(Wildcard);
1077+
} else {
1078+
split.push(Missing);
10801079
}
10811080
}
10821081
(split, missing)

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -688,13 +688,14 @@ impl<'p, 'tcx> WitnessMatrix<'p, 'tcx> {
688688
pcx: &PatCtxt<'_, 'p, 'tcx>,
689689
missing_ctors: &[Constructor<'tcx>],
690690
ctor: &Constructor<'tcx>,
691+
report_when_all_missing: bool,
691692
) {
692693
if self.is_empty() {
693694
return;
694695
}
695-
if matches!(ctor, Constructor::Wildcard) {
696+
if matches!(ctor, Constructor::Wildcard) && !report_when_all_missing {
696697
self.push_wild_ctor(pcx, Constructor::Wildcard);
697-
} else if matches!(ctor, Constructor::Missing { .. }) {
698+
} else if matches!(ctor, Constructor::Wildcard | Constructor::Missing) {
698699
if missing_ctors.iter().any(|c| c.is_non_exhaustive()) {
699700
// Here we don't want the user to try to list all variants, we want them to add a
700701
// wildcard, so we only suggest that.
@@ -787,6 +788,9 @@ fn compute_usefulness<'p, 'tcx>(
787788
let ctor_set = ConstructorSet::new(pcx);
788789
let (split_ctors, missing_ctors) =
789790
ctor_set.split(pcx, matrix.heads().map(|p| p.ctor()), is_top_level);
791+
// At the top level, we prefer to list all constructors when `_` could be reported as missing.
792+
let report_when_all_missing =
793+
is_top_level && !matches!(ctor_set, ConstructorSet::Integers { .. });
790794

791795
// For each constructor, we compute whether there's a value that starts with it that would
792796
// witness the usefulness of `v`.
@@ -797,7 +801,7 @@ fn compute_usefulness<'p, 'tcx>(
797801
let mut spec_matrix = matrix.specialize_constructor(pcx, &ctor);
798802
let mut witnesses =
799803
ensure_sufficient_stack(|| compute_usefulness(cx, &mut spec_matrix, lint_root, false));
800-
witnesses.apply_constructor(pcx, &missing_ctors, &ctor);
804+
witnesses.apply_constructor(pcx, &missing_ctors, &ctor, report_when_all_missing);
801805
ret.extend(witnesses);
802806

803807
// Lint on likely incorrect range patterns (#63987)
@@ -827,7 +831,8 @@ fn compute_usefulness<'p, 'tcx>(
827831
// When all the conditions are met we have a match with a `non_exhaustive` enum
828832
// that has the potential to trigger the `non_exhaustive_omitted_patterns` lint.
829833
if cx.refutable
830-
&& matches!(&ctor, Constructor::Missing)
834+
&& (matches!(&ctor, Constructor::Missing)
835+
|| (matches!(&ctor, Constructor::Wildcard) && is_top_level))
831836
&& matches!(&ctor_set, ConstructorSet::Variants { non_exhaustive: true, .. })
832837
&& spec_matrix.rows().len() != 0
833838
{

0 commit comments

Comments
 (0)