]> git.lizzy.rs Git - rust.git/commitdiff
Use precise errors during const to pat conversion instead of a catch-all on the main...
authorOliver Scherer <github35764891676564198441@oli-obk.de>
Sun, 20 Sep 2020 15:22:33 +0000 (17:22 +0200)
committerOliver Scherer <github35764891676564198441@oli-obk.de>
Sun, 20 Sep 2020 16:42:15 +0000 (18:42 +0200)
28 files changed:
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
compiler/rustc_session/src/lint/builtin.rs
src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.rs
src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr
src/test/ui/consts/const_in_pattern/issue-65466.rs
src/test/ui/consts/const_in_pattern/issue-65466.stderr [deleted file]
src/test/ui/consts/const_in_pattern/reject_non_partial_eq.rs
src/test/ui/consts/const_in_pattern/reject_non_partial_eq.stderr
src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr
src/test/ui/consts/match_ice.rs
src/test/ui/consts/match_ice.stderr
src/test/ui/issues/issue-34784.rs
src/test/ui/match/issue-70972-dyn-trait.rs
src/test/ui/match/issue-70972-dyn-trait.stderr
src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs
src/test/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.stderr
src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-embedded.rs
src/test/ui/rfc1445/allow-hide-behind-direct-unsafe-ptr-param.rs
src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-embedded.rs
src/test/ui/rfc1445/allow-hide-behind-indirect-unsafe-ptr-param.rs
src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-embedded.stderr
src/test/ui/rfc1445/cant-hide-behind-doubly-indirect-param.stderr
src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.rs
src/test/ui/rfc1445/issue-62307-match-ref-ref-forbidden-without-eq.stderr
src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs
src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr
src/test/ui/type-alias-impl-trait/structural-match.rs
src/test/ui/type-alias-impl-trait/structural-match.stderr

index 6ca1ff2c5f2e75fbb3d27e264a7fb21a26f0243b..ad0bcfeb367f946eed48dfd8d9b495cf6b957aa6 100644 (file)
@@ -43,7 +43,7 @@ struct ConstToPat<'a, 'tcx> {
     span: Span,
     param_env: ty::ParamEnv<'tcx>,
 
-    // This tracks if we signal some hard error for a given const value, so that
+    // This tracks if we saw some error or lint 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>,
@@ -103,7 +103,7 @@ fn to_pat(
         // once indirect_structural_match is a full fledged error, this
         // level of indirection can be eliminated
 
-        let inlined_const_as_pat = self.recur(cv);
+        let inlined_const_as_pat = self.recur(cv, mir_structural_match_violation);
 
         if self.include_lint_checks && !self.saw_const_match_error.get() {
             // If we were able to successfully convert the const to some pat,
@@ -216,7 +216,7 @@ fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
     }
 
     // Recursive helper for `to_pat`; invoke that (instead of calling this directly).
-    fn recur(&self, cv: &'tcx ty::Const<'tcx>) -> Pat<'tcx> {
+    fn recur(&self, cv: &'tcx ty::Const<'tcx>, mir_structural_match_violation: bool) -> Pat<'tcx> {
         let id = self.id;
         let span = self.span;
         let tcx = self.tcx();
@@ -227,7 +227,7 @@ fn recur(&self, cv: &'tcx ty::Const<'tcx>) -> Pat<'tcx> {
                 .enumerate()
                 .map(|(idx, val)| {
                     let field = Field::new(idx);
-                    FieldPat { field, pattern: self.recur(val) }
+                    FieldPat { field, pattern: self.recur(val, false) }
                 })
                 .collect()
         };
@@ -248,6 +248,21 @@ fn recur(&self, cv: &'tcx ty::Const<'tcx>) -> Pat<'tcx> {
                 tcx.sess.span_err(span, "cannot use unions in constant patterns");
                 PatKind::Wild
             }
