about summary refs log tree commit diff
path: root/compiler/rustc_session/src
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2020-09-20 17:22:33 +0200
committerOliver Scherer <github35764891676564198441@oli-obk.de>2020-09-20 18:42:15 +0200
commitadf98ab2dc6b3d8332873d41f3371a839b4e9df1 (patch)
tree94db6d5558a7a37eb042c67e21409983f855f209 /compiler/rustc_session/src
parentaba5ea1430df393eddc90068e838de6b1707c0d8 (diff)
downloadrust-adf98ab2dc6b3d8332873d41f3371a839b4e9df1.tar.gz
rust-adf98ab2dc6b3d8332873d41f3371a839b4e9df1.zip
Use precise errors during const to pat conversion instead of a catch-all on the main constant
Diffstat (limited to 'compiler/rustc_session/src')
-rw-r--r--compiler/rustc_session/src/lint/builtin.rs70
1 files changed, 52 insertions, 18 deletions
diff --git a/compiler/rustc_session/src/lint/builtin.rs b/compiler/rustc_session/src/lint/builtin.rs
index c72b97fa1ca..919aaf81ed2 100644
--- a/compiler/rustc_session/src/lint/builtin.rs
+++ b/compiler/rustc_session/src/lint/builtin.rs
@@ -2138,22 +2138,16 @@ declare_lint! {
     /// ```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 => { }
+    ///         _ => { }
     ///     }
     /// }
     /// ```
@@ -2170,9 +2164,8 @@ declare_lint! {
     /// [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,
@@ -2224,6 +2217,46 @@ declare_lint! {
 }
 
 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].
     ///
@@ -2657,6 +2690,7 @@ declare_lint_pass! {
         MUTABLE_BORROW_RESERVATION_CONFLICT,
         INDIRECT_STRUCTURAL_MATCH,
         POINTER_STRUCTURAL_MATCH,
+        NONTRIVIAL_STRUCTURAL_MATCH,
         SOFT_UNSTABLE,
         INLINE_NO_SANITIZE,
         ASM_SUB_REGISTER,