1

Consider the following code:

pub fn use_r<I, R>(xs: I, r: &R) {
    unimplemented!()
}

fn test<'a, R>(r: &'a mut R) {
    let a = |r: &'a mut R| {
        [(|| use_r(vec![0.].into_iter(), r))()]
    };
    a(r);
    // a(r);
}

fn test2<R>(r: &mut R) {
    let a = |r: &mut R| {
        [(|| use_r(vec![0.].into_iter(), r))()]
    };
    a(r);
    a(r);
}

Rust Playground

test compiles with the latest nightly, but I cannot call a(r); twice. test2 compiles with stable and does what I want, but it does not compile on nightly.

The motivation is that I have a RNG which I want to pass into an internal closure a few different times. What do I need to do to allow test2 to compile?

yong
  • 3,583
  • 16
  • 32

1 Answers1

1

I'm not sure why the compiler doesn't accept your test2 function. It compiles fine if you eliminate the unnecessary nested lambda:

fn test2<R>(r: &mut R) {
    let a = |r: &mut R| {
        [use_r(vec![0.].into_iter(), r)]
    };
    a(r);
    a(r);
}

I also found that the compiler accepts the code if you use a shared reference with explicit lifetime:

fn test2<'a, R>(r: &'a mut R) {
    let a = |r: &'a R| {
        [(|| use_r(vec![0.].into_iter(), r))()]
    };
    a(r);
    a(r);
}

I'm not sure why it doesn't work with a &mut reference, or why the compiler can't infer the lifetime automatically.

Do you really have an unnecessary (immediately invoked) nested lambda? I suspect you simplified the code too much and are asking a different question than you meant to ask.

Daniel
  • 15,944
  • 2
  • 54
  • 60
  • Yes, I do in fact have a nested lambda that I immediately invoke :(. The reason is that I want to pass a code fragment to a inlining macro, which works by calling the lambda. – yong Jan 10 '16 at 18:45