0

I would like to store a callback/closure, but when I try the following reduced code:

trait Stream<F> {
    fn set_cb(&mut self, f: F)
        where F: Fn(&Stream<F>);
}

pub struct SomeStream<F> {
    cb: Option<F>,
}

impl<F> Stream<F> for SomeStream<F> {
    fn set_cb(&mut self, f: F)
        where F: Fn(&Stream<F>)
    {
        self.cb = Some(f)
    }
}

fn main() {
    let ss = SomeStream { cb: None };
    let cb = |stream| {};
    ss.set_cb(cb);
}

I get the following error:

error: type mismatch resolving `for<'r> <[closure] as core::ops::FnOnce<(&'r Stream<[closure]> + 'r,)>>::Output == ()`:
 expected bound lifetime parameter ,
    found concrete lifetime [E0271]
         ss.set_cb(cb);
            ^~~~~~
help: see the detailed explanation for E0271

error: type mismatch: the type `[closure]` implements the trait `core::ops::Fn<(_,)>`, but the trait `for<'r> core::ops::Fn<(&'r Stream<[closure]> + 'r,)>` is required (expected concrete lifetime, found bound lifetime parameter ) [E0281]
         ss.set_cb(cb);
            ^~~~~~

I didn't specify any lifetime parameters. What's wrong here? Should I wrap the closure in a Box?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Ivan Baidakou
  • 713
  • 9
  • 14
  • Short answer: pass the closure inline instead of storing it in a variable, there is a difference in how things are inferred. Potential duplicate of http://stackoverflow.com/q/36415348/155423. See also http://stackoverflow.com/q/37528394/155423 – Shepmaster Jun 19 '16 at 18:41
  • Thank you! Could you, please, provide some link to documentation? I would like to have an long answer, if it is possible. Anyway, you advice works – Ivan Baidakou Jun 19 '16 at 20:25
  • All the documentation I know about I've added to the linked duplicate :-) – Shepmaster Jun 19 '16 at 20:47

0 Answers0