I'm trying to build a "field handle" abstraction which is basically something that's built once and stored; then later you can pass a shared reference to something to get a shared reference back.
The key property I'm trying to preserve is that the trait itself doesn't really need to know about lifetimes, except that the input to the methods (get and get_mut) only need to outlive the use of the borrowed input.
My trouble is in trying to come up with a way to chain two concrete impls - I want that ability because it makes generating these things a lot easier.
// The idea is that you build this, store it somewhere, and when it come times to read some data
// (or mutate it), you can simply call this method on the original object
pub trait FieldHandle {
type Source;
type Dest;
fn get<'a>(&self, source: &'a Self::Source) -> &'a Self::Dest;
fn get_mut<'a>(&self, source: &'a mut Self::Source) -> &'a mut Self::Dest;
}
struct ChainedExtractor<S, D>(S, D);
impl <S, D> FieldHandle for ChainedExtractor<S, D>
where
S: FieldHandle,
D: FieldHandle<Source=S::Dest>
{
type Source = S::Source;
type Dest = D::Dest;
fn get<'a>(&self, source: &'a Self::Source) -> &'a Self::Dest {
self.1.get(self.0.get(source))
}
fn get_mut<'a>(&self, source: &'a mut Self::Source) -> &'a mut Self::Dest {
self.1.get_mut(self.0.get_mut(source))
}
}
fn main() {
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0309]: the associated type `<S as FieldHandle>::Dest` may not live long enough
--> src/lib.rs:22:16
|
22 | self.1.get(self.0.get(source))
| ^^^
|
= help: consider adding an explicit lifetime bound `<S as FieldHandle>::Dest: 'a`...
= note: ...so that the reference type `&<S as FieldHandle>::Dest` does not outlive the data it points at
error[E0309]: the associated type `<S as FieldHandle>::Dest` may not live long enough
--> src/lib.rs:22:20
|
22 | self.1.get(self.0.get(source))
| ^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<S as FieldHandle>::Dest: 'a`...
= note: ...so that the type `<S as FieldHandle>::Dest` is not borrowed for too long
error[E0309]: the associated type `<S as FieldHandle>::Dest` may not live long enough
--> src/lib.rs:22:27
|
22 | self.1.get(self.0.get(source))
| ^^^
|
= help: consider adding an explicit lifetime bound `<S as FieldHandle>::Dest: 'a`...
= note: ...so that the reference type `&<S as FieldHandle>::Dest` does not outlive the data it points at
error[E0309]: the associated type `<S as FieldHandle>::Dest` may not live long enough
--> src/lib.rs:26:16
|
26 | self.1.get_mut(self.0.get_mut(source))
| ^^^^^^^
|
= help: consider adding an explicit lifetime bound `<S as FieldHandle>::Dest: 'a`...
= note: ...so that the reference type `&mut <S as FieldHandle>::Dest` does not outlive the data it points at
error[E0309]: the associated type `<S as FieldHandle>::Dest` may not live long enough
--> src/lib.rs:26:24
|
26 | self.1.get_mut(self.0.get_mut(source))
| ^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<S as FieldHandle>::Dest: 'a`...
= note: ...so that the type `<S as FieldHandle>::Dest` is not borrowed for too long
error[E0309]: the associated type `<S as FieldHandle>::Dest` may not live long enough
--> src/lib.rs:26:31
|
26 | self.1.get_mut(self.0.get_mut(source))
| ^^^^^^^
|
= help: consider adding an explicit lifetime bound `<S as FieldHandle>::Dest: 'a`...
= note: ...so that the reference type `&mut <S as FieldHandle>::Dest` does not outlive the data it points at
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0309`.
error: could not compile `playground`
To learn more, run the command again with --verbose.