Hi, thanks for the language! However, I am facing a compilation error and cannot use it
I tried this code:
fn main() {}
struct S {
field: String,
}
impl S {
fn f(&mut self) -> &str {
let a = &mut self.field;
if false { // `false`, or `true`, or whatever condition
return a;
}
// drop(a); // You can add this, but still error
return &self.field;
}
}
P.S. The real world case requires mut
(though this simple demo does not).
I expected to see this happen: explanation
No error.
IMHO, there are two cases:
If the if
gets true, it will immediately return, and everything is OK
If the if
gets false, the variable a
is never used afterwards. You can also add that drop
(but still error). Thus, it should not have problem.
Instead, this happened: explanation
error[E0502]: cannot borrow `self.field` as immutable because it is also borrowed as mutable
--> src/main.rs:15:16
|
8 | fn f(&mut self) -> &str {
| - let's call the lifetime of this reference `'1`
9 | let a = &mut self.field;
| --------------- mutable borrow occurs here
10 | if true {
11 | return a;
| - returning this value requires that `self.field` is borrowed for `'1`
...
15 | return &self.field;
| ^^^^^^^^^^^ immutable borrow occurs here
Meta
rustc --version --verbose
:
rustc 1.79.0-nightly (805813650 2024-03-31)
binary: rustc
commit-hash: 805813650248c1a2f6f271460d728d1bb852d2a7
commit-date: 2024-03-31
host: x86_64-apple-darwin
release: 1.79.0-nightly
LLVM version: 18.1.2
Backtrace
<backtrace>
P.S. More (roughly equivalent) examples that do not work
fn main() {}
struct S {
field: String,
}
fn f(arg: &mut S) -> &mut str {
let a = &mut arg.field;
if true {
return a;
}
drop(a);
return &mut arg.field;
}
P.S. Another maybe related example that does not work
fn main() {}
struct S {
field: String,
}
fn f(arg: &mut S) -> &mut str {
let a = &mut arg.field;
let b = if true {
a
} else {
drop(a);
&mut arg.field
};
b
}
gives
error[E0499]: cannot borrow `arg.field` as mutable more than once at a time
--> src/main.rs:13:9
|
7 | fn f(arg: &mut S) -> &mut str {
| - let's call the lifetime of this reference `'1`
8 | let a = &mut arg.field;
| -------------- first mutable borrow occurs here
...
13 | &mut arg.field
| ^^^^^^^^^^^^^^ second mutable borrow occurs here
14 | };
15 | b
| - returning this value requires that `arg.field` is borrowed for `'1`