Skip to content

Generator state borrowings should have same as generator lifetime #47654

Closed
@andreytkachenko

Description

@andreytkachenko

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 | | }
   | |_^

Activity

andreytkachenko

andreytkachenko commented on Jan 22, 2018

@andreytkachenko
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.

andreytkachenko

andreytkachenko commented on Jan 23, 2018

@andreytkachenko
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

andreytkachenko commented on Jan 24, 2018

@andreytkachenko
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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-coroutinesArea: CoroutinesC-feature-requestCategory: A feature request, i.e: not implemented / a PR.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @TimNN@andreytkachenko

        Issue actions

          Generator state borrowings should have same as generator lifetime · Issue #47654 · rust-lang/rust