#"borrowed data escapes outside of closure" when moving closure into closure.

9 messages · Page 1 of 1 (latest)

vocal moss
#

Lifetimes arent my strong suit, and I dont really get what the error is saying, I have tried playing with the bounds, but I just cant seem to find a solution that compiles.
(this is part of a more complex system, but this shows the error) ```rust
struct NonCopy;
struct Hello(NonCopy);
struct Guard<F>(F);

impl<F> Guard<F> {
fn new<'a, C, R>(func: F) -> Self
where
F: Fn(&'a C) -> R,
C: 'a,
R: 'a,
{
Self(func)
}
}

impl Hello {
fn get<'a, F, R>(&'a self, guard: &Guard<F>) -> R
where
F: Fn(&'a Self) -> R,
R: 'a,
{
(guard.0)(self)
}
}

fn main() {
let x = Guard::new(|hello: &Hello| &hello.0);

let _z = move |hello: &Hello| {
    let _res = hello.get(&x);
};

}

```rust
error[E0521]: borrowed data escapes outside of closure
  --> src/main.rs:30:20
   |
27 |     let x = Guard::new(|hello: &Hello| &hello.0);
   |         - `x` declared here, outside of the closure body
28 |
29 |     let _z = move |hello: &Hello| {
   |                    ----- `hello` is a reference that is only valid in the closure body
30 |         let _res = hello.get(&x);
   |                    ^^^^^^^^^^^^^ `hello` escapes the closure body here

I am not really sure where its "escaping"? I dont return the result of the get call, and I thought the lifetime bounds were correct.
The only examples I get of this error when googling is stuff like pushing into a vec outside the closure, which I get, but I thought i was moveing the guard into the closure? and the closure isnt even storing the value.

#

and if I try to force move it in with ```rust
let _z = move |hello: &Hello| {
let x = x;
let _res = hello.get(&x);
};

I get a even more confussing error ```rust
error[E0521]: borrowed data escapes outside of closure
  --> src/main.rs:30:17
   |
27 |     let x = Guard::new(|a: &Hello| &a.0);
   |         - `x` declared here, outside of the closure body
28 |
29 |     let _z = move |hello: &Hello| {
   |                    ----- `hello` is a reference that is only valid in the closure body
30 |         let x = x;
   |                 ^ `hello` escapes the closure body here
atomic raptor
vocal moss
atomic raptor
#

I'm unsure. My best guess is that the compiler is unable to reason about what's happening here as a closure.

#

We get a more clear error

#

It can't tell that the lifetime of &NonCopy is the same as the lifetime of &Hello

#

As a function, the compiler can tell