about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-02-27 20:50:01 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-04-03 15:59:21 +0000
commit4f97540432445c7e0dc4eb51e3ac5fd915d225ad (patch)
tree6da25472b6de8d1c7da37c7a8cb408880d779891
parent4d8ed585f2ba5ce3f5a1208dc19c9b07ba0b0cee (diff)
downloadrust-4f97540432445c7e0dc4eb51e3ac5fd915d225ad.tar.gz
rust-4f97540432445c7e0dc4eb51e3ac5fd915d225ad.zip
Reinstate confusion note.
-rw-r--r--compiler/rustc_mir_build/messages.ftl4
-rw-r--r--compiler/rustc_mir_build/src/errors.rs13
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs42
-rw-r--r--tests/ui/consts/const-pattern-irrefutable.rs9
-rw-r--r--tests/ui/consts/const-pattern-irrefutable.stderr34
-rw-r--r--tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr4
-rw-r--r--tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs4
-rw-r--r--tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr10
8 files changed, 61 insertions, 59 deletions
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index c8172219267..f346cd48347 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -347,15 +347,13 @@ mir_build_inform_irrefutable = `let` bindings require an "irrefutable pattern",
 
 mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
 
-mir_build_res_defined_here = {$res} defined here
-
 mir_build_adt_defined_here = `{$ty}` defined here
 
 mir_build_variant_defined_here = not covered
 
 mir_build_interpreted_as_const = introduce a variable instead
 
-mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as {$article} {$res} pattern, not a new variable
+mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as a constant pattern, not a new variable
 
 mir_build_suggest_if_let = you might want to use `if let` to ignore the {$count ->
         [one] variant that isn't
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index c67a002dce1..6a05f35bdf3 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -6,7 +6,6 @@ use rustc_errors::{
     error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
     Handler, IntoDiagnostic, MultiSpan, SubdiagnosticMessage,
 };
-use rustc_hir::def::Res;
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::thir::Pat;
 use rustc_middle::ty::{self, Ty};
@@ -795,8 +794,6 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> {
     pub let_suggestion: Option<SuggestLet>,
     #[subdiagnostic]
     pub misc_suggestion: Option<MiscPatternSuggestion>,
-    #[subdiagnostic]
-    pub res_defined_here: Option<ResDefinedHere>,
 }
 
 #[derive(Subdiagnostic)]
@@ -831,14 +828,6 @@ impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> {
 }
 
 #[derive(Subdiagnostic)]
-#[label(mir_build_res_defined_here)]
-pub struct ResDefinedHere {
-    #[primary_span]
-    pub def_span: Span,
-    pub res: Res,
-}
-
-#[derive(Subdiagnostic)]
 #[suggestion(
     mir_build_interpreted_as_const,
     code = "{variable}_var",
@@ -848,9 +837,7 @@ pub struct ResDefinedHere {
 pub struct InterpretedAsConst {
     #[primary_span]
     pub span: Span,
-    pub article: &'static str,
     pub variable: String,
-    pub res: Res,
 }
 
 #[derive(Subdiagnostic)]
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index b1f85f03989..4fb8e915220 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -424,29 +424,38 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
         let inform = sp.is_some().then_some(Inform);
         let mut let_suggestion = None;
         let mut misc_suggestion = None;
-        if let Some(span) = sp && self.tcx.sess.source_map().is_span_accessible(span) {
-            let mut bindings= vec![];
-            pat.each_binding(|name, _, _, _| {
-                bindings.push(name);
-            });
-            let semi_span = span.shrink_to_hi();
-            let start_span = span.shrink_to_lo();
-            let end_span = semi_span.shrink_to_lo();
-            let count = witnesses.len();
-
+        let mut interpreted_as_const = None;
+        if let PatKind::Constant { .. } = pat.kind
+            && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span)
+        {
             // If the pattern to match is an integer literal:
-            if bindings.is_empty()
-                && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span)
-                && snippet.chars().all(|c| c.is_digit(10))
-            {
+            if snippet.chars().all(|c| c.is_digit(10)) {
                 // Then give a suggestion, the user might've meant to create a binding instead.
                 misc_suggestion = Some(MiscPatternSuggestion::AttemptedIntegerLiteral {
                     start_span: pat.span.shrink_to_lo()
                 });
+            } else if snippet.chars().all(|c| c.is_alphanumeric() || c == '_') {
+                interpreted_as_const = Some(InterpretedAsConst {
+                    span: pat.span,
+                    variable: snippet,
+                });
             }
+        }
+
+        if let Some(span) = sp
+            && self.tcx.sess.source_map().is_span_accessible(span)
+            && interpreted_as_const.is_none()
+        {
+            let mut bindings = vec![];
+            pat.each_binding(|name, _, _, _| bindings.push(name));
+
+            let semi_span = span.shrink_to_hi();
+            let start_span = span.shrink_to_lo();
+            let end_span = semi_span.shrink_to_lo();
+            let count = witnesses.len();
 
             let_suggestion = Some(if bindings.is_empty() {
-                SuggestLet::If {start_span, semi_span, count }
+                SuggestLet::If { start_span, semi_span, count }
             } else {
                 SuggestLet::Else { end_span, count }
             });
@@ -469,12 +478,11 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
             origin,
             uncovered: Uncovered::new(pat.span, &cx, witnesses),
             inform,
-            interpreted_as_const: None,
+            interpreted_as_const,
             _p: (),
             pattern_ty,
             let_suggestion,
             misc_suggestion,
-            res_defined_here: None,
             adt_defined_here,
         });
     }
