about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs27
-rw-r--r--src/test/ui/consts/match_ice.rs6
-rw-r--r--src/test/ui/consts/match_ice.stderr17
-rw-r--r--src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs2
-rw-r--r--src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs2
-rw-r--r--src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs2
-rw-r--r--src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs2
-rw-r--r--src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs4
8 files changed, 34 insertions, 28 deletions
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 9af40acc6d6..f80c60b181e 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
@@ -43,11 +43,16 @@ struct ConstToPat<'a, 'tcx> {
     span: Span,
     param_env: ty::ParamEnv<'tcx>,
 
-    // This tracks if we saw some error or lint for a given const value, so that
+    // This tracks if we emitted some hard error for a given const value, so that
     // we will not subsequently issue an irrelevant lint for the same const
     // value.
     saw_const_match_error: Cell<bool>,
 
+    // This tracks if we emitted some diagnostic for a given const value, so that
+    // we will not subsequently issue an irrelevant lint for the same const
+    // value.
+    saw_const_match_lint: Cell<bool>,
+
     // For backcompat we need to keep allowing non-structurally-eq types behind references.
     // See also all the `cant-hide-behind` tests.
     behind_reference: Cell<bool>,
@@ -75,6 +80,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
             param_env: pat_ctxt.param_env,
             include_lint_checks: pat_ctxt.include_lint_checks,
             saw_const_match_error: Cell::new(false),
+            saw_const_match_lint: Cell::new(false),
             behind_reference: Cell::new(false),
         }
     }
