Skip to content

[NLL] Dropck is too permissive for generators #49918

Closed
@matthewjasper

Description

@matthewjasper

Code shows a case where y doesn't stay borrowed for long enough allowing it to be mutated while a reference to it exists. I think treating generators as if they implement Drop would fix this, but I'm not sure if this will end up causing incorrect errors in other places.

#![feature(nll)]
#![feature(generators, generator_trait)]

use std::ops::{GeneratorState, Generator};

struct SetToNone<'a: 'b, 'b>(&'b mut Option<&'a i32>);

impl<'a, 'b> Drop for SetToNone<'a, 'b> {
    fn drop(&mut self) {
        *self.0 = None;
    }
}

fn drop_using_generator() -> i32 {
    let mut y = Some(&0);
    let z = &mut y;
    let r;
    {
        let mut g = move || { let _s = SetToNone(z); yield; };
        unsafe { g.resume() }; // documented as unsafe only because of unmovable closures.
        r = y.as_ref().unwrap();
    } // y is set to 'null' here
    **r // Segmentation fault
}

fn main() {
    println!("{}", drop_using_generator());
}

Metadata

Metadata

Assignees

Labels

A-NLLArea: Non-lexical lifetimes (NLL)A-coroutinesArea: CoroutinesNLL-soundWorking towards the "invalid code does not compile" goal

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions