Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function leaks passed closure, even if lifetimes are declared to be independent #102848

Closed
ISibboI opened this issue Oct 9, 2022 · 3 comments
Closed
Labels
C-bug Category: This is a bug.

Comments

@ISibboI
Copy link

ISibboI commented Oct 9, 2022

(continuing from users.rust-lang.org)

I tried this code:

// the compiler thinks that the closure could be returned by by this function
// to me, the function signature indicates that the closure and the return value are independent
fn calls_closure<'closure, 'result>(
    closure: impl 'closure + FnOnce() -> (),
) -> impl 'result + Iterator<Item = i32> {
    closure();
    [2].into_iter()
}

fn creates_closure<'closure_state, 'result>(
    closure_state: &'closure_state mut i32,
) -> impl 'result + Iterator<Item = i32> {
    calls_closure(|| {
        *closure_state += 1;
    })
}

(playground)

I expected to see this happen: it should compile and run just fine. The lifetimes 'closure and 'result of function calls_closure are not related by any bounds.

Instead, this happened:

error: lifetime may not live long enough
  --> src/lib.rs:13:5
   |
10 |   fn creates_closure<'closure_state, 'result>(
   |                      --------------  ------- lifetime `'result` defined here
   |                      |
   |                      lifetime `'closure_state` defined here
...
13 | /     calls_closure(|| {
14 | |         *closure_state += 1;
15 | |     })
   | |______^ function was supposed to return data with lifetime `'result` but it is returning data with lifetime `'closure_state`
   |
   = help: consider adding the following bound: `'closure_state: 'result`

For some reason, the compiler thinks that calls_closure can return something with a lifetime related to that of the passed closure. But the lifetimes 'closure and 'result are unrelated in its signature.

On nightly, the error message is different, but still seems wrong:

error[E0700]: hidden type for `impl Iterator<Item = i32>` captures lifetime that does not appear in bounds
  --> src/lib.rs:13:5
   |
10 |   fn creates_closure<'closure_state, 'result>(
   |                      -------------- hidden type `impl Iterator<Item = i32>` captures the lifetime `'closure_state` as defined here
...
13 | /     calls_closure(|| {
14 | |         *closure_state += 1;
15 | |     })
   | |______^
   |
help: to declare that the `impl Trait` captures `'closure_state`, you can add an explicit `'closure_state` lifetime bound
   |
12 | ) -> impl 'result + Iterator<Item = i32> + 'closure_state {
   |                                          ++++++++++++++++

For more information about this error, try `rustc --explain E0700`.

Meta

rustc --version --verbose:
stable from playground: 1.64.0
nightly from playground: 1.66.0-nightly (2022-10-08 8796e7a)

@ISibboI ISibboI added the C-bug Category: This is a bug. label Oct 9, 2022
@nagisa
Copy link
Member

nagisa commented Oct 9, 2022

This looks like a duplicate of #79415?

@ISibboI
Copy link
Author

ISibboI commented Oct 10, 2022

I think so, yes. Over there they also found an even simpler example.

@nagisa
Copy link
Member

nagisa commented Oct 10, 2022

Duplicate of #79415

@nagisa nagisa closed this as completed Oct 10, 2022
@nagisa nagisa marked this as a duplicate of #79415 Oct 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

2 participants