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

Generator state borrowings should have same as generator lifetime #47654

Closed
andreytkachenko opened this issue Jan 22, 2018 · 3 comments
Closed
Labels
A-coroutines Area: Coroutines C-feature-request Category: A feature request, i.e: not implemented / a PR.

Comments

@andreytkachenko
Copy link

andreytkachenko commented Jan 22, 2018

Consider the example:

#![feature(generators, conservative_impl_trait, generator_trait)]
use std::ops::Generator;

fn test<'a>(val: u32) -> impl Generator<Yield = u32, Return = u32> + 'a {
    move || {             // returned generator state has lifetime 'a
        let mut x = val;  // variable x is in the generator state and, hence, it has lifetime 'a
        let y = &mut x;   // but y, (which pointing to x with lifetime 'a) doesn't have lifetime 'a

        yield 1;
        *y += 1;
        yield 2;
        *y += 1;
        yield 3;

        return *y;
    }
}

fn main() {
    let mut gen = test(1);
    
    println!("{:?}", gen.resume());
    println!("{:?}", gen.resume());
    println!("{:?}", gen.resume());
    println!("{:?}", gen.resume());
}

it won't compile with error:

error[E0597]: `x` does not live long enough
  --> src/main.rs:8:22
   |
8  |         let y = &mut x;
   |                      ^ borrowed value does not live long enough
...
22 |     }
   |     - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 5:1...
  --> src/main.rs:5:1
   |
5  | / fn test<'a>(val: u32) -> impl Generator<Yield = u32, Return = u32> + 'a {
6  | |     move || {
7  | |         let mut x = val;
8  | |         let y = &mut x;
...  |
22 | |     }
23 | | }
   | |_^
@andreytkachenko
Copy link
Author

I am sure that it is possible despite that generator may be moved and it actual address will change. Maybe create some sort of virtual pointers, which will be dependent on struct base address and rust will have vtable for derefecencing such pointers at runtime. On each struct move new address will be updated in such table.

@TimNN TimNN added C-feature-request Category: A feature request, i.e: not implemented / a PR. A-coroutines Area: Coroutines labels Jan 23, 2018
@andreytkachenko
Copy link
Author

The best solution for that problem, by my mind, is to track, on compile time, the generator state, and fail compilation when it will be moved while there are some references pointing to it part. Very similar how rust tracking the variables.

@andreytkachenko
Copy link
Author

Has to be fixed by #45337

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-coroutines Area: Coroutines C-feature-request Category: A feature request, i.e: not implemented / a PR.
Projects
None yet
Development

No branches or pull requests

2 participants