Type derives Hash but implements PartialEq by hand
ID |
rust.correctness.manual_partialeq_impl_derived_hash |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
medium |
Remediation Effort |
medium |
Resource |
Api Misuse |
Language |
Rust |
Description
Detects a struct that obtains Hash from #[derive(Hash)] while providing its own PartialEq implementation in the same file.
Rationale
Hash and Eq must agree: two values that compare equal have to produce the same hash. The derived Hash mixes in every field, whereas a hand-written eq almost always compares fewer fields or normalises them. Two values that eq calls equal then hash differently, and a HashMap or HashSet silently keeps both as separate entries, so lookups miss and insert stops replacing.
The following code illustrates the pattern detected by this rule:
use std::hash::{Hash, Hasher};
// FLAGGED: Type derives `Hash` but implements `PartialEq` by hand
#[derive(Hash)]
pub struct Account {
id: u32,
label: String,
}
impl PartialEq for Account {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Eq for Account {}