Skip to content

Changing async function body causes caller to fail #116048

Open
@TylerHorth

Description

@TylerHorth

Full reproducible example.

use std::{future::Future, pin::Pin};
use hyper::{Client, client::HttpConnector, Request};
use tower::ServiceExt;

struct MyClient<'a>(&'a Client<HttpConnector>);

impl<'a> MyClient<'a> {
    async fn send(&mut self) {
        (&mut self.0).oneshot(Request::default()).await;
       // ^^^ Remove this line and foo() compiles
    }
}

fn foo() -> Pin<Box<dyn Future<Output = ()> + Send>> {
    Box::pin(async move {
        let http_client = Client::new();
        let mut my_client = MyClient(&http_client);
        my_client.send().await;
    })
    // ^^^ error: implementation of `Service` is not general enough
    // note: `Service<hyper::Request<Body>>` would have to be implemented for the type `&'0 Client<HttpConnector>`, for any lifetime `'0`...
    // note: ...but `Service<hyper::Request<Body>>` is actually implemented for the type `&'1 Client<HttpConnector>`, for some specific lifetime `'1`
}

I expected to see this happen: The above code should compile.

Instead, this happened: The body of send causes a compile error inside its caller foo. This should not be possible as it would make changing the body of a method potentially a breaking change.

I think this may be related to #110338 as removing the Send bound from foo is enough to make the code compile.

Compile Error

   Compiling rustc-bug-repo v0.1.0 (/Users/thorth/IdeaProjects/rustc-bug-repo)
error: implementation of `Service` is not general enough
  --> src/lib.rs:16:5
   |
16 | /     Box::pin(async move {
17 | |         let http_client = Client::new();
18 | |         let mut my_client = MyClient(&http_client);
19 | |         my_client.send().await;
20 | |     })
   | |______^ implementation of `Service` is not general enough
   |
   = note: `Service<hyper::Request<Body>>` would have to be implemented for the type `&'0 Client<HttpConnector>`, for any lifetime `'0`...
   = note: ...but `Service<hyper::Request<Body>>` is actually implemented for the type `&'1 Client<HttpConnector>`, for some specific lifetime `'1`

error: could not compile `rustc-bug-repo` (lib) due to previous error

Meta

rustc --version --verbose:

rustc 1.74.0-nightly (3223b0b5e 2023-09-20)
binary: rustc
commit-hash: 3223b0b5e8dadda3f76c3fd1a8d6c5addc09599e
commit-date: 2023-09-20
host: aarch64-apple-darwin
release: 1.74.0-nightly
LLVM version: 17.0.0
Backtrace

N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-auto-traitsArea: auto traits (e.g., `auto trait Send {}`)AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions