Skip to content

MIR generation for generators considers any borrowed or assigned value as live across yield points #94067

@eholk

Description

@eholk

Consider an example such as this:

impl Agent {
    async fn handle(&mut self) {
        let mut info = self.info_result.clone();
        info.node = None;
        let element = parse_info(info);
        let _ = send_element(element).await;
    }
}

fn parse_info(_: Info) -> Element { ... }

fn foo(agent: Agent) {
    assert_send(agent.handle());
    //~^ cannot be sent between threads safely
}

Let's assume info is !Send. The future returned from handle is currently !Send as well, because the MIR generation for the generator considers info to be live across the await point, despite the fact that info is consumed by parse_info. The reason is because the generator step explicitly considers any borrowed local as live across the suspend point.

With the more precise drop tracking in the type checker, it would be nice not to have to capture these at the MIR level. Currently drop tracking has to be more conservative than necessary in order to match the MIR behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlA-borrow-checkerArea: The borrow checkerA-coroutinesArea: CoroutinesC-enhancementCategory: An issue proposing an enhancement or a PR with one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions