In its implementation, T can be borrowed from self, with a lifetime that is necessarily shorter than that of self. Alternatively, T can be separated from self, in which case, there are no imposed constraints on the lifetime of T.
But got the error:
error: `impl` item signature doesn't match `trait` item signature
--> src/lib.rs:6:5
|
2 | fn get(&self) -> T;
| ------------------- expected `fn(&'1 T) -> &'2 T`
...
6 | fn get(&self) -> &T {
| ^^^^^^^^^^^^^^^^^^^ found `fn(&'1 T) -> &'1 T`
|
= note: expected signature `fn(&'1 T) -> &'2 T`
found signature `fn(&'1 T) -> &'1 T`
help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
--> src/lib.rs:2:22
|
2 | fn get(&self) -> T;
| ^ consider borrowing this type parameter in the trait
This does not the thing you expect. Basically, it is
impl<T, 'a> Has<&'a T> for T {
fn get(&self) -> &'a T {
self
}
}
where 'a = 'static is allowed, so this is a special case of your impl, and this is not what you intended.
impl<T> Has<&'static T> for T {
fn get(&self) -> &'static T {
self
}
}
For this reason, the Deref trait has the &Target in the fn signature.
A trait Has that can do both owned and borrowed access could be quite tricky. But it definitely needs some GATs.
Correct. Making it identical to T cannot work.
You want your ref-based impl to have the signature to effectively be fn get<'a>(&'a self) -> &'a T.
You cannot write impl<T> Has<&'always_lifetime_of_the_self_arg T> for T.
Even HRTB dont help here for<'a> &'a T is not valid and would basically mean &'static.
Maybe you can do some trait magic that says, "if T and T1 are different, they are not too different."