struct RefWrap<'a> {
wrap: &'a mut Option<String>,
}
impl<'a> RefWrap<'a> {
fn unwrap(&mut self) -> &'a mut String {
match *self.wrap {
Some(ref mut s) => s,
None => panic!(),
}
}
}
(Playground)
As far as I understand, this code is correct (the returned reference really has the lifetime 'a
. But Rust produces the following error:
error[E0495]: cannot infer an appropriate lifetime for pattern due to conflicting requirements
--> <anon>:8:18
|
8 | Some(ref mut s) => s,
| ^^^^^^^^^
Using immutable references, it works without an error.
There has been one similar question, but I'm pretty sure it's not helpful in this case.
It looks like the conflict is that the return value:
'a
&mut self
, which is only the lifetime of the function call.If this were allowed, it would let you call it twice and get two &'a mut
references to the same String
contents:
let mut w = RefWrap { wrap: &mut s };
let ref1 = w.unwrap();
let ref2 = w.unwrap(); // two mutable references!
The reason is that the way Rust reasons about whether something is borrowed is by tying lifetimes together - but here you are explicitly saying that the return value's lifetime is unrelated to &mut self
, which means it doesn't extend the borrow - and then you can borrow again with another call.
The solution here, to get the original reference lifetime out without risking a second &mut
reference overlapping it, is to take self
by value (move) so that it can't be used again. The compiler is happy with this:
impl<'a> RefWrap<'a> {
fn unwrap(self) -> &'a mut String {
match *self.wrap {
Some(ref mut s) => s,
None => panic!(),
}
}
}
(Playground)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With