- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
Closed
Labels
A-closuresArea: Closures (`|…| { … }`)Area: Closures (`|…| { … }`)E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.
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.
Metadata
Metadata
Assignees
Labels
A-closuresArea: Closures (`|…| { … }`)Area: Closures (`|…| { … }`)E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.