+            ty::Adt(..)
+                if !self.type_has_partial_eq_impl(cv.ty)
+                    // 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() =>
+            {
+                let msg = format!(
+                    "to use a constant of type `{}` in a pattern, \
+                    `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
+                    cv.ty, cv.ty,
+                );
+                self.saw_const_match_error.set(true);
+                self.tcx().sess.span_err(self.span, &msg);
+                PatKind::Wild
+            }
             // If the type is not structurally comparable, just emit the constant directly,
             // causing the pattern match code to treat it opaquely.
             // FIXME: This code doesn't emit errors itself, the caller emits the errors.
@@ -258,6 +273,20 @@ fn recur(&self, cv: &'tcx ty::Const<'tcx>) -> Pat<'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);
+                    let msg = format!(
+                        "to use a constant of type `{}` in a pattern, \
+                        `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
+                        cv.ty, cv.ty,
+                    );
+                    tcx.struct_span_lint_hir(
+                        lint::builtin::INDIRECT_STRUCTURAL_MATCH,
+                        id,
+                        span,
+                        |lint| lint.build(&msg).emit(),
+                    );
+                }
                 PatKind::Constant { value: cv }
             }
             ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty) => {
@@ -292,14 +321,18 @@ fn recur(&self, cv: &'tcx ty::Const<'tcx>) -> Pat<'tcx> {
                     .destructure_const(param_env.and(cv))
                     .fields
                     .iter()
-                    .map(|val| self.recur(val))
+                    .map(|val| self.recur(val, false))
                     .collect(),
                 slice: None,
                 suffix: Vec::new(),
             },
             ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() {
                 // These are not allowed and will error elsewhere anyway.
-                ty::Dynamic(..) => PatKind::Constant { value: cv },
+                ty::Dynamic(..) => {
+                    self.saw_const_match_error.set(true);
+                    tcx.sess.span_err(span, &format!("`{}` cannot be used in patterns", cv.ty));
+                    PatKind::Wild
+                }
                 // `&str` and `&[u8]` are represented as `ConstValue::Slice`, let's keep using this
                 // optimization for now.
                 ty::Str => PatKind::Constant { value: cv },
@@ -321,7 +354,7 @@ fn recur(&self, cv: &'tcx ty::Const<'tcx>) -> Pat<'tcx> {
                                     .destructure_const(param_env.and(array))
                                     .fields
                                     .iter()
-                                    .map(|val| self.recur(val))
+                                    .map(|val| self.recur(val, false))
                                     .collect(),
                                 slice: None,
                                 suffix: vec![],
@@ -333,16 +366,21 @@ fn recur(&self, cv: &'tcx ty::Const<'tcx>) -> Pat<'tcx> {
                     self.behind_reference.set(old);
                     val
                 }
-                // Backwards compatibility hack. Don't take away the reference, since
-                // `PartialEq::eq` takes a reference, this makes the rest of the matching logic
-                // simpler.
+                // Backwards compatibility hack: support references to non-structural types.
+                // We'll lower
+                // this pattern to a `PartialEq::eq` comparison and `PartialEq::eq` takes a
+                // reference. This makes the rest of the matching logic simpler as it doesn't have
+                // to figure out how to get a reference again.
                 ty::Adt(..) if !self.type_marked_structural(pointee_ty) => {
                     PatKind::Constant { value: cv }
                 }
+                // All other references are converted into deref patterns and then recursively
+                // convert the dereferenced constant to a pattern that is the sub-pattern of the
+                // deref pattern.
                 _ => {
                     let old = self.behind_reference.replace(true);
                     let val = PatKind::Deref {
-                        subpattern: self.recur(tcx.deref_const(self.param_env.and(cv))),
+                        subpattern: self.recur(tcx.deref_const(self.param_env.and(cv)), false),
                     };
                     self.behind_reference.set(old);
                     val
@@ -373,11 +411,34 @@ fn recur(&self, cv: &'tcx ty::Const<'tcx>) -> Pat<'tcx> {
                 PatKind::Constant { value: cv }
             }
             _ => {
-                tcx.sess.delay_span_bug(span, &format!("cannot make a pattern out of {}", cv.ty));
+                self.saw_const_match_error.set(true);
+                tcx.sess.span_err(span, &format!("`{}` cannot be used in patterns", cv.ty));
                 PatKind::Wild
             }
         };
 
