Amanieu / intrusive-rs

Intrusive collections for Rust
Apache License 2.0
400 stars 47 forks source link

It's not possible to make multiple inserts through cursor at the same scope #9

Closed sergeyfedotov closed 7 years ago

sergeyfedotov commented 7 years ago
let mut cur = self.events.front_mut();
cur.insert(Box::new(EventNode::new(OneRootPoint::new(0, 0))));
cur.insert(Box::new(EventNode::new(OneRootPoint::new(0, 0))));
error[E0499]: cannot borrow `cur` as mutable more than once at a time
   --> src/sweep_line/mod.rs:109:9
    |
108 |         cur.insert(Box::new(EventNode::new(OneRootPoint::new(0, 0))));
    |         --- first mutable borrow occurs here
109 |         cur.insert(Box::new(EventNode::new(OneRootPoint::new(0, 0))));
    |         ^^^ second mutable borrow occurs here
...
121 |     }
    |     - first borrow ends here

Are there any reasons to specify insert method with the same lifetime as for CursorMut itself?

https://github.com/Amanieu/intrusive-rs/blob/70fef1fe156cdd5035d78e37c12fbf614999e0c4/src/rbtree.rs#L787

Amanieu commented 7 years ago

Hmm, that is a good point. Does changing &'a mut self to &mut self fix this problem? It should be safe.

Amanieu commented 7 years ago

Note that in your example, you can just call self.events.insert() directly, without going through a cursor.

Amanieu commented 7 years ago

I had a look at the implementation of CursorMut::insert. It might be possible to make it work, but it would require using unsafe code and I am not sure if the code will remain sound.

sergeyfedotov commented 7 years ago

Note that in your example, you can just call self.events.insert() directly, without going through a cursor.

Actually I want to insert the items inside the loop like this:

let mut cur = self.events.front_mut();
loop {
    match cur.get() {
        Some(_) => {
            // ...
            cur.insert(Box::new(EventNode::new(OneRootPoint::new(x, y))));
        },
        _ => break,
    }
    cur.move_next();
}

Is this a possible use case?

Amanieu commented 7 years ago

Fixed in 0.6.3

sergeyfedotov commented 7 years ago

Thanks!