The simplest thing to do is probably to build an intermediate vector of 
vertices to insert and then push them all after you are done iterating over the 
edges.

Cameron

> On Jun 1, 2014, at 12:48 PM, Nicholas Bishop <[email protected]> wrote:
> 
> I'm looking for a little borrow-checker advice. Here's a reasonably
> minimal program that demonstrates the problem:
> 
> extern crate collections;
> 
> use collections::HashMap;
> 
> struct G {
>   verts: HashMap<int, String>,
>   edges: Vec<(int, int)>,
> 
>   next_vert_id: int
> }
> 
> impl G {
>   fn new() -> G {
>       G{verts: HashMap::new(), edges: Vec::new(), next_vert_id: 0}
>   }
> 
>   fn add_vert(&mut self, s: &str) -> int {
>       let id = self.next_vert_id;
>       self.next_vert_id += 1;
>       self.verts.insert(id, String::from_str(s));
>       id
>   }
> 
>   fn add_edge(&mut self, v0: int, v1: int) {
>       self.edges.push((v0, v1))
>   }
> }
> 
> fn main() {
>   let mut g = G::new();
> 
>   {
>       let v0 = g.add_vert("vert 0");
>       let v1 = g.add_vert("vert 1");
>       g.add_edge(v0, v1);
>   }
> 
>   for &(v0, v1) in g.edges.iter() {
>       g.add_vert("edge vert");
>   }
> }
> 
> This fails to compile:
> $ rust-nightly-x86_64-unknown-linux-gnu/bin/rustc -v
> rustc 0.11.0-pre-nightly (064dbb9 2014-06-01 00:56:42 -0700)
> host: x86_64-unknown-linux-gnu
> 
> $ rust-nightly-x86_64-unknown-linux-gnu/bin/rustc graph.rs
> graph.rs:39:9: 39:10 error: cannot borrow `g` as mutable because
> `g.edges` is also borrowed as immutable
> graph.rs:39         g.add_vert("edge vert");
>                   ^
> graph.rs:38:22: 38:29 note: previous borrow of `g.edges` occurs here;
> the immutable borrow prevents subsequent moves or mutable borrows of
> `g.edges` until the borrow ends
> graph.rs:38     for &(v0, v1) in g.edges.iter() {
>                                ^~~~~~~
> graph.rs:41:2: 41:2 note: previous borrow ends here
> graph.rs:38     for &(v0, v1) in g.edges.iter() {
> graph.rs:39         g.add_vert("edge vert");
> graph.rs:40     }
> graph.rs:41 }
>           ^
> error: aborting due to previous error
> 
> My understanding of the error is: G::add_vert is being given a mutable
> reference to "g", which means it could do something naughty like clear
> g.edges, which would screw up the loop iteration that is happening in
> main().
> 
> That seems like a pretty reasonable thing to prevent, but it's not
> clear to me how I should restructure the program to work around the
> error. In this minimal example I could copy the code out of
> G::add_vert and stick it directly inside the loop, but that's clearly
> not the general solution.
> 
> Thanks,
> -Nicholas
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to