Reputation:
Consider the following:
pub trait Inner {}
pub struct Thing<'a> {
inner: &'a Inner,
}
impl<'a> Thing<'a> {
pub fn get_inner(&self) -> &Inner {
self.inner
}
pub fn get_inner_mut(&mut self) -> &mut Inner {
&mut self.inner
}
}
leads to:
error[E0277]: the trait bound `&'a (dyn Inner + 'a): Inner` is not satisfied
--> src/lib.rs:13:9
|
13 | &mut self.inner
| -^^^^^^^^^^^^^^
| |
| the trait `Inner` is not implemented for `&'a (dyn Inner + 'a)`
| help: consider removing 1 leading `&`-references
|
= note: required for the cast to the object type `dyn Inner`
Which is fair, so let's follow the advice, shall we?
Same as above with this change:
pub fn get_inner_mut(&mut self) -> &mut Inner {
mut self.inner
}
error: expected expression, found keyword `mut`
--> src/lib.rs:13:9
|
13 | mut self.inner
| ^^^ expected expression
(found keyword mut is what my local compiler says, not the one in the playground link below though!)
Hm, makes sense, right? mut
alone is not an expression
But how to return a mutable reference then?
Okay, let's get experimenting a bit, shall we?
pub fn get_inner_mut(&mut self) -> &mut &Inner {
&mut &self.inner
}
(Attention, changed signature!)
leads to:
error[E0308]: mismatched types
--> src/lib.rs:13:9
|
13 | &mut &self.inner
| ^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected type `&mut &dyn Inner`
found type `&mut &'a (dyn Inner + 'a)`
note: the anonymous lifetime #1 defined on the method body at 12:5...
--> src/lib.rs:12:5
|
12 | / pub fn get_inner_mut(&mut self) -> &mut &Inner {
13 | | &mut &self.inner
14 | | }
| |_____^
note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 7:6
--> src/lib.rs:7:6
|
7 | impl<'a> Thing<'a> {
| ^^
Could this all be solved with just specifying the lifetime?
Here is the playground
Upvotes: 1
Views: 1005
Reputation: 26
The main problem I see is that Thing
only has an immutable reference to inner
.
Here is my take on this:
pub trait Inner {}
pub struct Thing<'a> {
inner: &'a mut Inner,
}
impl<'a> Thing<'a> {
pub fn get_inner(&self) -> &Inner {
self.inner
}
pub fn get_inner_mut(&mut self) -> &mut Inner {
&mut *self.inner
}
}
struct SomeInner {}
impl Inner for SomeInner {}
fn main() {
let mut inner = SomeInner {};
let mut thing = Thing { inner: &mut inner };
let inner: &Inner = thing.get_inner();
let mutable_inner: &mut Inner = thing.get_inner_mut();
}
It compiles (as you can verify on the playground)
note:
let mut inner = SomeInner {}
-> inner
is mutablelet mut thing
-> thing
is also mutable&mut *self.shape
-> I am dereferencing the reference and then creating a mutable reference to it againI am sure there are more sophisticated solutions and I hope that someone else will contribute such.
edit: as Shepmaster kindly pointed out, there is no need at all to write &mut *self.shape
. As we already have access to a mutable reference, just returning self.inner
is enough - the compiler will make sure that the mutability is honored.
In the end, my attempt would become:
impl<'a> Thing<'a> {
pub fn get_inner(&self) -> &Inner {
self.inner
}
pub fn get_inner_mut(&mut self) -> &mut Inner {
self.inner
}
}
Upvotes: 1