Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

returning a future from a function with an impl Trait argument references that argument even if not used in the future, causing lifetime errors #125341

Closed
pushrax opened this issue May 20, 2024 · 3 comments
Labels
A-impl-trait Area: impl Trait. Universally / existentially quantified anonymous types with static dispatch. A-lifetimes Area: lifetime related C-bug Category: This is a bug. F-precise_capturing `#![feature(precise_capturing)]` WG-async Working group: Async & await

Comments

@pushrax
Copy link

pushrax commented May 20, 2024

I minimized an error I encountered into this reproduction: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=85de243a39f64d49d42939066a2a824c

use std::future::Future;

fn fn2(_unused: impl AsRef<[u64]>) -> impl Future<Output = ()> {
    async move {}
}

fn fn1() -> impl Future<Output = ()> {
    let v = vec![1];
    fn2(&v)
}

#[tokio::main]
async fn main() {
    fn1().await;
}

This should compile.

Instead, this happened:

error[E0597]: `v` does not live long enough
  --> src/main.rs:9:9
   |
8  |     let v = vec![1];
   |         - binding `v` declared here
9  |     fn2(&v)
   |     ----^^-
   |     |   |
   |     |   borrowed value does not live long enough
   |     argument requires that `v` is borrowed for `'static`
10 | }
   | - `v` dropped here while still borrowed

The function argument is unused and it doesn't make sense that it should be borrowed for 'static.

If the impl AsRef<[u64]> argument is changed to &[u64] the snippet compiles fine. It seems like any impl Trait argument passed by value will cause the issue.

In the original non-minimized code, the argument wasn't unused, but only used outside the returned future.

Meta

repros on stable as well as latest nightly (1.80.0-nightly 2024-05-19 d84b903)

cc @morgangallant

@pushrax pushrax added the C-bug Category: This is a bug. label May 20, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 20, 2024
@jwong101
Copy link
Contributor

jwong101 commented May 20, 2024

This happens with any generic type parameter, since those are automatically captured by RPITs. This needs the precise capturing feature in order to compile.

Minimized:

fn capture<T>(_: T) -> impl Sized { }

fn ret() -> impl Sized {
    let u = 0;
    capture(&u)
}

@traviscross traviscross added A-lifetimes Area: lifetime related A-impl-trait Area: impl Trait. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. WG-async Working group: Async & await and removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels May 20, 2024
@traviscross
Copy link
Contributor

The analysis by @jwong101 is correct. Let's close this as a duplicate of:

Thanks to @pushrax for the report.

@traviscross traviscross added the F-precise_capturing `#![feature(precise_capturing)]` label May 20, 2024
@pushrax
Copy link
Author

pushrax commented May 20, 2024

Thanks for your help!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-impl-trait Area: impl Trait. Universally / existentially quantified anonymous types with static dispatch. A-lifetimes Area: lifetime related C-bug Category: This is a bug. F-precise_capturing `#![feature(precise_capturing)]` WG-async Working group: Async & await
Projects
None yet
Development

No branches or pull requests

4 participants