Skip to content

Superfluous errors for missing lifetime in async function argument #76938

@djc

Description

@djc

In the example below (which is a little convoluted -- sorry, I already spent quite a bit reducing it), I'm getting what amounts to three compiler errors. But, when I fix the cause of the first error by applying the suggested fix, the other two errors go away. It feels like the compiler could be smarter about this and only throw the first diagnostic.

I tried this code:

use futures::stream::FuturesUnordered;
use http::Response;
use hyper::body::Body;

pub(crate) mod name {
    use super::*;
    pub(crate) async fn handler(cx: Context) -> Result<Response<Body>, ()> {
        let app = &cx.app;
        let name = cx.s();
        let query = cx.query();
        call(app, name, query).await
    }
    pub(crate) async fn call(app: &App, name: &str, query: Query) -> Result<Response<Body>, ()> {
        let stream = FuturesUnordered::new();
        stream.push(async move { Ok::<_, serde_json::Error>(format!("{}", true).into_bytes()) });
        Ok(Response::builder().body(Body::wrap_stream(stream)).unwrap())
    }
}

struct Context {
    app: App,
    s: String,
}

struct App {}

impl Context {
    fn s(&self) -> &str {
        &self.s
    }
    fn query(&self) -> Query {
        Query { s: &self.s }
    }
}

struct Query<'a> {
    s: &'a str,
}

(Playground.)

This is the compiler output I got:

error[E0726]: implicit elided lifetime not allowed here
  --> src/lib.rs:16:16
   |
16 |         query: Query,
   |                ^^^^^- help: indicate the anonymous lifetime: `<'_>`

error[E0597]: `cx` does not live long enough
  --> src/lib.rs:10:21
   |
10 |         let query = cx.query();
   |                     ^^--------
   |                     |
   |                     borrowed value does not live long enough
   |                     argument requires that `cx` is borrowed for `'static`
11 |         call(app, name, query).await
12 |     }
   |     - `cx` dropped here while still borrowed

error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
  --> src/lib.rs:17:10
   |
17 |     ) -> Result<Response<Body>, ()> {
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: hidden type `impl futures::Future` captures lifetime smaller than the function body
  --> src/lib.rs:17:10
   |
17 |     ) -> Result<Response<Body>, ()> {
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^

I expected to see this happen: it would be nice if I only got the first error (E0726). It seems like the compiler is substituting some placeholder lifetime in place of the missing lifetime which is making things worse, causing the two other errors. It seems reasonable to replace missing lifetimes with '_ instead (especially if that's the suggested fix anyway) instead, which would make the other errors go away and makes it easier to focus on the actual problem. For this particular case, I also find the second and third error highly opaque and not very actionable.

Meta

The same thing happens on both current stable (1.46.0) and latest nightly (rustc 1.48.0-nightly bbc6774 2020-09-18).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.D-verboseDiagnostics: Too much output caused by a single piece of incorrect code.S-needs-reproStatus: This issue has no reproduction and needs a reproduction to make progress.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions