pub trait PhfBorrow<B: ?Sized> {
    fn borrow(&self) -> &B;
}
Expand description

Identical to std::borrow::Borrow except omitting blanket impls to facilitate other borrowing patterns.

The same semantic requirements apply:

In particular Eq, Ord and Hash must be equivalent for borrowed and owned values: x.borrow() == y.borrow() should give the same result as x == y.

(This crate’s API only requires Eq and PhfHash, however.)

Motivation

The conventional signature for lookup methods on collections looks something like this:

impl<K, V> Map<K, V> where K: PhfHash + Eq {
    fn get<T: ?Sized>(&self, key: &T) -> Option<&V> where T: PhfHash + Eq, K: Borrow<T> {
        ...
    }
}

This allows the key type used for lookup to be different than the key stored in the map so for example you can use &str to look up a value in a Map<String, _>. However, this runs into a problem in the case where T and K are both a Foo<_> type constructor but the contained type is different (even being the same type with different lifetimes).

The main issue for this crate’s API is that, with this method signature, you cannot perform a lookup on a Map<UniCase<&'static str>, _> with a UniCase<&'a str> where 'a is not 'static; there is no impl of Borrow that resolves to impl Borrow<UniCase<'a>> for UniCase<&'static str> and one cannot be added either because of all the blanket impls.

Instead, this trait is implemented conservatively, without blanket impls, so that impls like this may be added. This is feasible since the set of types that implement PhfHash is intentionally small.

This likely won’t be fixable with specialization alone but will require full support for lattice impls since we technically want to add overlapping blanket impls.

Required Methods

Convert a reference to self to a reference to the borrowed type.

Implementations on Foreign Types

Implementors