Skip to content

Coroutine upvars are not required to be live in borrowck if witness has no drop requirements #144155

Description

@compiler-errors

I tried this code:

struct NeedsDrop<'a>(&'a Vec<i32>);

impl Drop for NeedsDrop<'_> {
    fn drop(&mut self) {
        println!("dropping {:#?}", self.0);
    }
}

async fn await_point() {}

fn main() {
    let v = vec![1, 2, 3];
    let x = NeedsDrop(&v);
    let c = async {
        std::future::ready(()).await;
        drop(x);
    };
    drop(v);
}

I expected it to fail, since dropping the coroutine c requires that NeedsDrop's 'a lifetime is live, since dropping the coroutine also performs a drop of NeedsDrop (as an upvar).

Instead, it compiled. This is UB.

This fails on rustc as of nightly 2025-07-18. Not sure if this has either always been incorrect, or if this was introduced due to the fix in #117134.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

A-async-awaitArea: Async & AwaitA-borrow-checkerArea: The borrow checkerC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-criticalCritical priorityS-has-bisectionStatus: A bisection has been found for this issue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions