Reputation: 179
I have a simple struct like below called TopicTree:
#[derive(Debug, PartialEq, Eq, Hash, Default, Clone)]
// #[allow(dead_code)]
pub struct TopicTree {
topic_name: String,
child: Option<Vec<Box<TopicTree>>>,
data: Option<Vec<String>>
}
And another struct called App which has an impl block as below:
struct App {
// Topic Tree
topic_tree_root:TopicTree,
}
impl App {
pub fn parse_topic_to_tree(& mut self, topic: &str){
let mut temp_node = & mut self.topic_tree_root;
let mut found = false;
for text in topic.split("/") {
for item in temp_node.child.as_mut().unwrap() {
if item.topic_name == text {
temp_node = item.as_mut();
found = true;
break;
}
}
}
}
}
When I try to compile the code, rustc gives me this error:
error[E0499]: cannot borrow `temp_node.child` as mutable more than once at a time
--> src/pub/lib/app.rs:22:26
|
22 | for j in temp_node.child.as_mut().unwrap() {
| ^^^^^^^^^^^^^^^^^^^^^^^^ `temp_node.child` was mutably borrowed here in the previous iteration of the loop
So my question is, isn't variable item local scoped? if it is not as so, how can I iterate over temp_node.child in a nested loop, it is necessary because temp_node is also mutable.
Upvotes: 0
Views: 101
Reputation: 16475
For the inner loop to execute, the compiler has to 1) create an implicit borrow on temp_node
in order to 2) borrow temp_node.child
, in order to call as_mut()
(which takes &mut self
) and then bind the result to item
. The lifetime of item
depends on temp_node
being alive, because of this borrow-chain.
In a subsequent iteration of the outer loop, a conflict occurs: If temp_node = item.as_mut()
has executed, you need to mutably borrow temp_node
in the for item = ...
line. But it is already being borrowed to keep temp_item
alive, which came from item
, which came from temp_node
... Here, the circular logic might become apparent: There can be no guarantee - as the code is written, notwithstanding that the data structure wouldn't support this - that temp_node
and item
end up being the same object, which would cause two mutable borrows on the same value.
There might be some confusion with respect to mut
and &mut
here. temp_node
needs to be mut
(as in let mut
, because you change temp_node
), but it does not need to be a &mut
(as in "mutable borrow", because you are not modifying the data behind the reference).
Upvotes: 3