summary refs log tree commit diff
path: root/compiler/rustc_pattern_analysis/src
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2024-02-06 01:21:29 +0100
committerNadrieril <nadrieril+git@gmail.com>2024-02-08 15:34:17 +0100
commit3602b9d8174ac697b0f28721076e0c1e7513a410 (patch)
treeef99df6f6cf15f71370a47c5b69787855b9717d7 /compiler/rustc_pattern_analysis/src
parent924d6cd1a625a1200bd587f9ecb734aec0d72ae2 (diff)
downloadrust-3602b9d8174ac697b0f28721076e0c1e7513a410.tar.gz
rust-3602b9d8174ac697b0f28721076e0c1e7513a410.zip
Decide which constructors to report earlier.
This gets rid of `report_individual_missing_ctors`
Diffstat (limited to 'compiler/rustc_pattern_analysis/src')
-rw-r--r--compiler/rustc_pattern_analysis/src/usefulness.rs36
1 files changed, 17 insertions, 19 deletions
diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index bab53c04248..9b15f447c89 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -1319,28 +1319,16 @@ impl<Cx: TypeCx> WitnessMatrix<Cx> {
     fn apply_constructor(
         &mut self,
         pcx: &PlaceCtxt<'_, Cx>,
-        mut missing_ctors: &[Constructor<Cx>],
+        missing_ctors: &[Constructor<Cx>],
         ctor: &Constructor<Cx>,
-        report_individual_missing_ctors: bool,
     ) {
         if self.is_empty() {
             return;
         }
         if matches!(ctor, Constructor::Missing) {
             // We got the special `Missing` constructor that stands for the constructors not present
-            // in the match.
-            if !missing_ctors.is_empty() && !report_individual_missing_ctors {
-                // Report `_` as missing.
-                missing_ctors = &[Constructor::Wildcard];
-            } else if missing_ctors.iter().any(|c| c.is_non_exhaustive()) {
-                // We need to report a `_` anyway, so listing other constructors would be redundant.
-                // `NonExhaustive` is displayed as `_` just like `Wildcard`, but it will be picked
-                // up by diagnostics to add a note about why `_` is required here.
-                missing_ctors = &[Constructor::NonExhaustive];
-            }
-
-            // For each missing constructor `c`, we add a `c(_, _, _)` witness appropriately
-            // filled with wildcards.
+            // in the match. For each missing constructor `c`, we add a `c(_, _, _)` witness
+            // appropriately filled with wildcards.
             let mut ret = Self::empty();
             for ctor in missing_ctors {
                 let pat = pcx.wild_from_ctor(ctor.clone());
@@ -1515,9 +1503,6 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
         split_ctors.push(Constructor::Missing);
     }
 
-    // Whether we should report "Enum::A and Enum::C are missing" or "_ is missing". At the top
-    // level we prefer to list all constructors.
-    let report_individual_missing_ctors = place.is_scrutinee || !all_missing;
     // Which constructors are considered missing. We ensure that `!missing_ctors.is_empty() =>
     // split_ctors.contains(Missing)`. The converse usually holds except when
     // `!place_validity.is_known_valid()`.
@@ -1526,6 +1511,19 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
         missing_ctors.append(&mut split_set.missing_empty);
     }
 
+    // Whether we should report "Enum::A and Enum::C are missing" or "_ is missing". At the top
+    // level we prefer to list all constructors.
+    let report_individual_missing_ctors = place.is_scrutinee || !all_missing;
+    if !missing_ctors.is_empty() && !report_individual_missing_ctors {
+        // Report `_` as missing.
+        missing_ctors = vec![Constructor::Wildcard];
+    } else if missing_ctors.iter().any(|c| c.is_non_exhaustive()) {
+        // We need to report a `_` anyway, so listing other constructors would be redundant.
+        // `NonExhaustive` is displayed as `_` just like `Wildcard`, but it will be picked
+        // up by diagnostics to add a note about why `_` is required here.
+        missing_ctors = vec![Constructor::NonExhaustive];
+    }
+
     let mut ret = WitnessMatrix::empty();
     for ctor in split_ctors {
         // Dig into rows that match `ctor`.
@@ -1540,7 +1538,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
         })?;
 
         // Transform witnesses for `spec_matrix` into witnesses for `matrix`.
-        witnesses.apply_constructor(pcx, &missing_ctors, &ctor, report_individual_missing_ctors);
+        witnesses.apply_constructor(pcx, &missing_ctors, &ctor);
         // Accumulate the found witnesses.
         ret.extend(witnesses);