Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1a97d14

Browse files
committed
fix [derive_partial_eq_without_eq] FP on trait projection
1 parent 139191b commit 1a97d14

File tree

4 files changed

+46
-2
lines changed

4 files changed

+46
-2
lines changed

clippy_lints/src/derive.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,8 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
451451
&& let Some(def_id) = trait_ref.trait_def_id()
452452
&& cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
453453
&& !has_non_exhaustive_attr(cx.tcx, *adt)
454+
&& !ty_implements_eq_trait(cx.tcx, ty, eq_trait_def_id)
454455
&& let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
455-
&& !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[])
456456
// If all of our fields implement `Eq`, we can implement `Eq` too
457457
&& adt
458458
.all_fields()
@@ -471,6 +471,10 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
471471
}
472472
}
473473

474+
fn ty_implements_eq_trait<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, eq_trait_id: DefId) -> bool {
475+
tcx.non_blanket_impls_for_ty(eq_trait_id, ty).next().is_some()
476+
}
477+
474478
/// Creates the `ParamEnv` used for the give type's derived `Eq` impl.
475479
fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> ParamEnv<'_> {
476480
// Initial map from generic index to param def.

tests/ui/derive_partial_eq_without_eq.fixed

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,21 @@ pub enum MissingEqNonExhaustive3 {
153153
Bar,
154154
}
155155

156+
mod issue_9413 {
157+
pub trait Group {
158+
type Element: Eq + PartialEq;
159+
}
160+
161+
pub trait Suite {
162+
type Group: Group;
163+
}
164+
165+
#[derive(PartialEq, Eq)]
166+
//~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
167+
pub struct Foo<C: Suite>(<C::Group as Group>::Element);
168+
169+
#[derive(PartialEq, Eq)]
170+
pub struct Bar<C: Suite>(i32, <C::Group as Group>::Element);
171+
}
172+
156173
fn main() {}

tests/ui/derive_partial_eq_without_eq.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,21 @@ pub enum MissingEqNonExhaustive3 {
153153
Bar,
154154
}
155155

156+
mod issue_9413 {
157+
pub trait Group {
158+
type Element: Eq + PartialEq;
159+
}
160+
161+
pub trait Suite {
162+
type Group: Group;
163+
}
164+
165+
#[derive(PartialEq)]
166+
//~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
167+
pub struct Foo<C: Suite>(<C::Group as Group>::Element);
168+
169+
#[derive(PartialEq, Eq)]
170+
pub struct Bar<C: Suite>(i32, <C::Group as Group>::Element);
171+
}
172+
156173
fn main() {}

tests/ui/derive_partial_eq_without_eq.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,11 @@ error: you are deriving `PartialEq` and can implement `Eq`
6767
LL | #[derive(PartialEq)]
6868
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
6969

70-
error: aborting due to 11 previous errors
70+
error: you are deriving `PartialEq` and can implement `Eq`
71+
--> tests/ui/derive_partial_eq_without_eq.rs:165:14
72+
|
73+
LL | #[derive(PartialEq)]
74+
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
75+
76+
error: aborting due to 12 previous errors
7177

0 commit comments

Comments
 (0)