Closed
Description
This code does not work very unexpectedly:
#![feature(unboxed_closures)]
struct Parser<I, O> {
parse: Box<FnMut<(I,), Result<O, String>>>
}
impl<I, O:'static> Parser<I, O> {
fn compose<K>(mut self, mut rhs: Parser<O, K>) -> Parser<I, K> {
Parser {
parse: box |&mut: x: I| {
match self.parse.call_mut((x,)) {
Ok(r) => rhs.parse.call_mut((r,)),
Err(e) => Err(e)
}
}
}
}
}
The error:
<anon>:11:23: 11:33 error: cannot borrow data mutably in an aliasable location
<anon>:11 match self.parse.call_mut((x,)) {
^~~~~~~~~~
<anon>:12:30: 12:39 error: cannot borrow data mutably in an aliasable location
<anon>:12 Ok(r) => rhs.parse.call_mut((r,)),
^~~~~~~~~
error: aborting due to 2 previous errors
When I expand this manually, I can get it to work:
#![feature(unboxed_closures)]
struct Parser<I, O> {
parse: Box<FnMut<(I,), Result<O, String>>>
}
impl<I, O:'static> Parser<I, O> {
fn compose<K>(self, rhs: Parser<O, K>) -> Parser<I, K> {
struct ManualClosure<I, O, K> {
this: Parser<I, O>,
rhs: Parser<O, K>
}
impl<I, O, K> FnMut<(I,), Result<K, String>> for ManualClosure<I, O, K> {
extern "rust-call" fn call_mut(&mut self, arg: (I,)) -> Result<K, String> {
match self.this.parse.call_mut(arg) {
Ok(r) => self.rhs.parse.call_mut((r,)),
Err(e) => Err(e)
}
}
}
Parser { parse: box ManualClosure { this: self, rhs: rhs } }
}
}
Though for some reason completely opaque to me I need to put 'static
bound on O
parameter, otherwise there is a compilation error:
<anon>:23:25: 23:67 error: value may contain references; add `'static` bound to `O` [E0149]
<anon>:23 Parser { parse: box ManualClosure { this: self, rhs: rhs } }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
The original problem came from here.