I am the user of yoke crate,
in order to remove the lifetime in struct declaration.
But the API is not easy to use because it lacks implementation of Deref trait.
So I wrap it inside a new type, and want to implement Deref trait through it.
My example does not involve yoke for simplicity:
use core::ops::Deref;
struct Foo<'a> {
data: &'a str,
}
struct Bar(Foo<'static>);
impl Deref for Bar {
type Target = Foo<'static>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
}
The above code works,
but is there a way to specify Self lifetime in Target
The code below does not work
impl Deref for Bar {
type Target = Foo<'Self>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
Thanks
Real example with yoke crate
/*
[dependencies]
yoke = { version = "0.7", features = ["derive"] }
*/
use core::ops::Deref;
use std::sync::Arc;
use yoke::{Yoke, Yokeable};
#[derive(Yokeable)]
struct Foo<'a> {
data: &'a str,
}
struct Bar(Yoke<Foo<'static>, Arc<String>>);
impl Deref for Bar {
// HELP: How to change this to `Self` lifetime?
type Target = Foo<'static>;
fn deref(&self) -> &Self::Target {
// ERROR: Cannot compile here
self.0.get()
}
}
fn main() {
}
No, that's not possible in associated type position, for the same reason you have to be explicit about the lifetimes in the definition of a struct or enum. As impls are in global scope, there's no context anywhere for the compiler to infer any particular lifetime from, as there would be in a signature or a function body.
To answer the question: your problem is that there's no concrete lifetime to put in the associated Target type of Deref, andDeref::Target is not a GAT (generic associated type).
You thus have to be explicit about there being a reference and a named lifetime to begin with:
The purpose of Yoke is that you can have a self-referential type Anyway – if you need Bar to be non-generic, then introduce a second level of wrapper that you only create temporarily, when and where needed:
Guess why Yoke itself doesn't implement Deref.. because the target type (as returned by the Yoke::get method) would need to depend on the lifetime of its &self argument! It's the same problem
Wrapping a Yoke type won't make you magically be able to achieve what yoke itself couldn't
Thanks,
I think the best solution is to not use Yoke wrapped type in most situation.
The alternative may be to delegate all APIs of borrowed type to owned type.