Why is the following invalid and what should I do instead to make it work?
struct Foo;
impl Foo {
fn mutable1(&mut self) -> Result<(), &str> {
Ok(())
}
fn mutable2(&mut self) -> Result<(), &str> {
self.mutable1()?;
self.mutable1()?;
Ok(())
}
}
This code yields:
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/lib.rs:10:9
|
8 | fn mutable2(&mut self) -> Result<(), &str> {
| - let's call the lifetime of this reference `'1`
9 | self.mutable1()?;
| ---- - returning this value requires that `*self` is borrowed for `'1`
| |
| first mutable borrow occurs here
10 | self.mutable1()?;
| ^^^^ second mutable borrow occurs here
There are many questions already with the same error but I cannot use them to address this one as it's the presence of the implicit return provided by ?
that causes the problem, without ?
the code compiles successfully, yet with warnings.
Playground
This is the same problem discussed in Returning a reference from a HashMap or Vec causes a borrow to last beyond the scope it's in?. Through lifetime elision, the lifetime of the &str
is tied to the lifetime of &self
. The compiler isn't aware that the borrow won't be used in the condition that an Ok
is returned. It's overly conservative and disallows this code. This is a limitation of the current borrow checker implementation.
If you did need the lifetime of the Err
variant to be tied to the lifetime of the Foo
instance, there's not much to be done in safe Rust (unsafe Rust is another story). In your case, however, it seems unlikely that your &str
is intended to be tied to the lifetime of self
, so you can use explicit lifetimes to avoid the problem. For example, a &'static str
is a common basic error type:
impl Foo {
fn mutable1(&mut self) -> Result<(), &'static str> {
Ok(())
}
fn mutable2(&mut self) -> Result<(), &'static str> {
self.mutable1()?;
self.mutable1()?;
Ok(())
}
}
as it's the presence of the implicit return provided by
?
Not really, as the same code with explicit returns has the same problem:
fn mutable2(&mut self) -> Result<(), &str> {
if let Err(e) = self.mutable1() {
return Err(e);
}
if let Err(e) = self.mutable1() {
return Err(e);
}
Ok(())
}
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/lib.rs:12:25
|
8 | fn mutable2(&mut self) -> Result<(), &str> {
| - let's call the lifetime of this reference `'1`
9 | if let Err(e) = self.mutable1() {
| ---- first mutable borrow occurs here
10 | return Err(e);
| ------ returning this value requires that `*self` is borrowed for `'1`
11 | }
12 | if let Err(e) = self.mutable1() {
| ^^^^ second mutable borrow occurs here
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