Skip to content

Commit 4ade12b

Browse files
committed
make non-PartialEq-typed consts as patterns a hard error
1 parent 384b02c commit 4ade12b

File tree

8 files changed

+27
-112
lines changed

8 files changed

+27
-112
lines changed

compiler/rustc_lint/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,11 @@ fn register_builtins(store: &mut LintStore) {
525525
"no longer needed, see RFC #3535 \
526526
<https://rust-lang.github.io/rfcs/3535-constants-in-patterns.html> for more information",
527527
);
528+
store.register_removed(
529+
"const_patterns_without_partial_eq",
530+
"converted into hard error, see RFC #3535 \
531+
<https://rust-lang.github.io/rfcs/3535-constants-in-patterns.html> for more information",
532+
);
528533
}
529534

530535
fn register_internals(store: &mut LintStore) {

compiler/rustc_lint_defs/src/builtin.rs

-52
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ declare_lint_pass! {
3232
CONFLICTING_REPR_HINTS,
3333
CONST_EVALUATABLE_UNCHECKED,
3434
CONST_ITEM_MUTATION,
35-
CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
3635
DEAD_CODE,
3736
DEPRECATED,
3837
DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
@@ -2343,57 +2342,6 @@ declare_lint! {
23432342
};
23442343
}
23452344

2346-
declare_lint! {
2347-
/// The `const_patterns_without_partial_eq` lint detects constants that are used in patterns,
2348-
/// whose type does not implement `PartialEq`.
2349-
///
2350-
/// ### Example
2351-
///
2352-
/// ```rust,compile_fail
2353-
/// #![deny(const_patterns_without_partial_eq)]
2354-
///
2355-
/// trait EnumSetType {
2356-
/// type Repr;
2357-
/// }
2358-
///
2359-
/// enum Enum8 { }
2360-
/// impl EnumSetType for Enum8 {
2361-
/// type Repr = u8;
2362-
/// }
2363-
///
2364-
/// #[derive(PartialEq, Eq)]
2365-
/// struct EnumSet<T: EnumSetType> {
2366-
/// __enumset_underlying: T::Repr,
2367-
/// }
2368-
///
2369-
/// const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
2370-
///
2371-
/// fn main() {
2372-
/// match CONST_SET {
2373-
/// CONST_SET => { /* ok */ }
2374-
/// _ => panic!("match fell through?"),
2375-
/// }
2376-
/// }
2377-
/// ```
2378-
///
2379-
/// {{produces}}
2380-
///
2381-
/// ### Explanation
2382-
///
2383-
/// Previous versions of Rust accepted constants in patterns, even if those constants' types
2384-
/// did not have `PartialEq` implemented. The compiler falls back to comparing the value
2385-
/// field-by-field. In the future we'd like to ensure that pattern matching always
2386-
/// follows `PartialEq` semantics, so that trait bound will become a requirement for
2387-
/// matching on constants.
2388-
pub CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
2389-
Warn,
2390-
"constant in pattern does not implement `PartialEq`",
2391-
@future_incompatible = FutureIncompatibleInfo {
2392-
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
2393-
reference: "issue #116122 <https://github.com/rust-lang/rust/issues/116122>",
2394-
};
2395-
}
2396-
23972345
declare_lint! {
23982346
/// The `ambiguous_associated_items` lint detects ambiguity between
23992347
/// [associated items] and [enum variants].

compiler/rustc_mir_build/src/errors.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,14 @@ pub struct TypeNotStructural<'tcx> {
764764
pub non_sm_ty: Ty<'tcx>,
765765
}
766766

767+
#[derive(Diagnostic)]
768+
#[diag(mir_build_non_partial_eq_match)]
769+
pub struct TypeNotPartialEq<'tcx> {
770+
#[primary_span]
771+
pub span: Span,
772+
pub non_peq_ty: Ty<'tcx>,
773+
}
774+
767775
#[derive(Diagnostic)]
768776
#[diag(mir_build_invalid_pattern)]
769777
pub struct InvalidPattern<'tcx> {
@@ -819,12 +827,6 @@ pub struct NontrivialStructuralMatch<'tcx> {
819827
pub non_sm_ty: Ty<'tcx>,
820828
}
821829