+        if self.include_lint_checks
+            && !self.saw_const_match_error.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);
+            let msg = format!(
+                "to use a constant of type `{}` in a pattern, \
+                 the constant's initializer must be trivial or all types \
+                 in the constant must be annotated with `#[derive(PartialEq, Eq)]`",
+                cv.ty,
+            );
+            tcx.struct_span_lint_hir(
+                lint::builtin::NONTRIVIAL_STRUCTURAL_MATCH,
+                id,
+                span,
+                |lint| lint.build(&msg).emit(),
+            );
+        }
+
         Pat { span, ty: cv.ty, kind: Box::new(kind) }
     }
 }
index c72b97fa1cabca2a7d7bcee7d39a263d2d4bbefa..919aaf81ed207adccffd2296ce8cc81d9c51d1f0 100644 (file)
     /// ```rust,compile_fail
     /// #![deny(indirect_structural_match)]
     ///
-    /// struct Plus(i32, i32);
-    /// const ONE_PLUS_TWO: &&Plus = &&Plus(1, 2);
-    ///
-    /// impl PartialEq for Plus {
-    ///     fn eq(&self, other: &Self) -> bool {
-    ///         self.0 + self.1 == other.0 + other.1
-    ///     }
-    /// }
-    ///
-    /// impl Eq for Plus {}
-    ///
+    /// struct NoDerive(i32);
+    /// impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
+    /// impl Eq for NoDerive { }
+    /// #[derive(PartialEq, Eq)]
+    /// struct WrapParam<T>(T);
+    /// const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0));
     /// fn main() {
-    ///     if let ONE_PLUS_TWO = &&Plus(3, 0) {
-    ///         println!("semantic!");
-    ///     } else {
-    ///         println!("structural!");
+    ///     match WRAP_INDIRECT_PARAM {
+    ///         WRAP_INDIRECT_PARAM => { }
+    ///         _ => { }
     ///     }
     /// }
     /// ```
     /// [issue #62411]: https://github.com/rust-lang/rust/issues/62411
     /// [future-incompatible]: ../index.md#future-incompatible-lints
     pub INDIRECT_STRUCTURAL_MATCH,
-    // defaulting to allow until rust-lang/rust#62614 is fixed.
-    Allow,
-    "pattern with const indirectly referencing non-structural-match type",
+    Warn,
+    "constant used in pattern contains value of non-structural-match type in a field or a variant",
     @future_incompatible = FutureIncompatibleInfo {
         reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
         edition: None,
     };
 }
 
