Consider a simple trait like this one
trait HasItem {
type Item
fn item(&self) -> Self::Item;
}
What I want is that implementers of this trait can choose Self::Item
to be an owned return value or a reference to some value stored in the struct implementing the trait, something like this:
struct ValAccess { it: u32 }
struct RefAccess { it: u32 }
impl HasItem for ValAccess {
type Item = u32;
fn item(&self) -> Self::Item { self.it }
}
impl HasItem for RefAccess {
type Item = &u32;
fn item(&self) -> Self::Item { &self.it }
}
The implementation of HasItem
for ValAccess
is perfectly sound, but the compiler (obviously) complains about a missing lifetime for the Item
type in RefAccess
's implementation of HasItem
.
I can fix this by adding a lifetime bound to the trait itself:
trait HasItem<'a> {
type Item
fn item(&'a self) -> Self::Item;
}
struct ValAccess { it: u32 }
struct RefAccess { it: u32 }
impl<'a> HasItem<'a> for ValAccess {
type Item = u32;
fn item(&'a self) -> Self::Item { self.it }
}
impl<'a> HasItem<'a> for RefAccess {
type Item = &'a u32;
fn item(&'a self) -> &'a u32 { &self.it }
}
But this seems awkward for two reasons: (1) The module defining the trait needs to anticipate that in some implementations the Item
may be a reference. (2) The lifetime parameter now needs to be specified everywhere the trait is used. I guess what I really want is something like this:
trait HasItem {
type Item
fn item(&self) -> Self::Item;
}
struct ValAccess { it: u32 }
struct RefAccess { it: u32 }
impl HasItem for ValAccess {
type Item = u32;
fn item(&self) -> Self::Item { self.it }
}
impl<'a> HasItem for RefAccess
where Self: 'a // <-- The idea is to put a lifetime bound on Self
// so the lifetime bound of Item is tied to Self's
// lifetime
{
type Item = &'a u32;
fn item(&self) -> Self::Item { &self.it }
}
Is anything of this sort possible at the moment? It seems to me that choosing between returning owned values or references is something rather natural to do, so I hope it's possible to do this without putting additional warts on the trait itself.