]> git.lizzy.rs Git - rust.git/commitdiff
Make sure we don't hide errors just because a lint has been emitted
authorOliver Scherer <github35764891676564198441@oli-obk.de>
Wed, 23 Sep 2020 15:52:37 +0000 (17:52 +0200)
committerOliver Scherer <github35764891676564198441@oli-obk.de>
Wed, 23 Sep 2020 15:52:37 +0000 (17:52 +0200)
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
src/test/ui/consts/match_ice.rs
src/test/ui/consts/match_ice.stderr
src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.rs
src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.rs
src/test/ui/rfc1445/cant-hide-behind-indirect-struct-embedded.rs
src/test/ui/rfc1445/cant-hide-behind-indirect-struct-param.rs
src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs

index 9af40acc6d6168ef2b6a41b14fd9b3456352c4d7..f80c60b181ebc59332598d8aa3596c3cf50af81a 100644 (file)
@@ -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 @@ fn new(
             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 @@ fn to_pat(
                 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 @@ fn recur(
             // 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 @@ fn recur(
             // 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 @@ fn recur(
 
         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 \
index db76e230070890c9aca20ea5db0f68e15a4550be..73ff15f212234711d3dbd6aa3fe6c75b27bc8d72 100644 (file)
@@ -8,10 +8,10 @@
 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 {
index 6cc79dbca7cc2219d0c8fbf6e357123dd3308b75..915111b3ce4b49e9b00aab779fde313b7a99d951 100644 (file)
@@ -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`.
index f6947819695a60a895057b8e43b43f046efb85bd..fe62774d220d4efe825d320b60cab4a143c9278c 100644 (file)
@@ -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"); }
     }
 }
index 1c29d67b65529dd5b3d2e92589b59a6782f0eb87..c3a30674ea3878b766306c5692bad45266ca35ae 100644 (file)
@@ -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"); }
     }
 }
index 1a41dbb55c2e97f9c0c457a5078f72541982a7a0..4d0e80d5af31235f237855afa3839a5f2b0125e2 100644 (file)
@@ -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"); }
     }
 }
index 46032c4b0ebd434ef9f9f1ec52904d20820ca810..432f196ec81279fd82854e5449661beef1004fa8 100644 (file)
@@ -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"); }
     }
 }
index b5e19611da83ad035e387dc74fdb70e2e160f0f5..46d8ee3b6be9c0c5a2b1eb9efc87e696529c1898 100644 (file)
@@ -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
         _ => { }
     }
 }