+declare_lint! {
+    /// The `nontrivial_structural_match` lint detects constants that are used in patterns,
+    /// whose type is not structural-match and whose initializer body actually uses values
+    /// that are not structural-match. So `Option<NotStruturalMatch>` is ok if the constant
+    /// is just `None`.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(nontrivial_structural_match)]
+    ///
+    /// struct Plus(i32, i32);
+    /// const ONE_PLUS_TWO: &&Plus = &&Plus(1, 2);
+    ///
+    /// impl PartialEq for Plus {
+    ///     fn eq(&self, other: &Self) -> bool {
+    ///         self.0 + self.1 == other.0 + other.1
+    ///     }
+    /// }
+    ///
+    /// impl Eq for Plus {}
+    ///
+    /// fn main() {
+    ///     if let ONE_PLUS_TWO = &&Plus(3, 0) {
+    ///         println!("semantic!");
+    ///     } else {
+    ///         println!("structural!");
+    ///     }
+    /// }
+    /// ```
+    pub NONTRIVIAL_STRUCTURAL_MATCH,
+    Warn,
+    "constant used in pattern of non-structural-match type and the constant's initializer \
+    expression contains values of non-structural-match types",
+    @future_incompatible = FutureIncompatibleInfo {
+        reference: "issue #73448 <https://github.com/rust-lang/rust/issues/73448>",
+        edition: None,
+    };
+}
+
 declare_lint! {
     /// The `ambiguous_associated_items` lint detects ambiguity between
     /// [associated items] and [enum variants].
         MUTABLE_BORROW_RESERVATION_CONFLICT,
         INDIRECT_STRUCTURAL_MATCH,
         POINTER_STRUCTURAL_MATCH,
+        NONTRIVIAL_STRUCTURAL_MATCH,
         SOFT_UNSTABLE,
         INLINE_NO_SANITIZE,
         ASM_SUB_REGISTER,
index a1f9838ca088573ba7c595c2e7ac0512cdfacbfc..856d204178d42b8d3ed289567e1412ea70d86d55 100644 (file)
@@ -1,8 +1,5 @@
 // check-pass
 
-#![warn(indirect_structural_match)]
-//~^ NOTE lint level is defined here
-
 struct CustomEq;
 
 impl Eq for CustomEq {}
@@ -32,7 +29,8 @@ fn main() {
         BAR_BAZ => panic!(),
         //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
         //~| WARN this was previously accepted
-        //~| NOTE see issue #62411
+        //~| NOTE see issue #73448
+        //~| NOTE `#[warn(nontrivial_structural_match)]` on by default
         _ => {}
     }
 }
index 0be1cca806ed1bedcbbe6794a7c4e42796063501..fd6732195e49411793415288a6b07b0a63ef1f15 100644 (file)
@@ -1,16 +1,12 @@
-warning: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/custom-eq-branch-warn.rs:32:9
+warning: to use a constant of type `Foo` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/custom-eq-branch-warn.rs:29:9
    |
 LL |         BAR_BAZ => panic!(),
    |         ^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/custom-eq-branch-warn.rs:3:9
-   |
-LL | #![warn(indirect_structural_match)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(nontrivial_structural_match)]` on by default
    = 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 #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
 
 warning: 1 warning emitted
 
index 0e3e0f6dd88343f6e2bbcc22a64d709c18943287..2b421f4c705ecddea3ab9d3cc5b94b6c4fdf14cf 100644 (file)
@@ -1,9 +1,7 @@
-// FIXME: This still ICEs.
-//
-// ignore-test
-
 #![deny(indirect_structural_match)]
 
+// check-pass
+
 #[derive(PartialEq, Eq)]
 enum O<T> {
     Some(*const T), // Can also use PhantomData<T>
diff --git a/src/test/ui/consts/const_in_pattern/issue-65466.stderr b/src/test/ui/consts/const_in_pattern/issue-65466.stderr
deleted file mode 100644 (file)
index 9fe3049..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0601]: `main` function not found in crate `issue_65466`
-  --> $DIR/issue-65466.rs:1:1
-   |
-LL | / #![deny(indirect_structural_match)]
-LL | |
-LL | | #[derive(PartialEq, Eq)]
-LL | | enum O<T> {
-...  |
-LL | |     }
-LL | | }
-   | |_^ consider adding a `main` function to `$DIR/issue-65466.rs`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0601`.
index a8216901c027f2f057dd416da6961430727c9aae..b2b2daa830f8990cdc0727eca254494f96969667 100644 (file)
@@ -27,6 +27,7 @@ fn main() {
     match None {
         NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
         //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+        //~| ERROR must be annotated with `#[derive(PartialEq, Eq)]`
         _ => panic!("whoops"),
     }
 }
