How to manually implement 'static to 'a lifetime coercion (Borrow vs PhfBorrow)

Due to the differences between PhfBorrow and Borrow, the following code compiles only for HashMap and not phf::Map:

fn test(key: &str) {
    let map: HashMap<MyStruct, u32> = HashMap::new();
    let phf_map: phf::Map<MyStruct, u32> = phf::Map::new();

    let key = MyStruct { key };
    map.get(&key);
    phf_map.get(&key); // <- fails to compile
}

Here is a RustExplorer link that shows the example & compiler error in more detail.

The docs state that I can manually implement the requisite borrow pattern for my type. So I was wondering if anyone would be able to provide an example impl of PhfBorrow that would result in the code compiling or point me in the right direction for further reading on this topic?

Your problem was implementing phf_shared::PhfBorrow<Self>. You just need to implement it for two lifetimes instead of one

impl<'a: 'b, 'b> phf_shared::PhfBorrow<MyStruct<'b>> for MyStruct<'a> {
    fn borrow(&self) -> &MyStruct<'b> {
        self
    }
}
4 Likes
impl<'a: 'b, 'b> phf_shared::PhfBorrow<MyStruct<'b>> for MyStruct<'a> {
    fn borrow(&self) -> &Self {
        self
    }
}

@semicoleon, haha, that was the same code posted at the same second!

4 Likes

Haha @semicoleon @steffahn, thank you both a bunch! The lifetime restrictions on the impl block is not something I've come across yet but is brilliant.

By the way, you can also put where clauses on an impl. So equivalent to the code above, an alternative way of writing it is

impl<'a, 'b> phf_shared::PhfBorrow<MyStruct<'b>> for MyStruct<'a>
where
    'a: 'b,
{
    fn borrow(&self) -> &Self {
        self
    }
}
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.