One thing I'm confused about is the "expected" versus "found" sections, since they are visually identical. I think they actually differ in lifetimes, but rust has [not so] helpfully elided them from the diagnostic.
Does anyone have any hints about how to implement this trait?
You can't. As you have noted, there is a difference in lifetimes,
This
impl Borrow<(&str, u8)> for Name {
fn borrow(&self) -> &(&str, u8) {
// creates a temporary, and tries to return a reference to it
&(&self.name, self.version)
}
}
Unless you type explicitly contains (&str, u8), you cannot borrow as (&str, u8).
If I have a HashMap<Name, _>, and I want to look up entries with .get() -- is there anyway to do that by passing in something like a (&str, u8) (that is, I don't want to construct the Name just to see if it exists in the map).
Then store Name<'static> in the HashMap. This has the downside of increased memory usage, and you can avoid that with some specialized crates like beef.
You can then access the HashMap using
Name {
name: Cow::Borrowed(name),
version
}
However this is a lot of boilerplate to get rid of that allocation. I think there may be a better way, but I can't think of it right now. (This solution is untested, so take it with a grain of salt)
There's a neat trick you can apply here, described in a StackOverflow post. It's not zero-cost, but it does not increase the storage space required by the hashmap and it does not require changing the definition of Name.