Open
Description
The code below doesn't compile due to multiple mutable borrows, however the exact same code without the std::pin::Pin
compiles fine actually. My expectation is however that the code would obviously compile fine in both cases.
use std::pin::Pin;
use slab;
struct Entry {
complete: u64
}
struct Ctx {}
impl Ctx {
fn new() -> Self {
Ctx{}
}
fn pread<T>(&mut self, _key: T) -> std::io::Result<()> {
Ok(())
}
}
struct Foo {
ctx: Ctx,
handles: slab::Slab<Entry>
}
impl Foo {
fn new() -> Self {
Foo {ctx: Ctx::new(),
handles: slab::Slab::with_capacity(20)}
}
fn blah(mut self: Pin<&mut Self>) {
let v = self.handles.vacant_entry();
let key = v.key();
match self.ctx.pread(key) {
Ok(()) => {
v.insert(Entry{complete:123});
},
Err(_) => {
}
}
}
}
fn main() {
Pin::new(&mut Foo::new()).blah();
}
The exception raised is:
error[E0499]: cannot borrow `self` as mutable more than once at a time
--> src/main.rs:31:15
|
29 | let v = self.handles.vacant_entry();
| ---- first mutable borrow occurs here
30 | let key = v.key();
31 | match self.ctx.pread(key) {
| ^^^^ second mutable borrow occurs here
32 | Ok(()) => {
33 | v.insert(Entry{complete:123});
| - first borrow later used here
error: aborting due to previous error
I'm able to get the code to compile also by creating additional scopes around the areas where I'm supposedly borrowing self
like this:
let key = {
let entry = self.handles.vacant_entry();
entry.key()
};
match self.ctx.pread(key) {
Ok(()) => {
*self.handles.get_mut(key).unwrap() =
Entry { complete: 123 };
}
Although obviously that's pretty awkward. I'm told that this could possibly be a bug in the NLL, but I'm pretty new to the language so I'm just reporting this with a short reproducible example.
Hope it helps.