Skip to content

Generators requiring temporaries live too long #44257

New issue

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

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

Already on GitHub? # to your account

Closed
alexcrichton opened this issue Sep 1, 2017 · 3 comments
Closed

Generators requiring temporaries live too long #44257

alexcrichton opened this issue Sep 1, 2017 · 3 comments
Labels
A-coroutines Area: Coroutines C-bug Category: This is a bug.

Comments

@alexcrichton
Copy link
Member

This code:

fn foo() {
    use std::ops::{GeneratorState, Generator};

    || {
        let a = {
            let mut f = || {
                if false { yield }
                format!("a")
            };
            let a = loop {
                match f.resume() {
                    GeneratorState::Complete(e) => break e,
                    GeneratorState::Yielded(()) => {}
                }
                yield
            };
            a.len()
        };
        if false { yield }
        return a
    };
}

generates the error:

error[E0597]: `a` does not live long enough
   --> tests/smoke.rs:112:9
    |
111 |             a.len()
    |             - borrow occurs here
112 |         };
    |         ^ `a` dropped here while still borrowed
...
115 |     };
    |     - borrowed value needs to live until here

error: aborting due to previous error

but naively at least I'd expect it to work!

cc @Zoxc

@alexcrichton alexcrichton added the A-coroutines Area: Coroutines label Sep 1, 2017
@alexcrichton
Copy link
Member Author

This may or may not be the same as issues like #44197 or #44200

@arielb1
Copy link
Contributor

arielb1 commented Sep 3, 2017

This looks like #44200 :

fn foo() {
    use std::ops::{GeneratorState, Generator};

    || {
        let a = {
            let mut f = || {
                if false { yield }
                format!("a")
            };
            let a = loop {
                match f.resume() {
                    GeneratorState::Complete(e) => break e,
                    GeneratorState::Yielded(()) => {}
                }
                yield // [X] this yield
            };
            a.len() // [X] is caught up by this expression
        };
        if false { yield }
        return a
    };
}

@alex
Copy link
Member

alex commented Sep 22, 2017

This was fixed by #44392

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-coroutines Area: Coroutines C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

4 participants