Don't lint derive_partial_eq_without_eq on private types

This commit is contained in:
Jason Newcomb 2022-06-04 17:28:23 -04:00
parent d9ddce8a22
commit a0821fbd75
4 changed files with 95 additions and 36 deletions

View file

@ -11,7 +11,9 @@ use rustc_hir::{
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::subst::GenericArg;
use rustc_middle::ty::{self, BoundConstness, ImplPolarity, ParamEnv, PredicateKind, TraitPredicate, TraitRef, Ty};
use rustc_middle::ty::{
self, BoundConstness, ImplPolarity, ParamEnv, PredicateKind, TraitPredicate, TraitRef, Ty, Visibility,
};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;
use rustc_span::sym;
@ -459,6 +461,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) {
if_chain! {
if let ty::Adt(adt, substs) = ty.kind();
if cx.tcx.visibility(adt.did()) == Visibility::Public;
if let Some(eq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Eq);
if let Some(peq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::PartialEq);
if let Some(def_id) = trait_ref.trait_def_id();

View file

@ -4,28 +4,28 @@
#![warn(clippy::derive_partial_eq_without_eq)]
// Don't warn on structs that aren't PartialEq
struct NotPartialEq {
pub struct NotPartialEq {
foo: u32,
bar: String,
}
// Eq can be derived but is missing
#[derive(Debug, PartialEq, Eq)]
struct MissingEq {
pub struct MissingEq {
foo: u32,
bar: String,
}
// Eq is derived
#[derive(PartialEq, Eq)]
struct NotMissingEq {
pub struct NotMissingEq {
foo: u32,
bar: String,
}
// Eq is manually implemented
#[derive(PartialEq)]
struct ManualEqImpl {
pub struct ManualEqImpl {
foo: u32,
bar: String,
}
@ -34,13 +34,13 @@ impl Eq for ManualEqImpl {}
// Cannot be Eq because f32 isn't Eq
#[derive(PartialEq)]
struct CannotBeEq {
pub struct CannotBeEq {
foo: u32,
bar: f32,
}
// Don't warn if PartialEq is manually implemented
struct ManualPartialEqImpl {
pub struct ManualPartialEqImpl {
foo: u32,
bar: String,
}
@ -53,52 +53,74 @@ impl PartialEq for ManualPartialEqImpl {
// Generic fields should be properly checked for Eq-ness
#[derive(PartialEq)]
struct GenericNotEq<T: Eq, U: PartialEq> {
pub struct GenericNotEq<T: Eq, U: PartialEq> {
foo: T,
bar: U,
}
#[derive(PartialEq, Eq)]
struct GenericEq<T: Eq, U: Eq> {
pub struct GenericEq<T: Eq, U: Eq> {
foo: T,
bar: U,
}
#[derive(PartialEq, Eq)]
struct TupleStruct(u32);
pub struct TupleStruct(u32);
#[derive(PartialEq, Eq)]
struct GenericTupleStruct<T: Eq>(T);
pub struct GenericTupleStruct<T: Eq>(T);
#[derive(PartialEq)]
struct TupleStructNotEq(f32);
pub struct TupleStructNotEq(f32);
#[derive(PartialEq, Eq)]
enum Enum {
pub enum Enum {
Foo(u32),
Bar { a: String, b: () },
}
#[derive(PartialEq, Eq)]
enum GenericEnum<T: Eq, U: Eq, V: Eq> {
pub enum GenericEnum<T: Eq, U: Eq, V: Eq> {
Foo(T),
Bar { a: U, b: V },
}
#[derive(PartialEq)]
enum EnumNotEq {
pub enum EnumNotEq {
Foo(u32),
Bar { a: String, b: f32 },
}
// Ensure that rustfix works properly when `PartialEq` has other derives on either side
#[derive(Debug, PartialEq, Eq, Clone)]
struct RustFixWithOtherDerives;
pub struct RustFixWithOtherDerives;
#[derive(PartialEq)]
struct Generic<T>(T);
pub struct Generic<T>(T);
#[derive(PartialEq, Eq)]
struct GenericPhantom<T>(core::marker::PhantomData<T>);
pub struct GenericPhantom<T>(core::marker::PhantomData<T>);
mod _hidden {
#[derive(PartialEq, Eq)]
pub struct Reexported;
#[derive(PartialEq, Eq)]
pub struct InPubFn;
#[derive(PartialEq)]
pub(crate) struct PubCrate;
#[derive(PartialEq)]
pub(super) struct PubSuper;
}
pub use _hidden::Reexported;
pub fn _from_mod() -> _hidden::InPubFn {
_hidden::InPubFn
}
#[derive(PartialEq)]
struct InternalTy;
fn main() {}

View file

@ -4,28 +4,28 @@
#![warn(clippy::derive_partial_eq_without_eq)]
// Don't warn on structs that aren't PartialEq
struct NotPartialEq {
pub struct NotPartialEq {
foo: u32,
bar: String,
}
// Eq can be derived but is missing
#[derive(Debug, PartialEq)]
struct MissingEq {
pub struct MissingEq {
foo: u32,
bar: String,
}
// Eq is derived
#[derive(PartialEq, Eq)]
struct NotMissingEq {
pub struct NotMissingEq {
foo: u32,
bar: String,
}
// Eq is manually implemented
#[derive(PartialEq)]
struct ManualEqImpl {
pub struct ManualEqImpl {
foo: u32,
bar: String,
}
@ -34,13 +34,13 @@ impl Eq for ManualEqImpl {}
// Cannot be Eq because f32 isn't Eq
#[derive(PartialEq)]
struct CannotBeEq {
pub struct CannotBeEq {
foo: u32,
bar: f32,
}
// Don't warn if PartialEq is manually implemented
struct ManualPartialEqImpl {
pub struct ManualPartialEqImpl {
foo: u32,
bar: String,
}
@ -53,52 +53,74 @@ impl PartialEq for ManualPartialEqImpl {
// Generic fields should be properly checked for Eq-ness
#[derive(PartialEq)]
struct GenericNotEq<T: Eq, U: PartialEq> {
pub struct GenericNotEq<T: Eq, U: PartialEq> {
foo: T,
bar: U,
}
#[derive(PartialEq)]
struct GenericEq<T: Eq, U: Eq> {
pub struct GenericEq<T: Eq, U: Eq> {
foo: T,
bar: U,
}
#[derive(PartialEq)]
struct TupleStruct(u32);
pub struct TupleStruct(u32);
#[derive(PartialEq)]
struct GenericTupleStruct<T: Eq>(T);
pub struct GenericTupleStruct<T: Eq>(T);
#[derive(PartialEq)]
struct TupleStructNotEq(f32);
pub struct TupleStructNotEq(f32);
#[derive(PartialEq)]
enum Enum {
pub enum Enum {
Foo(u32),
Bar { a: String, b: () },
}
#[derive(PartialEq)]
enum GenericEnum<T: Eq, U: Eq, V: Eq> {
pub enum GenericEnum<T: Eq, U: Eq, V: Eq> {
Foo(T),
Bar { a: U, b: V },
}
#[derive(PartialEq)]
enum EnumNotEq {
pub enum EnumNotEq {
Foo(u32),
Bar { a: String, b: f32 },
}
// Ensure that rustfix works properly when `PartialEq` has other derives on either side
#[derive(Debug, PartialEq, Clone)]
struct RustFixWithOtherDerives;
pub struct RustFixWithOtherDerives;
#[derive(PartialEq)]
struct Generic<T>(T);
pub struct Generic<T>(T);
#[derive(PartialEq, Eq)]
struct GenericPhantom<T>(core::marker::PhantomData<T>);
pub struct GenericPhantom<T>(core::marker::PhantomData<T>);
mod _hidden {
#[derive(PartialEq)]
pub struct Reexported;
#[derive(PartialEq)]
pub struct InPubFn;
#[derive(PartialEq)]
pub(crate) struct PubCrate;
#[derive(PartialEq)]
pub(super) struct PubSuper;
}
pub use _hidden::Reexported;
pub fn _from_mod() -> _hidden::InPubFn {
_hidden::InPubFn
}
#[derive(PartialEq)]
struct InternalTy;
fn main() {}

View file

@ -42,5 +42,17 @@ error: you are deriving `PartialEq` and can implement `Eq`
LL | #[derive(Debug, PartialEq, Clone)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: aborting due to 7 previous errors
error: you are deriving `PartialEq` and can implement `Eq`
--> $DIR/derive_partial_eq_without_eq.rs:105:14
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
--> $DIR/derive_partial_eq_without_eq.rs:108:14
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: aborting due to 9 previous errors