about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-02-08 20:08:19 +0100
committerRalf Jung <post@ralfj.de>2024-02-25 11:30:10 +0100
commit5b7786cd1d246fd0bbe748c8690fb99b1134d2be (patch)
treede6631e08afd079374b8eadc58bce87847f4343d
parente9f95949138125bb1b98ed213a41b9aa825bacf5 (diff)
downloadrust-5b7786cd1d246fd0bbe748c8690fb99b1134d2be.tar.gz
rust-5b7786cd1d246fd0bbe748c8690fb99b1134d2be.zip
make non-PartialEq-typed consts as patterns a hard error
-rw-r--r--compiler/rustc_lint/src/lib.rs5
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs52
-rw-r--r--compiler/rustc_mir_build/src/errors.rs14
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs15
-rw-r--r--tests/ui/consts/const_in_pattern/issue-65466.rs7
-rw-r--r--tests/ui/consts/const_in_pattern/issue-65466.stderr21
-rw-r--r--tests/ui/match/issue-72896-non-partial-eq-const.rs4
-rw-r--r--tests/ui/match/issue-72896-non-partial-eq-const.stderr21
8 files changed, 27 insertions, 112 deletions
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index d8e12c04f75..844f87c3f50 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -527,6 +527,11 @@ fn register_builtins(store: &mut LintStore) {
         "no longer needed, see #93367 \
          <https://github.com/rust-lang/rust/issues/93367> for more information",
     );
+    store.register_removed(
+        "const_patterns_without_partial_eq",
+        "converted into hard error, see RFC #3535 \
+         <https://rust-lang.github.io/rfcs/3535-constants-in-patterns.html> for more information",
+    );
 }
 
 fn register_internals(store: &mut LintStore) {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 84a050a242a..1cddb45428c 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -32,7 +32,6 @@ declare_lint_pass! {
         CONFLICTING_REPR_HINTS,
         CONST_EVALUATABLE_UNCHECKED,
         CONST_ITEM_MUTATION,
-        CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
         DEAD_CODE,
         DEPRECATED,
         DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
@@ -2343,57 +2342,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `const_patterns_without_partial_eq` lint detects constants that are used in patterns,
-    /// whose type does not implement `PartialEq`.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,compile_fail
-    /// #![deny(const_patterns_without_partial_eq)]
-    ///
-    /// trait EnumSetType {
-    ///    type Repr;
-    /// }
-    ///
-    /// enum Enum8 { }
-    /// impl EnumSetType for Enum8 {
-    ///     type Repr = u8;
-    /// }
-    ///
-    /// #[derive(PartialEq, Eq)]
-    /// struct EnumSet<T: EnumSetType> {
-    ///     __enumset_underlying: T::Repr,
-    /// }
-    ///
-    /// const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
-    ///
-    /// fn main() {
-    ///     match CONST_SET {
-    ///         CONST_SET => { /* ok */ }
-    ///         _ => panic!("match fell through?"),
-    ///     }
-    /// }
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// Previous versions of Rust accepted constants in patterns, even if those constants' types
-    /// did not have `PartialEq` implemented. The compiler falls back to comparing the value
-    /// field-by-field. In the future we'd like to ensure that pattern matching always
-    /// follows `PartialEq` semantics, so that trait bound will become a requirement for
-    /// matching on constants.
-    pub CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
-    Warn,
-    "constant in pattern does not implement `PartialEq`",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
-        reference: "issue #116122 <https://github.com/rust-lang/rust/issues/116122>",
-    };
-}
-
-declare_lint! {
     /// The `ambiguous_associated_items` lint detects ambiguity between
     /// [associated items] and [enum variants].
     ///
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 48b93ce0ac5..101f1cb9f2f 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -768,6 +768,14 @@ pub struct TypeNotStructural<'tcx> {
 }
 
 #[derive(Diagnostic)]
+#[diag(mir_build_non_partial_eq_match)]
+pub struct TypeNotPartialEq<'tcx> {
+    #[primary_span]
+    pub span: Span,
+    pub non_peq_ty: Ty<'tcx>,
+}
+
+#[derive(Diagnostic)]
 #[diag(mir_build_invalid_pattern)]
 pub struct InvalidPattern<'tcx> {
     #[primary_span]
@@ -822,12 +830,6 @@ pub struct NontrivialStructuralMatch<'tcx> {
     pub non_sm_ty: Ty<'tcx>,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(mir_build_non_partial_eq_match)]
-pub struct NonPartialEqMatch<'tcx> {
-    pub non_peq_ty: Ty<'tcx>,
-}
-
 #[derive(Diagnostic)]
 #[diag(mir_build_pattern_not_covered, code = E0005)]
 pub(crate) struct PatternNotCovered<'s, 'tcx> {
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 c77c80d9f4b..09727f9b71b 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
@@ -16,7 +16,7 @@ use std::cell::Cell;
 
 use super::PatCtxt;
 use crate::errors::{
-    IndirectStructuralMatch, InvalidPattern, NaNPattern, NonPartialEqMatch, PointerPattern,
+    IndirectStructuralMatch, InvalidPattern, NaNPattern, PointerPattern, TypeNotPartialEq,
     TypeNotStructural, UnionPattern, UnsizedPattern,
 };
 
@@ -208,15 +208,12 @@ impl<'tcx> ConstToPat<'tcx> {
                 );
             }
 
-            // Always check for `PartialEq`, even if we emitted other lints. (But not if there were
-            // any errors.) This ensures it shows up in cargo's future-compat reports as well.
+            // Always check for `PartialEq` if we had no other errors yet.
             if !self.type_has_partial_eq_impl(cv.ty()) {
-                self.tcx().emit_node_span_lint(
-                    lint::builtin::CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
-                    self.id,
-                    self.span,
-                    NonPartialEqMatch { non_peq_ty: cv.ty() },
-                );
+                let err = TypeNotPartialEq { span: self.span, non_peq_ty: cv.ty() };
+                let e = self.tcx().dcx().emit_err(err);
+                let kind = PatKind::Error(e);
+                return Box::new(Pat { span: self.span, ty: cv.ty(), kind });
             }
         }
 
diff --git a/tests/ui/consts/const_in_pattern/issue-65466.rs b/tests/ui/consts/const_in_pattern/issue-65466.rs
index 048fca762d5..62efce64876 100644
--- a/tests/ui/consts/const_in_pattern/issue-65466.rs
+++ b/tests/ui/consts/const_in_pattern/issue-65466.rs
@@ -1,7 +1,3 @@
-#![deny(indirect_structural_match)]
-
-//@ check-pass
-
 #[derive(PartialEq, Eq)]
 enum O<T> {
     Some(*const T), // Can also use PhantomData<T>
@@ -15,8 +11,7 @@ const C: &[O<B>] = &[O::None];
 fn main() {
     let x = O::None;
     match &[x][..] {
-        C => (), //~WARN: the type must implement `PartialEq`
-        //~| previously accepted
+        C => (), //~ERROR: the type must implement `PartialEq`
         _ => (),
     }
 }
diff --git a/tests/ui/consts/const_in_pattern/issue-65466.stderr b/tests/ui/consts/const_in_pattern/issue-65466.stderr
index 9c80cb3a849..7d5e5b5b0c6 100644
--- a/tests/ui/consts/const_in_pattern/issue-65466.stderr
+++ b/tests/ui/consts/const_in_pattern/issue-65466.stderr
@@ -1,23 +1,8 @@
-warning: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
-  --> $DIR/issue-65466.rs:18:9
+error: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
+  --> $DIR/issue-65466.rs:14:9
    |
 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 #116122 <https://github.com/rust-lang/rust/issues/116122>
-   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
-
-warning: 1 warning emitted
 
-Future incompatibility report: Future breakage diagnostic:
-warning: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
-  --> $DIR/issue-65466.rs:18:9
-   |
-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 #116122 <https://github.com/rust-lang/rust/issues/116122>
-   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/match/issue-72896-non-partial-eq-const.rs b/tests/ui/match/issue-72896-non-partial-eq-const.rs
index d4972714608..f15eae83896 100644
--- a/tests/ui/match/issue-72896-non-partial-eq-const.rs
+++ b/tests/ui/match/issue-72896-non-partial-eq-const.rs
@@ -1,4 +1,3 @@
-//@ run-pass
 trait EnumSetType {
     type Repr;
 }
@@ -17,8 +16,7 @@ const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
 
 fn main() {
     match CONST_SET {
-        CONST_SET => { /* ok */ } //~WARN: must implement `PartialEq`
-        //~| previously accepted
+        CONST_SET => { /* ok */ } //~ERROR: must implement `PartialEq`
         _ => panic!("match fell through?"),
     }
 }
diff --git a/tests/ui/match/issue-72896-non-partial-eq-const.stderr b/tests/ui/match/issue-72896-non-partial-eq-const.stderr
index a7fc0cfc054..4155586c160 100644
--- a/tests/ui/match/issue-72896-non-partial-eq-const.stderr
+++ b/tests/ui/match/issue-72896-non-partial-eq-const.stderr
@@ -1,23 +1,8 @@
-warning: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
-  --> $DIR/issue-72896-non-partial-eq-const.rs:20:9
+error: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
+  --> $DIR/issue-72896-non-partial-eq-const.rs:19:9
    |
 LL |         CONST_SET => { /* ok */ }
    |         ^^^^^^^^^
-   |
-   = 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 #116122 <https://github.com/rust-lang/rust/issues/116122>
-   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
-
-warning: 1 warning emitted
 
-Future incompatibility report: Future breakage diagnostic:
-warning: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
-  --> $DIR/issue-72896-non-partial-eq-const.rs:20:9
-   |
-LL |         CONST_SET => { /* ok */ }
-   |         ^^^^^^^^^
-   |
-   = 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 #116122 <https://github.com/rust-lang/rust/issues/116122>
-   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
+error: aborting due to 1 previous error