rust - Cannot borrow `x` as mutable more than once at a time -
in following code (playground):
struct node { datum: &'static str, edges: vec<node>, } fn add<'a>(node: &'a mut node, data: &'static str) -> &'a node { node.edges .push(node { datum: data, edges: vec::new(), }); &node.edges[node.edges.len() - 1] // return added 1 } fn traverse<f>(root: &node, callback: &f) f: fn(&'static str) { callback(root.datum); node in &root.edges { traverse(node, callback); } } fn main() { let mut tree = node { datum: "start", edges: vec::new(), }; let lvl1 = add(&mut tree, "level1"); traverse(&mut tree, &|x| println!("{:}", x)); //i don't need mutability here } i have kind of error:
error[e0499]: cannot borrow `tree` mutable more once @ time --> src/main.rs:32:19 | 30 | let lvl1 = add(&mut tree, "level1"); | ---- first mutable borrow occurs here 31 | 32 | traverse(&mut tree, &|x| println!("{:}", x)); //i don't need mutability here | ^^^^ second mutable borrow occurs here 33 | } | - first borrow ends here my question seems similar why rust want borrow variable mutable more once @ time?, i'm not sure. if so, there workaround case?
this happens because of how add defined:
fn add<'a>(node: &'a mut node, data : &'static str) -> &'a node here specified lifetime of resulting reference should equal lifetime of incoming reference. only way possible (except unsafe code) resulting reference somehow derived incoming reference, example, references field inside object incoming reference points at:
struct x { a: u32, b: u32 } fn borrow_a<'a>(x: &'a mut x) -> &'a mut u32 { &mut x.a } however, there no way compiler know what exactly incoming structure borrowed looking @ function signature (which, in general, thing can when compiling code uses function). therefore, can't know following code technically correct:
let mut x = x { a: 1, b: 2 }; let = borrow_a(&mut x); let b = &mut x.b; we know a , b disjoint because point @ different parts of structure, compiler can't know because there nothing in borrow_a signature suggest (and there can't be, rust not support it).
therefore, sensible thing compiler consider the whole x borrowed until reference returned borrow_a() dropped. otherwise possible create 2 mutable references same data, violation of rust aliasing guarantees.
note following code correct:
let mut x = x { a: 1, b: 2 }; let = &mut x.a; let b = &mut x.b; here compiler can see a , b never point same data, though point inside of same structure.
so, there no workaround this, , solution restructure code doesn't have such borrowing patterns.
Comments
Post a Comment