822-
#[derive(LintDiagnostic)]
823-
#[diag(mir_build_non_partial_eq_match)]
824-
pub struct NonPartialEqMatch<'tcx> {
825-
pub non_peq_ty: Ty<'tcx>,
826-
}
827-
828830
#[derive(Diagnostic)]
829831
#[diag(mir_build_pattern_not_covered, code = E0005)]
830832
pub(crate) struct PatternNotCovered<'s, 'tcx> {

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::cell::Cell;
1616

1717
use super::PatCtxt;
1818
use crate::errors::{
19-
IndirectStructuralMatch, InvalidPattern, NaNPattern, NonPartialEqMatch, PointerPattern,
19+
IndirectStructuralMatch, InvalidPattern, NaNPattern, PointerPattern, TypeNotPartialEq,
2020
TypeNotStructural, UnionPattern, UnsizedPattern,
2121
};
2222

@@ -209,15 +209,12 @@ impl<'tcx> ConstToPat<'tcx> {
209209
);
210210
}
211211

212-
// Always check for `PartialEq`, even if we emitted other lints. (But not if there were
213-
// any errors.) This ensures it shows up in cargo's future-compat reports as well.
212+
// Always check for `PartialEq` if we had no other errors yet.
214213
if !self.type_has_partial_eq_impl(cv.ty()) {
215-
self.tcx().emit_node_span_lint(
216-
lint::builtin::CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
217-
self.id,
218-
self.span,
219-
NonPartialEqMatch { non_peq_ty: cv.ty() },
220-
);
214+
let err = TypeNotPartialEq { span: self.span, non_peq_ty: cv.ty() };
215+
let e = self.tcx().dcx().emit_err(err);
216+
let kind = PatKind::Error(e);
217+
return Box::new(Pat { span: self.span, ty: cv.ty(), kind });
221218
}
222219
}
223220

Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
#![deny(indirect_structural_match)]
2-
3-
// check-pass
4-
51
#[derive(PartialEq, Eq)]
62
enum O<T> {
73
Some(*const T), // Can also use PhantomData<T>
@@ -15,8 +11,7 @@ const C: &[O<B>] = &[O::None];
1511
fn main() {
1612
let x = O::None;
1713
match &[x][..] {
18-
C => (), //~WARN: the type must implement `PartialEq`
19-
//~| previously accepted
14+
C => (), //~ERROR: the type must implement `PartialEq`
2015
_ => (),
2116
}
2217
}
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,8 @@
1-
warning: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
2-
--> $DIR/issue-65466.rs:18:9
1+
error: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
2+
--> $DIR/issue-65466.rs:14:9
33
|
44
LL | C => (),
55
| ^
6-
|
7-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8-
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
9-
= note: `#[warn(const_patterns_without_partial_eq)]` on by default
10-
11-
warning: 1 warning emitted
126

13-
Future incompatibility report: Future breakage diagnostic:
14-
warning: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
15-
--> $DIR/issue-65466.rs:18:9
16-
|
17-
LL | C => (),
18-
| ^
19-
|
20-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
21-
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
22-
= note: `#[warn(const_patterns_without_partial_eq)]` on by default
7+
error: aborting due to 1 previous error
238

tests/ui/match/issue-72896-non-partial-eq-const.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// run-pass
21
trait EnumSetType {
32
type Repr;
43
}
@@ -17,8 +16,7 @@ const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
1716

1817
fn main() {
1918
match CONST_SET {
20-
CONST_SET => { /* ok */ } //~WARN: must implement `PartialEq`
21-
//~| previously accepted
19+
CONST_SET => { /* ok */ } //~ERROR: must implement `PartialEq`
2220
_ => panic!("match fell through?"),
2321
}
2422
}
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,8 @@
1-
warning: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
2-
--> $DIR/issue-72896-non-partial-eq-const.rs:20:9
1+
error: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
2+
--> $DIR/issue-72896-non-partial-eq-const.rs:19:9
33
|
44
LL | CONST_SET => { /* ok */ }
55
| ^^^^^^^^^
6-
|
7-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8-
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
9-
= note: `#[warn(const_patterns_without_partial_eq)]` on by default
10-
11-
warning: 1 warning emitted
126

13-
Future incompatibility report: Future breakage diagnostic:
14-
warning: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
15-
--> $DIR/issue-72896-non-partial-eq-const.rs:20:9
16-
|
17-
LL | CONST_SET => { /* ok */ }
18-
| ^^^^^^^^^
19-
|
20-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
21-
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
22-
= note: `#[warn(const_patterns_without_partial_eq)]` on by default
7+
error: aborting due to 1 previous error
238

0 commit comments

Comments
 (0)