index 95cfa4a9ebe95a24b6f29a0f4e0998e68d14f747..dc830d360031ac387610852dcc4243449a5716d8 100644 (file)
@@ -1,8 +1,14 @@
-error: to use a constant of type `NoPartialEq` in a pattern, `NoPartialEq` must be annotated with `#[derive(PartialEq, Eq)]`
+error: to use a constant of type `Option<NoPartialEq>` in a pattern, `Option<NoPartialEq>` must be annotated with `#[derive(PartialEq, Eq)]`
   --> $DIR/reject_non_partial_eq.rs:28:9
    |
 LL |         NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
    |         ^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: to use a constant of type `Option<NoPartialEq>` in a pattern, `Option<NoPartialEq>` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/reject_non_partial_eq.rs:28:9
+   |
+LL |         NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
+   |         ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
index 3e7ed573c74d75e6259e05fd50ac97ee209eda04..a4feaff55b2e115e43eb19879992bb9e1ad95b20 100644 (file)
@@ -1,34 +1,30 @@
-warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
+warning: to use a constant of type `Option<NoDerive>` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
   --> $DIR/warn_corner_cases.rs:26:47
    |
 LL |     match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), };
    |                                               ^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/warn_corner_cases.rs:15:9
-   |
-LL | #![warn(indirect_structural_match)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(nontrivial_structural_match)]` on by default
    = 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 #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
 
-warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
+warning: to use a constant of type `Option<NoDerive>` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
   --> $DIR/warn_corner_cases.rs:32:47
    |
 LL |     match None { Some(_) => panic!("whoops"), CALL => dbg!(CALL), };
    |                                               ^^^^
    |
    = 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 #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
 
-warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
+warning: to use a constant of type `Option<NoDerive>` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
   --> $DIR/warn_corner_cases.rs:38:47
    |
 LL |     match None { Some(_) => panic!("whoops"), METHOD_CALL => dbg!(METHOD_CALL), };
    |                                               ^^^^^^^^^^^
    |
    = 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 #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
 
 warning: 3 warnings emitted
 
