Hello, everyone!
I have a situation where I need to pass a generic parameter of some kind of function defined as a trait. Not a simple Fn
or similar traits, but something specific. Here's my minimal code example that reproduces the problem (playground):
pub trait Hasher {
fn hash(&self) -> u64;
}
#[derive(Debug, Clone)]
pub struct Tree<H> {
data: Vec<u64>,
_phantom: std::marker::PhantomData<fn() -> H>,
}
#[derive(Debug, Clone)]
pub struct Node<'a, H> {
tree_ref: &'a Tree<H>,
index: usize,
}
#[derive(Debug, Clone)]
pub struct Proof<'a, H> {
node: Node<'a, H>,
siblings: Vec<u64>,
}
impl<'a, H: Hasher> Proof<'a, H> {
pub fn do_something(node: Node<H>) -> Self {
let n = node.clone();
todo!()
}
}
fn main() {
}
The problem is that the Proof
impl block there doesn't compile. It says that the clone doesn't work because H
doesn't implement Clone
. So if I change that impl to impl<'a, H: Hasher + Clone>
, it compiles. But... this is wrong! The Hasher shouldn't have a clone functionality (other traits, like Eq and PartialEq, Ord, PartialOrd, etc, also cause similar problems).
Also, another solution is, if I implement Clone
manually for Node
, then it will also work. But that's very clunky it reminds me of C++ operator==
issues, because then no derive works! I have to do this manually for every member for Eq, Clone, PartialEq, and everything else.
What I'd like to have is just derive and have the derived impls just work as if I derive them, so that I wouldn't have to implement them myself or have to add incorrect trait bounds to H
.
Why is this problem happening? Can someone please explain what's going on?