I'm having trouble figuring out why the borrow checker is complaining about this seemingly simple generalization of an impl on &T
:
Works:
unsafe impl<T: TrustedContainer + ?Sized> TrustedContainer for &T {
type Item = T::Item;
unsafe fn get_unchecked(&self, i: usize) -> &Self::Item {
T::get_unchecked(self, i)
}
}
Errors:
unsafe impl<'a, T: ?Sized, D> TrustedContainer for D
where
T: TrustedContainer,
D: ops::Deref<Target = T>,
{
type Item = T::Item;
unsafe fn get_unchecked(&self, i: usize) -> &Self::Item {
T::get_unchecked(self, i)
}
}
The error in question is
error[E0311]: the parameter type `T` may not live long enough
the parameter type `T` must be valid for the anonymous lifetime defined on the method body
...so that the reference type `&T` does not outlive the data it points at
In the &T
implementation, the T
may be bounded by any potentially short lived lifetime. Why does the Deref
option seem to require a lifetime bound that the specific version doesn't? (Borrow
would be a more correct bound here, I believe, except that it doesn't constrain T
.)
I'm trying to avoid having to write a TrustedContainer
impl for every container type (String
, Vec
, Box
, etc.), especially because I'd like the library not to have to contain any std flag (because it's otherwise no_std compatible). The terminal implementations are [T]
and str
, and both work perfectly.