index 008c03ecddcc6f775e73377d13a12086188d10cd..db76e230070890c9aca20ea5db0f68e15a4550be 100644 (file)
@@ -8,8 +8,10 @@
 fn main() {
     const C: &S = &S;
     match C {
+        //~^ non-exhaustive patterns: `&S` not covered
         C => {}
-        //~^ ERROR to use a constant of type `S` in a pattern, `S` must be annotated with
+        //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]`
+        //~| WARN was previously accepted by the compiler
     }
     const K: &T = &T;
     match K {
index 699b4a5e200e41311cfaabfdde075b812b89098e..6cc79dbca7cc2219d0c8fbf6e357123dd3308b75 100644 (file)
@@ -1,8 +1,25 @@
-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
+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
    |
 LL |         C => {}
    |         ^
+   |
+   = note: `#[warn(nontrivial_structural_match)]` on by default
+   = 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
+   |
+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`
 
-error: aborting due to previous error
+error: aborting due to previous error; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0004`.
index d3206e994300937b6c79353408d4c9b0e59749aa..98d943470a7f9ac05aa3e31abd1997fca5e3b7a5 100644 (file)
@@ -1,4 +1,6 @@
 // run-pass
+
+#![warn(pointer_structural_match)]
 #![allow(dead_code)]
 const C: *const u8 = &0;
 
index a9b2699cafdc4956c95720b3554253ea69227dca..b69e2dab2650bc7d5c05a1ab313f94e9b7cfe795 100644 (file)
@@ -4,7 +4,8 @@ fn main() {
     let a: &dyn Send = &7u32;
     match a {
         F => panic!(),
-        //~^ ERROR trait objects cannot be used in patterns
+        //~^ ERROR `&dyn Send` cannot be used in patterns
+        //~| ERROR `&dyn Send` cannot be used in patterns
         _ => {}
     }
 }
index a4e827357de6bdfec3278c0283c295c794785f6c..985799b3c8357973cfab8a8ffb1695125031ef15 100644 (file)
@@ -1,8 +1,14 @@
-error: trait objects cannot be used in patterns
+error: `&dyn Send` cannot be used in patterns
   --> $DIR/issue-70972-dyn-trait.rs:6:9
    |
 LL |         F => panic!(),
    |         ^
 
-error: aborting due to previous error
+error: `&dyn Send` cannot be used in patterns
+  --> $DIR/issue-70972-dyn-trait.rs:6:9
+   |
+LL |         F => panic!(),
+   |         ^
+
+error: aborting due to 2 previous errors
 
index c5e4a72fb9ff18ed69a61ae52506d7fbf6d8500e..0c38b533a16e6fd0365840bdeb149dc93f2a4ca5 100644 (file)
@@ -4,6 +4,8 @@
 fn main() {
     const C: impl Copy = 0;
     match C {
-        C | _ => {} //~ ERROR: opaque types cannot be used in patterns
+        C => {} //~ ERROR: `impl Copy` cannot be used in patterns
+        //~^ ERROR: `impl Copy` cannot be used in patterns
+        _ => {}
     }
 }
index 7695223f2cf98ef8dfff80d6090302a22769551c..ad6cc0aa3e3e9ed9c8829b635271169b6c42f0c1 100644 (file)
@@ -1,8 +1,14 @@
-error: opaque types cannot be used in patterns
+error: `impl Copy` cannot be used in patterns
   --> $DIR/issue-71042-opaquely-typed-constant-used-in-pattern.rs:7:9
    |
-LL |         C | _ => {}
+LL |         C => {}
    |         ^
 
-error: aborting due to previous error
+error: `impl Copy` cannot be used in patterns
+  --> $DIR/issue-71042-opaquely-typed-constant-used-in-pattern.rs:7:9
+   |
+LL |         C => {}
+   |         ^
+
+error: aborting due to 2 previous errors
 
index b90a750cc16c4f66ff4042d94b0dac81108bf2e1..c6d7166e74065bde8a2c5ca1fc42619a8193a632 100644 (file)
@@ -3,6 +3,8 @@
 
 // run-pass
 
+#![warn(pointer_structural_match)]
+
 struct NoDerive(i32);
 
 // This impl makes NoDerive irreflexive
index 1076b9f25d89aa95eb86b3ee73190ff3bc9c7932..cc7ea6cde8d7f3bea786f4460fc9a2f0197dac34 100644 (file)
@@ -3,6 +3,8 @@
 
 // run-pass
 
+#![warn(pointer_structural_match)]
+
 struct NoDerive(i32);
 
 // This impl makes NoDerive irreflexive
index a4b832d377d6f3249ae097a13dd1a1758de065f4..86db09cc08fc8a0194f16c0dc92ba14fbb1ab02f 100644 (file)
@@ -3,6 +3,8 @@
 
 // run-pass
 
+#![warn(pointer_structural_match)]
+
 struct NoDerive(i32);
 
 // This impl makes NoDerive irreflexive
index 47b70e2e9cc56b6e7f5049241a0da93d7d867869..99c574d0780457345a05e8d9387df403d39b142d 100644 (file)
@@ -3,6 +3,8 @@
 
 // run-pass
 
+#![warn(pointer_structural_match)]
+
 struct NoDerive(i32);
 
 // This impl makes NoDerive irreflexive
index 659a9812672330b8ead5893c3e64a67e2629fb4e..eb13eed6ec11b7047c572da0a4da7830d5a06ed5 100644 (file)
@@ -1,16 +1,12 @@
-warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
+warning: to use a constant of type `&&WrapInline` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
   --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:24:9
    |
 LL |         WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9
-   |
-LL | #![warn(indirect_structural_match)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(nontrivial_structural_match)]` on by default
    = 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 #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
 
 warning: 1 warning emitted
 
index c8c36510542a2d47378b60bda79bd661a23c9d45..ddee99e76bbb9fc5ded5f5653de4396a05f68d6f 100644 (file)
@@ -1,16 +1,12 @@
-warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
+warning: to use a constant of type `&&WrapParam<NoDerive>` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
   --> $DIR/cant-hide-behind-doubly-indirect-param.rs:24:9
    |
 LL |         WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9
-   |
-LL | #![warn(indirect_structural_match)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(nontrivial_structural_match)]` on by default
    = 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 #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
 
 warning: 1 warning emitted
 
index 6ebb948d736ec3b389c035ad8d21339ad65c8cf8..b5e19611da83ad035e387dc74fdb70e2e160f0f5 100644 (file)
@@ -10,7 +10,7 @@
 
 // Issue 62307 pointed out a case where the structural-match checking
 // was too shallow.
-#![warn(indirect_structural_match)]
+#![warn(indirect_structural_match, nontrivial_structural_match)]
 // run-pass
 
 #[derive(Debug)]
index ae011dfcdba90eee8c85d03bd64400e15e10ddf1..7f4b4923332a4bf3efabe8bb6a34f2beb65727f2 100644 (file)
@@ -1,25 +1,25 @@
-warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]`
+warning: to use a constant of type `&&B` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
   --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:31:9
    |
 LL |         RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
    |         ^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9
+  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:36
    |
-LL | #![warn(indirect_structural_match)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![warn(indirect_structural_match, nontrivial_structural_match)]
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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 #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
 
-warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]`
+warning: to use a constant of type `&&B` in a pattern, the constant's initializer must be trivial or all types in the constant must be annotated with `#[derive(PartialEq, Eq)]`
   --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:38:9
    |
 LL |         RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); }
    |         ^^^^^
    |
    = 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 #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
 
 warning: 2 warnings emitted
 