@@ -165,7 +171,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                 if !self.type_has_partial_eq_impl(cv.ty) {
                     // span_fatal avoids ICE from resolution of non-existent method (rare case).
                     self.tcx().sess.span_fatal(self.span, &msg);
-                } else if mir_structural_match_violation {
+                } else if mir_structural_match_violation && !self.saw_const_match_lint.get() {
                     self.tcx().struct_span_lint_hir(
                         lint::builtin::INDIRECT_STRUCTURAL_MATCH,
                         self.id,
@@ -289,8 +295,11 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
             // Backwards compatibility hack because we can't cause hard errors on these
             // types, so we compare them via `PartialEq::eq` at runtime.
             ty::Adt(..) if !self.type_marked_structural(cv.ty) && self.behind_reference.get() => {
-                if self.include_lint_checks && !self.saw_const_match_error.get() {
-                    self.saw_const_match_error.set(true);
+                if self.include_lint_checks
+                    && !self.saw_const_match_error.get()
+                    && !self.saw_const_match_lint.get()
+                {
+                    self.saw_const_match_lint.set(true);
                     let msg = format!(
                         "to use a constant of type `{}` in a pattern, \
                         `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
@@ -429,8 +438,11 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
             // compilation choices change the runtime behaviour of the match.
             // See https://github.com/rust-lang/rust/issues/70861 for examples.
             ty::FnPtr(..) | ty::RawPtr(..) => {
-                if self.include_lint_checks && !self.saw_const_match_error.get() {
-                    self.saw_const_match_error.set(true);
+                if self.include_lint_checks
+                    && !self.saw_const_match_error.get()
+                    && !self.saw_const_match_lint.get()
+                {
+                    self.saw_const_match_lint.set(true);
                     let msg = "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.";
@@ -457,12 +469,13 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
 
         if self.include_lint_checks
             && !self.saw_const_match_error.get()
+            && !self.saw_const_match_lint.get()
             && mir_structural_match_violation
             // FIXME(#73448): Find a way to bring const qualification into parity with
             // `search_for_structural_match_violation` and then remove this condition.
             && self.search_for_structural_match_violation(cv.ty).is_some()
         {
-            self.saw_const_match_error.set(true);
+            self.saw_const_match_lint.set(true);
             let msg = format!(
                 "to use a constant of type `{}` in a pattern, \
                  the constant's initializer must be trivial or all types \
diff --git a/src/test/ui/consts/match_ice.rs b/src/test/ui/consts/match_ice.rs
index db76e230070..73ff15f2122 100644
--- a/src/test/ui/consts/match_ice.rs
+++ b/src/test/ui/consts/match_ice.rs
@@ -8,10 +8,10 @@ struct T;
 fn main() {
     const C: &S = &S;
     match C {
-        //~^ non-exhaustive patterns: `&S` not covered
         C => {}
-        //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
-        //~| WARN was previously accepted by the compiler
+        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+        //~| WARN must be annotated
+        //~| WARN previously accepted
     }
     const K: &T = &T;
     match K {
diff --git a/src/test/ui/consts/match_ice.stderr b/src/test/ui/consts/match_ice.stderr
index 6cc79dbca7c..915111b3ce4 100644
--- a/src/test/ui/consts/match_ice.stderr
+++ b/src/test/ui/consts/match_ice.stderr
@@ -1,5 +1,5 @@
 warning: to use a constant of type `&S` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/match_ice.rs:12:9
+  --> $DIR/match_ice.rs:11:9
    |
 LL |         C => {}
    |         ^
@@ -8,18 +8,11 @@ LL |         C => {}
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
 
-error[E0004]: non-exhaustive patterns: `&S` not covered
-  --> $DIR/match_ice.rs:10:11
+error: to use a constant of type `S` in a pattern, `S` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/match_ice.rs:11:9
    |
-LL | struct S;
-   | --------- `S` defined here
-...
-LL |     match C {
-   |           ^ pattern `&S` not covered
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-   = note: the matched value is of type `&S`
+LL |         C => {}
+   |         ^
 
 error: aborting due to previous error; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs
index f6947819695..fe62774d220 100644
--- a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs
+++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs
@@ -23,7 +23,7 @@ fn main() {
     match WRAP_DOUBLY_INDIRECT_INLINE {
         WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
         //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
-        //~| WARN will become a hard error in a future release
+        //~| WARN this was previously accepted
         _ => { println!("WRAP_DOUBLY_INDIRECT_INLINE correctly did not match itself"); }
     }
 }
diff --git a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs
index 1c29d67b655..c3a30674ea3 100644
--- a/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs
+++ b/src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs
@@ -23,7 +23,7 @@ fn main() {
     match WRAP_DOUBLY_INDIRECT_PARAM {
         WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
         //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
-        //~| WARN will become a hard error in a future release
+        //~| WARN this was previously accepted
         _ => { println!("WRAP_DOUBLY_INDIRECT_PARAM correctly did not match itself"); }
     }
 }
diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs
index 1a41dbb55c2..4d0e80d5af3 100644
--- a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs
+++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs
@@ -23,7 +23,7 @@ fn main() {
     match WRAP_INDIRECT_INLINE {
         WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); }
         //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
-        //~| WARN will become a hard error in a future release
+        //~| WARN this was previously accepted
         _ => { println!("WRAP_INDIRECT_INLINE did not match itself"); }
     }
 }
diff --git a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs
index 46032c4b0eb..432f196ec81 100644
--- a/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs
+++ b/src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs
@@ -23,7 +23,7 @@ fn main() {
     match WRAP_INDIRECT_PARAM {
         WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); }
         //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
-        //~| WARN will become a hard error in a future release
+        //~| WARN this was previously accepted
         _ => { println!("WRAP_INDIRECT_PARAM correctly did not match itself"); }
     }
 }
diff --git a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs
index b5e19611da8..46d8ee3b6be 100644
--- a/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs
+++ b/src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs
@@ -30,14 +30,14 @@ fn main() {
     match RR_B0 {
         RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
         //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
-        //~| WARN will become a hard error in a future release
+        //~| WARN this was previously accepted
         _ => { }
     }
 
     match RR_B1 {
         RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); }
         //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
-        //~| WARN will become a hard error in a future release
+        //~| WARN this was previously accepted
         _ => { }
     }
 }