When the last copy of an `@mut` value is overwritten or goes out of scope, the runtime is free to deallocate the value it points to. When you take an `&'r mut` to a value in an `@mut`, the compiler has to ensure that at least one copy of the `@mut` exists for the lifetime 'r, since the `&'r mut` isn't involved in memory management and risks becoming a dangling pointer if the memory it points to gets deallocated. It does this by "rooting" the borrow, which means that it implicitly stores a copy of the `@mut` pointer on the stack for the lifetime 'r. The problem is that the lifetime 'r escapes the stack frame (via the return value), so there's nowhere to store a copy of the `@mut` that will outlive the borrow.
Also, even if the compiler realized that, since the pointer passed to the function has to be frozen for the lifetime of the borrow, any `@mut` it references will outlive the borrow, it would still have to dynamically freeze the `@mut` for the lifetime 'r, and there's no way for the compiler to know to dynamically *unfreeze* the `@mut` when the borrow ends, again since the lifetime outlives the stack frame where the borrow happens. One solution, since your function already relies on the `Node`s being managed (they're stored via `@mut` pointers) is to pass around `@mut Node`s rather than `&'r mut Node`s. There's no loss of generality, since your code already requires that the pointers be managed. On Mon, Apr 29, 2013 at 9:08 AM, Ryan Hyun Choi <ryan.c...@samsung.com>wrote: > Dear all, > > I come across an error message that I do not know how to fix it. I have a > tree, and I would like to have a function that returns > a node in a tree. Here's the data structure: > > struct Node { > name: ~str, > children: ~[@mut Node] > } > > This is a simplified search function. I would like to find a node whose > name is the same as tag. > > fn findTreeNode<'r>(node: &'r mut Node, tag: &~str) -> Option<&'r mut > Node> { > if node.name == *tag { > return Some(node); > } > else { > let childNode = node.children[0]; > let candNode = findTreeNode(childNode, tag); > return candNode; > } > } > > The error message that I got is > > error: illegal borrow: cannot root managed value long enough > succinct.rs:777 let candNode = findTreeNode(childNode, tag); > ^~~~~~~~~ > succinct.rs:768:76: 792:1 note: managed value would have to be rooted for > the lifetime &'r as defined on the block at 768:76... > succinct.rs:768:76: 792:1 note: ...but can only be rooted for the block > at 768:76 > > > 1. Could you kindly explain to me what the error message mean, and how to > fix it? > > > Addionally, I would like to have the follow code in the else statement. > > for uint::range(0, vec::len(node.children)) |i| { > let childNode = node.children[i]; > // check whether the node in the Option() struct is valid > // if valid, wrap the node in Option(), and return it > // else continue the for loop > } > > Here's my attempt: > > for uint::range(0, vec::len(node.children)) |i| { > let childNode = node.children[0]; > let candNode = findTreeNode(childNode, tag); > > let mut found = match candNode { > Some(c) => { > true > } > None => { > false > } > }; > if found { > return candNode; > } > } > return None; > > And the error message that I get is: > > succinct.rs:788:23: 788:31 error: use of moved value: `candNode` > succinct.rs:788 return candNode; > ^~~~~~~~ > succinct.rs:779:34: 779:42 note: `candNode` moved here because it has > type core::option::Option<&'r mut Node>, which is moved by default (use > `copy` to override) > succinct.rs:779 let mut found = match candNode { > > > 2. Could you kindly explain to me how to fix this error? > Any help would be much appreciated. Thank you a lot. > > Best regards, > Ryan > > --------- > appendix: this is how the tree is built. Tree is built using a stack. > > fn build(tag: &str, stack: &mut ~[@mut Node]) { > let node = @mut Node{name: str::from_slice(tag), children: ~[]}; > if stack.is_empty() { > stack.push(node); > } > else { > let mut parent = stack.pop(); > parent.children.push(node); > stack.push(parent); > stack.push(node); > } > } > > Tree is built successfully. > > ---- > 최현 / Ryan Hyun Choi > Senior Engineer > Web Platform Lab. > Software R&D Center > Samsung Electronics Co., Ltd > email: ryan.c...@samsung.com > _______________________________________________ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev >
_______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev