I'm trying to figure out how I'm offending the rust compiler but I'm not able to wrap my head around whats wrong.
So this is the basic algorithm:
And this is how I coded it up
fn append_at_end(&mut self, value: i32) {
match self {
List::Empty => {
*self = List::new_node(value);
},
List::Head(head) => {
let mut itr = head;
loop {
if let Some(x) = itr {
if x.next.is_none() {
x.next = Some(Node::new_node(value));
break;
} else {
itr = &mut x.next;
}
}
}
}
}
}
Now the rust compiler complains for this block of code
Compiling random v0.1.0 (/Users/katharva/Personal/rust/random)
error[E0503]: cannot use `*itr` because it was mutably borrowed
--> src/main.rs:65:28
|
65 | if let Some(x) = itr {
| ^^^^^-^
| | |
| | `itr.0` is borrowed here
| use of borrowed `itr.0`
| borrow later used here
error[E0499]: cannot borrow `itr.0` as mutable more than once at a time
--> src/main.rs:65:33
|
65 | if let Some(x) = itr {
| ^ --- first borrow used here, in later iteration of loop
| |
| `itr.0` was mutably borrowed here in the previous iteration of the loop
Some errors have detailed explanations: E0499, E0503.
For more information about an error, try `rustc --explain E0499`.
error: could not compile `random` (bin "random") due to 2 previous errors
But the same code written as
fn append_at_end_option2(&mut self, value: i32) {
match self {
List::Empty => {
*self = List::new_node(value);
},
List::Head(head) => {
let mut itr = head;
loop {
match itr {
None => {},
Some(x) => {
// A bit convoluted but shows the bug
if x.next.is_none() {
x.next = Some(Node::new_node(value));
break;
} else {
itr = &mut x.next;
}
}
}
}
}
}
}
Or
fn append_at_end_option1(&mut self, value: i32) {
match self {
List::Empty => {
*self = List::new_node(value);
},
List::Head(head) => {
let mut itr = head;
loop {
if let Some(x) = itr {
itr = &mut x.next;
continue;
}
*itr = Some(Node::new_node(value));
break;
}
}
}
}
is okay, the compiler is happy with it. Both append_at_end_option2
and append_at_end_option1
will work as expected. As per my understanding all 3 pieces of the code have the same logic. So why does the first one not acceptable?
Apparently this works in the rust playground. Seems like a bug with the compiler which was fixed.