work towards rejecting consts in patterns that do not implement PartialEq
This commit is contained in:
parent
19c65022fc
commit
c5fccb98ea
8 changed files with 123 additions and 4 deletions
|
@ -2310,6 +2310,57 @@ declare_lint! {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `match_without_partial_eq` lint detects constants that are used in patterns,
|
||||||
|
/// whose type does not implement `PartialEq`.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust,compile_fail
|
||||||
|
/// #![deny(match_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 MATCH_WITHOUT_PARTIAL_EQ,
|
||||||
|
Warn,
|
||||||
|
"constant in pattern does not implement `PartialEq`",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
|
||||||
|
reference: "issue #X <https://github.com/rust-lang/rust/issues/X>",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
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].
|
||||||
|
@ -3389,6 +3440,7 @@ declare_lint_pass! {
|
||||||
LOSSY_PROVENANCE_CASTS,
|
LOSSY_PROVENANCE_CASTS,
|
||||||
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
|
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
|
||||||
MACRO_USE_EXTERN_CRATE,
|
MACRO_USE_EXTERN_CRATE,
|
||||||
|
MATCH_WITHOUT_PARTIAL_EQ,
|
||||||
META_VARIABLE_MISUSE,
|
META_VARIABLE_MISUSE,
|
||||||
MISSING_ABI,
|
MISSING_ABI,
|
||||||
MISSING_FRAGMENT_SPECIFIER,
|
MISSING_FRAGMENT_SPECIFIER,
|
||||||
|
|
|
@ -229,6 +229,9 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type
|
||||||
.suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
.suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
||||||
.help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
|
.help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
|
||||||
|
|
||||||
|
mir_build_non_partial_eq_match =
|
||||||
|
to use a constant of type `{$non_peq_ty}` in a pattern, the type must implement `PartialEq`
|
||||||
|
|
||||||
mir_build_nontrivial_structural_match =
|
mir_build_nontrivial_structural_match =
|
||||||
to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
|
to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||||
|
|
||||||
|
|
|
@ -748,6 +748,12 @@ 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(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
#[diag(mir_build_overlapping_range_endpoints)]
|
#[diag(mir_build_overlapping_range_endpoints)]
|
||||||
#[note]
|
#[note]
|
||||||
|
|
|
@ -16,8 +16,8 @@ use std::cell::Cell;
|
||||||
|
|
||||||
use super::PatCtxt;
|
use super::PatCtxt;
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
FloatPattern, IndirectStructuralMatch, InvalidPattern, NontrivialStructuralMatch,
|
FloatPattern, IndirectStructuralMatch, InvalidPattern, NonPartialEqMatch,
|
||||||
PointerPattern, TypeNotStructural, UnionPattern, UnsizedPattern,
|
NontrivialStructuralMatch, PointerPattern, TypeNotStructural, UnionPattern, UnsizedPattern,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
|
@ -235,6 +235,16 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
PointerPattern,
|
PointerPattern,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
_ if !self.type_may_have_partial_eq_impl(cv.ty()) => {
|
||||||
|
// Value is structural-match but the type doesn't even implement `PartialEq`...
|
||||||
|
self.saw_const_match_lint.set(true);
|
||||||
|
self.tcx().emit_spanned_lint(
|
||||||
|
lint::builtin::MATCH_WITHOUT_PARTIAL_EQ,
|
||||||
|
self.id,
|
||||||
|
self.span,
|
||||||
|
NonPartialEqMatch { non_peq_ty: cv.ty() },
|
||||||
|
);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@ const C: &[O<B>] = &[O::None];
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = O::None;
|
let x = O::None;
|
||||||
match &[x][..] {
|
match &[x][..] {
|
||||||
C => (),
|
C => (), //~WARN: the type must implement `PartialEq`
|
||||||
|
//~| previously accepted
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
23
tests/ui/consts/const_in_pattern/issue-65466.stderr
Normal file
23
tests/ui/consts/const_in_pattern/issue-65466.stderr
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
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 #X <https://github.com/rust-lang/rust/issues/X>
|
||||||
|
= note: `#[warn(match_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 #X <https://github.com/rust-lang/rust/issues/X>
|
||||||
|
= note: `#[warn(match_without_partial_eq)]` on by default
|
||||||
|
|
|
@ -17,7 +17,8 @@ const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
match CONST_SET {
|
match CONST_SET {
|
||||||
CONST_SET => { /* ok */ }
|
CONST_SET => { /* ok */ } //~WARN: must implement `PartialEq`
|
||||||
|
//~| previously accepted
|
||||||
_ => panic!("match fell through?"),
|
_ => panic!("match fell through?"),
|
||||||
}
|
}
|
||||||
}
|
}
|
23
tests/ui/match/issue-72896-non-partial-eq-const.stderr
Normal file
23
tests/ui/match/issue-72896-non-partial-eq-const.stderr
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
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 #X <https://github.com/rust-lang/rust/issues/X>
|
||||||
|
= note: `#[warn(match_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 #X <https://github.com/rust-lang/rust/issues/X>
|
||||||
|
= note: `#[warn(match_without_partial_eq)]` on by default
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue