I am trying to decide whether I should add a lifetime parameter to my impls, but it seems I'm in a "damned if you do, damned if you don't" situation because the compiler complains regardless whether there's a lifetime parameter or not.
pub struct TurtleRef<'a> {
t: &'a BorrowedTurtle<'a>,
}
impl TurtleRef<'_> {
pub fn borrowed_turtle(&self) -> BorrowedTurtle {
*self.t
}
pub fn new(r: Turtle) -> TurtleRef {
TurtleRef{t: &BorrowedTurtle{ t:r}}
}
}
pub struct BorrowedTurtle<'a> {
t: Turtle<'a>,
}
impl<'a> std::ops::Deref for BorrowedTurtle<'_> {
type Target = Turtle<'a>;
fn deref(&self) -> &Self::Target {
&self.t
}
}
impl<'a> std::ops::DerefMut for BorrowedTurtle<'_> {
type Target = Turtle<'a>;
fn deref_mut(&mut self) -> &mut Self::Target {
&self.t
}
}
pub struct Turtle<'a> {
children: Vec<Turtle<'a>>,
}
Turtle has more fields, but I removed them for simplicity. You can see the code snippet here. The code throws the error
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
--> src/campus.rs:54:6
|
54 | impl<'a> std::ops::Deref for BorrowedTurtle<'_> {
| ^^ unconstrained lifetime parameter
No problem, I'll just remove the parameter since it's causing such a fuss. But after removing it, I get a whole bunch of new errors:
error[E0261]: use of undeclared lifetime name `'a`
--> src/campus.rs:55:26
|
55 | type Target = Turtle<'a>;
| ^^ undeclared lifetime
|
help: consider introducing lifetime `'a` here
|
54 | impl<'a> std::ops::Deref for BorrowedTurtle<'_> {
| ^^^^
help: consider introducing lifetime `'a` here
|
55 | type Target<'a> = Turtle<'a>;
| ^^^^
Whatever you say, I'll just go ahead and add that parameter to target. But now I get yet another error:
error[E0658]: generic associated types are unstable
--> src/campus.rs:55:5
|
55 | type Target<'a> = Turtle<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
So no matter what I do, it seems I run into a major error. How do I stop these errors without starting over from scratch? I'd like to keep the impls, structs, and deref functions, so the only thing I should change is their implementation.
On another note, I get the error
error[E0437]: type `Target` is not a member of trait `std::ops::DerefMut`
--> src/campus.rs:64:5
|
64 | type Target = Turtle<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `std::ops::DerefMut`
because Turtle doesn't implement DerefMut, and in fact Turtle should not implement DerefMut. Is there a slight modification of Turtle which results in something that already implements DerefMut?