make non-PartialEq-typed consts as patterns a hard error
This commit is contained in:
parent
e9f9594913
commit
5b7786cd1d
8 changed files with 27 additions and 112 deletions
|
@ -527,6 +527,11 @@ fn register_builtins(store: &mut LintStore) {
|
||||||
"no longer needed, see #93367 \
|
"no longer needed, see #93367 \
|
||||||
<https://github.com/rust-lang/rust/issues/93367> for more information",
|
<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) {
|
fn register_internals(store: &mut LintStore) {
|
||||||
|
|
|
@ -32,7 +32,6 @@ declare_lint_pass! {
|
||||||
CONFLICTING_REPR_HINTS,
|
CONFLICTING_REPR_HINTS,
|
||||||
CONST_EVALUATABLE_UNCHECKED,
|
CONST_EVALUATABLE_UNCHECKED,
|
||||||
CONST_ITEM_MUTATION,
|
CONST_ITEM_MUTATION,
|
||||||
CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
|
|
||||||
DEAD_CODE,
|
DEAD_CODE,
|
||||||
DEPRECATED,
|
DEPRECATED,
|
||||||
DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
|
DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
|
||||||
|
@ -2342,57 +2341,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! {
|
declare_lint! {
|
||||||
/// The `ambiguous_associated_items` lint detects ambiguity between
|
/// The `ambiguous_associated_items` lint detects ambiguity between
|
||||||
/// [associated items] and [enum variants].
|
/// [associated items] and [enum variants].
|
||||||
|
|
|
@ -767,6 +767,14 @@ pub struct TypeNotStructural<'tcx> {
|
||||||
pub non_sm_ty: Ty<'tcx>,
|
pub non_sm_ty: Ty<'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)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(mir_build_invalid_pattern)]
|
#[diag(mir_build_invalid_pattern)]
|
||||||
pub struct InvalidPattern<'tcx> {
|
pub struct InvalidPattern<'tcx> {
|
||||||
|
@ -822,12 +830,6 @@ pub struct NontrivialStructuralMatch<'tcx> {
|
||||||
pub non_sm_ty: Ty<'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)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(mir_build_pattern_not_covered, code = E0005)]
|
#[diag(mir_build_pattern_not_covered, code = E0005)]
|
||||||
pub(crate) struct PatternNotCovered<'s, 'tcx> {
|
pub(crate) struct PatternNotCovered<'s, 'tcx> {
|
||||||
|
|
|
@ -16,7 +16,7 @@ use std::cell::Cell;
|
||||||
|
|
||||||
use super::PatCtxt;
|
use super::PatCtxt;
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
IndirectStructuralMatch, InvalidPattern, NaNPattern, NonPartialEqMatch, PointerPattern,
|
IndirectStructuralMatch, InvalidPattern, NaNPattern, PointerPattern, TypeNotPartialEq,
|
||||||
TypeNotStructural, UnionPattern, UnsizedPattern,
|
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
|
// Always check for `PartialEq` if we had no other errors yet.
|
||||||
// any errors.) This ensures it shows up in cargo's future-compat reports as well.
|
|
||||||
if !self.type_has_partial_eq_impl(cv.ty()) {
|
if !self.type_has_partial_eq_impl(cv.ty()) {
|
||||||
self.tcx().emit_node_span_lint(
|
let err = TypeNotPartialEq { span: self.span, non_peq_ty: cv.ty() };
|
||||||
lint::builtin::CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
|
let e = self.tcx().dcx().emit_err(err);
|
||||||
self.id,
|
let kind = PatKind::Error(e);
|
||||||
self.span,
|
return Box::new(Pat { span: self.span, ty: cv.ty(), kind });
|
||||||
NonPartialEqMatch { non_peq_ty: cv.ty() },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
#![deny(indirect_structural_match)]
|
|
||||||
|
|
||||||
//@ check-pass
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
enum O<T> {
|
enum O<T> {
|
||||||
Some(*const T), // Can also use PhantomData<T>
|
Some(*const T), // Can also use PhantomData<T>
|
||||||
|
@ -15,8 +11,7 @@ const C: &[O<B>] = &[O::None];
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = O::None;
|
let x = O::None;
|
||||||
match &[x][..] {
|
match &[x][..] {
|
||||||
C => (), //~WARN: the type must implement `PartialEq`
|
C => (), //~ERROR: the type must implement `PartialEq`
|
||||||
//~| previously accepted
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,8 @@
|
||||||
warning: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
|
error: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
|
||||||
--> $DIR/issue-65466.rs:18:9
|
--> $DIR/issue-65466.rs:14:9
|
||||||
|
|
|
|
||||||
LL | C => (),
|
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
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
//@ run-pass
|
|
||||||
trait EnumSetType {
|
trait EnumSetType {
|
||||||
type Repr;
|
type Repr;
|
||||||
}
|
}
|
||||||
|
@ -17,8 +16,7 @@ const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
match CONST_SET {
|
match CONST_SET {
|
||||||
CONST_SET => { /* ok */ } //~WARN: must implement `PartialEq`
|
CONST_SET => { /* ok */ } //~ERROR: must implement `PartialEq`
|
||||||
//~| previously accepted
|
|
||||||
_ => panic!("match fell through?"),
|
_ => panic!("match fell through?"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,8 @@
|
||||||
warning: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
|
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:20:9
|
--> $DIR/issue-72896-non-partial-eq-const.rs:19:9
|
||||||
|
|
|
|
||||||
LL | CONST_SET => { /* ok */ }
|
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
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue