struct Foo(Option<Box<Foo>>);
fn func(mut foo: Foo) {
let mut bar = &mut foo;
loop {
// while let Some(next) = bar.0.as_mut() { // version-1
// while let Some(next) = &mut bar.0 { // version-2
while let Some(ref mut next) = bar.0 { // version-3
bar = next.as_mut();
}
}
}
In the above code, only version-3 can be compiled successfully. I would like to know the differences between these three versions and why only version-3 is valid.
Note that in version-3, bar.0
doesn't seem to move to the left pattern. One simple trial:
let mut a = Foo(Some(Box::new(Foo(None))));
if let Some(ref mut _b) = a.0 {
// Foo does not implement the `Copy` trait
println!("Go into if-let");
}
let b = a; // Moving occurs here, so `a.0` is not moved
Error message of version-1:
error[E0499]: cannot borrow `bar.0` as mutable more than once at a time
--> src/lib.rs:6:32
|
6 | while let Some(next) = bar.0.as_mut() { // version-1
| ^^^^^ mutable borrow starts here in previous iteration of loop
Error message of version-2:
error[E0499]: cannot borrow `bar.0` as mutable more than once at a time
--> src/lib.rs:7:32
|
7 | while let Some(next) = &mut bar.0 { // version-2
| ^^^^^^^^^^ mutable borrow starts here in previous iteration of loop