index 479d6cd9af765b9bf4eae241faa4d67e3d7456c0..54fc4956b9b2825753922e574c900e6554db0224 100644 (file)
@@ -12,9 +12,10 @@ const fn leak_free() -> Bar {
 fn leak_free_test() {
     match todo!() {
         LEAK_FREE => (),
-        //~^ opaque types cannot be used in patterns
+        //~^ `impl Send` cannot be used in patterns
+        //~| `impl Send` cannot be used in patterns
         _ => (),
     }
 }
 
-fn main() { }
+fn main() {}
index ae0d8e8d4239c4a772bbdcc11fb1726670659a35..90b44f6598df6647792101eaa1540f1d9f2e790d 100644 (file)
@@ -1,8 +1,14 @@
-error: opaque types cannot be used in patterns
+error: `impl Send` cannot be used in patterns
   --> $DIR/structural-match-no-leak.rs:14:9
    |
 LL |         LEAK_FREE => (),
    |         ^^^^^^^^^
 
-error: aborting due to previous error
+error: `impl Send` cannot be used in patterns
+  --> $DIR/structural-match-no-leak.rs:14:9
+   |
+LL |         LEAK_FREE => (),
+   |         ^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
index 481448d64b1aab64458e874deb5cbdbbc23c10a5..5fe5bb4bdeaa83a9112589f97595b5a24390286b 100644 (file)
@@ -13,9 +13,10 @@ const fn value() -> Foo {
 fn test() {
     match todo!() {
         VALUE => (),
-        //~^ opaque types cannot be used in patterns
+        //~^ `impl Send` cannot be used in patterns
+        //~| `impl Send` cannot be used in patterns
         _ => (),
     }
 }
 
-fn main() { }
+fn main() {}
index ad9036a87d1d950071ccc8a0a024edec123244e4..7aca3ba8640f14e033b392bb60a4bfe958ad977b 100644 (file)
@@ -1,8 +1,14 @@
-error: opaque types cannot be used in patterns
+error: `impl Send` cannot be used in patterns
   --> $DIR/structural-match.rs:15:9
    |
 LL |         VALUE => (),
    |         ^^^^^
 
-error: aborting due to previous error
+error: `impl Send` cannot be used in patterns
+  --> $DIR/structural-match.rs:15:9
+   |
+LL |         VALUE => (),
+   |         ^^^^^
+
+error: aborting due to 2 previous errors