Type is Hash and borrows as both str and [u8]
ID |
rust.correctness.conflicting_borrow_hash_impl_avoided |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
medium |
Remediation Effort |
medium |
Resource |
Api Misuse |
Language |
Rust |
Description
Borrow requires the borrowed form to hash exactly like the owning type, but str and [u8] hash differently, so at most one of these two implementations can be consistent with Hash. A lookup through the other borrowed form silently misses entries in a HashMap or HashSet. Keep only the Borrow implementation that matches how the type hashes.
Rationale
Borrow requires the borrowed form to hash exactly like the owning type, but str and [u8] hash differently, so at most one of these two implementations can be consistent with Hash. A lookup through the other borrowed form silently misses entries in a HashMap or HashSet. Keep only the Borrow implementation that matches how the type hashes.
The following code illustrates the pattern detected by this rule:
use std::borrow::Borrow;
use std::hash::{Hash, Hasher};
// FLAGGED: Type is `Hash` and borrows as both `str` and `[u8]`
#[derive(PartialEq, Eq, Hash)]
pub struct DerivedKey {
text: String,
}
impl Borrow<str> for DerivedKey {
fn borrow(&self) -> &str {
self.text.as_str()
}
}
impl Borrow<[u8]> for DerivedKey {
fn borrow(&self) -> &[u8] {
self.text.as_bytes()
}
}