rust does not have proper higher kinded types, you'll need to "emulate" some of the behavior, e.g. with GAT, but it's not real HKT, so it depends on the use cases.
for this example, I think you can try something like this:
trait View<'a> {
type Interned<'b>;
fn intern_key(&self) -> &'a str;
fn intern<'arena>(&self, arena: &'arena Bump) -> (&'arena str, Self::Interned<'arena>);
}
because it's not real HKT, you cannot ensure Self::Interned and Self is the same type (constructor), so you'll have to rely on the implementor being cooperative.
it can be used like this:
struct Interner<'arena, T: View<'arena>> {
items: HashMap<&'arena str, <T as View<'arena>>::Interned<'arena>>,
arena: &'arena Bump,
}
impl<'arena, T> Interner<'arena, T>
where
T: View<'arena>,
<T as View<'arena>>::Interned<'arena>: Copy,
{
fn add<'a>(&mut self, obj: T) {
let (key, interned) = obj.intern(&self.arena);
self.items.insert(key, interned);
}
fn get(&self, key: &str) -> Option<T::Interned<'arena>> {
self.items.get(key).copied()
}
}
some of the <T as View<'arena>>::Interned<'arena> can be shortened as T::Interned<'arena>, but you can also make an alias for convenienct, e.g.:
type ArenaInterned<'a, T> = <T as View<'a>>::Interned<'a>;
if such workaround is insufficient for you use case, check out the higher-kinded-types crate, which provides a more sophisticated solution, you just use ForLt as super trait of View, and replace <T as View<'a>>::Interned<'b>> with <T as ForLt>::Of<'b>, or T::Of<'b> for short. something like:
use higher_kinded_types::ForLt;
trait View<'a>: ForLt {
fn intern_key(&self) -> &'a str;
fn intern<'arena>(&self, arena: &'arena Bump) -> (&'arena str, Self::Of<'arena>);
}
but still, it's not real hkt, so you may encounter some limitations. see the documentation of higher-kinded-types for more information.