Skip to content

impl-trait return type is bounded by all input type parameters, even when unnecessary #42940

Open
@Arnavion

Description

rustc 1.20.0-nightly (f590a44ce 2017-06-27)
binary: rustc
commit-hash: f590a44ce61888c78b9044817d8b798db5cd2ffd
commit-date: 2017-06-27
host: x86_64-pc-windows-msvc
release: 1.20.0-nightly
LLVM version: 4.0
trait Future {}

impl<F> Future for Box<F> where F: Future + ?Sized {}

struct SomeFuture<'a>(&'a Client);
impl<'a> Future for SomeFuture<'a> {}

struct Client;
impl Client {
    fn post<'a, B>(&'a self, _body: &B) -> impl Future + 'a /* (1) */ {
        SomeFuture(self)
    }
}

fn login<'a>(client: &'a Client, username: &str) -> impl Future + 'a {
    client.post(&[username])
}

fn main() {
    let client = Client;
    let _f = {
        let username = "foo".to_string();
        login(&client, &username)
    };
}

Since SomeFuture borrows 'a Client, I'd expect impl Future + 'a to be the correct return type, but it gives this error:

error[E0700]: hidden type for `impl Future + 'a` captures lifetime that does not appear in bounds
  --> src/main.rs:16:5
   |
15 | fn login<'a>(client: &'a Client, username: &str) -> impl Future + 'a {
   |                                            ----     ---------------- opaque type defined here
   |                                            |
   |                                            hidden type `impl Future + 'a` captures the anonymous lifetime defined here
16 |     client.post(&[username])
   |     ^^^^^^^^^^^^^^^^^^^^^^^^
   |
help: add a `use<...>` bound to explicitly capture `'_`
   |
15 | fn login<'a>(client: &'a Client, username: &str) -> impl Future + 'a + use<'a, '_> {
   |                                                                      +++++++++++++

  • Changing _body to have an explicit lifetime like _body: &'b B where 'b is independent of 'a or where 'a: 'b does not change the error. This and the original error make it seem that returning an impl trait is somehow causing the _body parameter to get the 'a lifetime, even though it's clearly unused, let alone used in a way that it would require the 'a lifetime.

  • Changing (1) from impl Future + 'a to SomeFuture<'a> fixes it.

  • Changing (1) from impl Future + 'a to Box<Future + 'a> and returning Box::new(SomeFuture(self)) fixes it.

Metadata

Assignees

No one assigned

    Labels

    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-lifetimesArea: Lifetimes / regionsC-bugCategory: This is a bug.F-precise_capturing`#![feature(precise_capturing)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.WG-asyncWorking group: Async & await

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions