about summary refs log tree commit diff
diff options
context:
space:
mode:
authormejrs <>2022-12-20 21:24:18 +0100
committerDavid Tolnay <dtolnay@gmail.com>2023-01-11 14:39:59 -0800
commitef3307289056ac3151a1a6eb29065932e5326bcf (patch)
treeb484749203f3f330fc506196b362a15ac9e213c0
parent5d2b9a9ed09ac8a4cb4b7977cdc513fe1cf56408 (diff)
downloadrust-ef3307289056ac3151a1a6eb29065932e5326bcf.tar.gz
rust-ef3307289056ac3151a1a6eb29065932e5326bcf.zip
Migrate usefulness.rs
-rw-r--r--compiler/rustc_error_messages/locales/en-US/mir_build.ftl14
-rw-r--r--compiler/rustc_mir_build/src/errors.rs14
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs21
5 files changed, 47 insertions, 6 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl
index 162cfce0a24..9f10dc4b634 100644
--- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl
@@ -313,10 +313,10 @@ mir_build_float_pattern = floating-point types cannot be used in patterns
 
 mir_build_pointer_pattern = function pointers and unsized pointers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
 
-mir_build_indirect_structural_match = 
+mir_build_indirect_structural_match =
     to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
 
-mir_build_nontrivial_structural_match = 
+mir_build_nontrivial_structural_match =
     to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
 
 mir_build_overlapping_range_endpoints = multiple patterns overlap on their endpoints
@@ -324,3 +324,13 @@ mir_build_overlapping_range_endpoints = multiple patterns overlap on their endpo
     .note = you likely meant to write mutually exclusive ranges
 
 mir_build_overlapping_range = this range overlaps on `{$range}`...
+
+mir_build_non_exhaustive_omitted_pattern = some variants are not matched explicitly
+    .label = {$count ->
+        [1] pattern `{$witness_1}`
+        [2] patterns `{$witness_1}` and `{$witness_2}`
+        [3] patterns `{$witness_1}`, `{$witness_2}` and `{$witness_3}`
+        *[other] patterns `{$witness_1}`, `{$witness_2}`, `{$witness_3}` and more
+    } not covered
+    .help = ensure that all variants are matched explicitly by adding the suggested match arms
+    .note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 6bb15730b00..e15da5bb9ce 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -685,3 +685,17 @@ pub struct Overlap<'tcx> {
     pub span: Span,
     pub range: Pat<'tcx>,
 }
+
+#[derive(LintDiagnostic)]
+#[diag(mir_build_non_exhaustive_omitted_pattern)]
+#[help]
+#[note]
+pub(crate) struct NonExhaustiveOmittedPattern<'tcx> {
+    pub scrut_ty: Ty<'tcx>,
+    #[label]
+    pub uncovered: Span,
+    pub count: usize,
+    pub witness_1: Pat<'tcx>,
+    pub witness_2: Pat<'tcx>,
+    pub witness_3: Pat<'tcx>,
+}
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 8e7ca32feb3..7f3519945c3 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -435,7 +435,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 _ => {
                     if !pointee_ty.is_sized(tcx, param_env) {
                         // `tcx.deref_mir_constant()` below will ICE with an unsized type
-                        // (except slices, which are handled in a separate arm above).                        
+                        // (except slices, which are handled in a separate arm above).
 
                         let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
                         tcx.sess.create_err(err).emit_unless(!self.include_lint_checks);
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 2c775b39718..6395b75a08f 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -2,7 +2,7 @@
 
 mod check_match;
 mod const_to_pat;
-mod deconstruct_pat;
+pub(crate) mod deconstruct_pat;
 mod usefulness;
 
 pub(crate) use self::check_match::check_match;
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index 8f80cb95e58..37aed5bd14d 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -291,9 +291,8 @@
 
 use self::ArmType::*;
 use self::Usefulness::*;
-
-use super::check_match::{joined_uncovered_patterns, pattern_not_covered_label};
 use super::deconstruct_pat::{Constructor, DeconstructedPat, Fields, SplitWildcard};
+use crate::errors::NonExhaustiveOmittedPattern;
 
 use rustc_data_structures::captures::Captures;
 
@@ -754,6 +753,23 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
     hir_id: HirId,
     witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
 ) {
+    let witness_1 = witnesses.get(0).unwrap().to_pat(cx);
+
+    cx.tcx.emit_spanned_lint(
+        NON_EXHAUSTIVE_OMITTED_PATTERNS,
+        hir_id,
+        sp,
+        NonExhaustiveOmittedPattern {
+            scrut_ty,
+            uncovered: sp,
+            count: witnesses.len(),
+            // Substitute dummy values if witnesses is smaller than 3.
+            witness_2: witnesses.get(1).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
+            witness_3: witnesses.get(2).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
+            witness_1,
+        },
+    );
+    /*
     cx.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, hir_id, sp, "some variants are not matched explicitly", |lint| {
         let joined_patterns = joined_uncovered_patterns(cx, &witnesses);
         lint.span_label(sp, pattern_not_covered_label(&witnesses, &joined_patterns));
@@ -766,6 +782,7 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
         ));
         lint
     });
+    */
 }
 
 /// Algorithm from <http://moscova.inria.fr/~maranget/papers/warn/index.html>.