I have a HashSet
(actually a DashSet
from the DashMap
crate) which holds Arc<Foo>
, where Foo
looks like this:
struct Foo {
pub bar: usize,
pub children: [Whiz],
}
Yes, I'm aware that unsized types like this are tricky - that's not the topic of this post.
I'm trying to implement a lookup
function like this:
fn lookup(&mut set: DashSet<Arc<Foo>>, bar: usize, children: &[Whiz]) -> Option<Arc<Foo>> {
todo!();
}
The trickiness here comes from the fact that the keys are stored inside Arc
s, but I don't want to allocate a new Arc
or Foo
to compare against during the lookup.
DashSet
lets us look things up by any type Q
where the Key
type is Borrow<Q>
, so I thought that I could be clever and do something like this:
struct LookupKey<'a> {
bar: usize,
children: &'a [Whiz],
}
// impls to give it identical `Eq` and `Hash` behaviour to `Arc<Foo>` elided
// Borrow Arc<Foo> as LookupKey so we can call .get() by LookupKey
impl<'a> Borrow<LookupKey<'a>> for Arc<Foo> {
return &LookupKey{ bar: self.bar, children: &self.children };
}
This "clever" solution isn't working out for me, because I can't get the lifetimes to work. In the above Borrow
implementation it fails to infer a lifetime on self.children
due to conflicting requirements, and all of my playing about with trying to make lifetimes explicit has failed.
I've only been playing around in Rust for a week or so, and this is my first time not managing to win a fight against the borrow checker on my own. Help would be appreciated, both with how to make this Borrow
implementation work, and also any comments on whether I'm solving the lookup problem in a sensible way.