Skip to content

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

@compiler-errors

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.

Metadata

Metadata

Labels

A-async-awaitArea: Async & AwaitA-borrow-checkerArea: The borrow checkerC-bugCategory: This is a bug.I-prioritizeIssue: Indicates that prioritization has been requested for this issue.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessS-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