fix [derive_partial_eq_without_eq] FP on trait projection

This commit is contained in:
J-ZhengLi 2024-03-02 00:37:35 +08:00
parent 139191b8b7
commit 1a97d1460b
4 changed files with 46 additions and 2 deletions

View file

@ -451,8 +451,8 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
&& let Some(def_id) = trait_ref.trait_def_id()
&& cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
&& !has_non_exhaustive_attr(cx.tcx, *adt)
&& !ty_implements_eq_trait(cx.tcx, ty, eq_trait_def_id)
&& let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
&& !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[])
// If all of our fields implement `Eq`, we can implement `Eq` too
&& adt
.all_fields()
@ -471,6 +471,10 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
}
}
fn ty_implements_eq_trait<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, eq_trait_id: DefId) -> bool {
tcx.non_blanket_impls_for_ty(eq_trait_id, ty).next().is_some()
}
/// Creates the `ParamEnv` used for the give type's derived `Eq` impl.
fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> ParamEnv<'_> {
// Initial map from generic index to param def.

View file

@ -153,4 +153,21 @@ pub enum MissingEqNonExhaustive3 {
Bar,
}
mod issue_9413 {
pub trait Group {
type Element: Eq + PartialEq;
}
pub trait Suite {
type Group: Group;
}
#[derive(PartialEq, Eq)]
//~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
pub struct Foo<C: Suite>(<C::Group as Group>::Element);
#[derive(PartialEq, Eq)]
pub struct Bar<C: Suite>(i32, <C::Group as Group>::Element);
}
fn main() {}

View file

@ -153,4 +153,21 @@ pub enum MissingEqNonExhaustive3 {
Bar,
}
mod issue_9413 {
pub trait Group {
type Element: Eq + PartialEq;
}
pub trait Suite {
type Group: Group;
}
#[derive(PartialEq)]
//~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
pub struct Foo<C: Suite>(<C::Group as Group>::Element);
#[derive(PartialEq, Eq)]
pub struct Bar<C: Suite>(i32, <C::Group as Group>::Element);
}
fn main() {}

View file

@ -67,5 +67,11 @@ error: you are deriving `PartialEq` and can implement `Eq`
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: aborting due to 11 previous errors
error: you are deriving `PartialEq` and can implement `Eq`
--> tests/ui/derive_partial_eq_without_eq.rs:165:14
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: aborting due to 12 previous errors