diff --git a/tests/ui/consts/const-pattern-irrefutable.rs b/tests/ui/consts/const-pattern-irrefutable.rs
index d7d8e732839..61bdf57ffdb 100644
--- a/tests/ui/consts/const-pattern-irrefutable.rs
+++ b/tests/ui/consts/const-pattern-irrefutable.rs
@@ -12,14 +12,17 @@ fn main() {
     let a = 4;
     //~^ ERROR refutable pattern in local binding
     //~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
-    //~| HELP you might want to use `if let` to ignore the variants that aren't matched
+    //~| missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
+    //~| HELP introduce a variable instead
     let c = 4;
     //~^ ERROR refutable pattern in local binding
     //~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
-    //~| HELP you might want to use `if let` to ignore the variants that aren't matched
+    //~| missing patterns are not covered because `c` is interpreted as a constant pattern, not a new variable
+    //~| HELP introduce a variable instead
     let d = 4;
     //~^ ERROR refutable pattern in local binding
     //~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
-    //~| HELP you might want to use `if let` to ignore the variants that aren't matched
+    //~| missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
+    //~| HELP introduce a variable instead
     fn f() {} // Check that the `NOTE`s still work with an item here (cf. issue #35115).
 }
diff --git a/tests/ui/consts/const-pattern-irrefutable.stderr b/tests/ui/consts/const-pattern-irrefutable.stderr
index 956a97a476c..2aed68bdd64 100644
--- a/tests/ui/consts/const-pattern-irrefutable.stderr
+++ b/tests/ui/consts/const-pattern-irrefutable.stderr
@@ -2,43 +2,43 @@ error[E0005]: refutable pattern in local binding
   --> $DIR/const-pattern-irrefutable.rs:12:9
    |
 LL |     let a = 4;
-   |         ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
+   |         ^
+   |         |
+   |         patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
+   |         missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
+   |         help: introduce a variable instead: `a_var`
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `u8`
-help: you might want to use `if let` to ignore the variants that aren't matched
-   |
-LL |     if let a = 4 { todo!() };
-   |     ++           +++++++++++
 
 error[E0005]: refutable pattern in local binding
-  --> $DIR/const-pattern-irrefutable.rs:16:9
+  --> $DIR/const-pattern-irrefutable.rs:17:9
    |
 LL |     let c = 4;
-   |         ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
+   |         ^
+   |         |
+   |         patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
+   |         missing patterns are not covered because `c` is interpreted as a constant pattern, not a new variable
+   |         help: introduce a variable instead: `c_var`
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `u8`
-help: you might want to use `if let` to ignore the variants that aren't matched
-   |
-LL |     if let c = 4 { todo!() };
-   |     ++           +++++++++++
 
 error[E0005]: refutable pattern in local binding
-  --> $DIR/const-pattern-irrefutable.rs:20:9
+  --> $DIR/const-pattern-irrefutable.rs:22:9
    |
 LL |     let d = 4;
-   |         ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
+   |         ^
+   |         |
+   |         patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
+   |         missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
+   |         help: introduce a variable instead: `d_var`
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `u8`
-help: you might want to use `if let` to ignore the variants that aren't matched
-   |
-LL |     if let d = 4 { todo!() };
-   |     ++           +++++++++++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr
index 55f0b2319fb..ab3f6f69fb1 100644
--- a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr
+++ b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr
@@ -5,6 +5,10 @@ LL |     let f = |3: isize| println!("hello");
    |              ^ pattern `_` not covered
    |
    = note: the matched value is of type `isize`
+help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
+   |
+LL |     let f = |_3: isize| println!("hello");
+   |              +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs
index 0b7eb3ee605..af47ba8baa3 100644
--- a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs
+++ b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs
@@ -2,7 +2,9 @@ fn main() {
     let A = 3;
     //~^ ERROR refutable pattern in local binding
     //~| patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered
-    //~| HELP you might want to use `if let` to ignore the variants that aren't matched
+    //~| missing patterns are not covered because `A` is interpreted as a constant pattern, not a new variable
+    //~| HELP introduce a variable instead
+    //~| SUGGESTION A_var
 
     const A: i32 = 2;
 }
diff --git a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
index b112e3a1175..9ee3e6eb2c8 100644
--- a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
+++ b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
@@ -2,15 +2,15 @@ error[E0005]: refutable pattern in local binding
   --> $DIR/const-pat-non-exaustive-let-new-var.rs:2:9
    |
 LL |     let A = 3;
-   |         ^ patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered
+   |         ^
+   |         |
+   |         patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered
+   |         missing patterns are not covered because `A` is interpreted as a constant pattern, not a new variable
+   |         help: introduce a variable instead: `A_var`
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
-help: you might want to use `if let` to ignore the variants that aren't matched
-   |
-LL |     if let A = 3 { todo!() };
-   |     ++           +++++++++++
 
 error: aborting due to previous error