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

Changing async function body causes caller to fail #116048

Open
TylerHorth opened this issue Sep 22, 2023 · 6 comments
Open

Changing async function body causes caller to fail #116048

TylerHorth opened this issue Sep 22, 2023 · 6 comments
Labels
A-async-await Area: Async & Await A-auto-traits Area: auto traits (e.g., `auto trait Send {}`) AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@TylerHorth
Copy link

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

@TylerHorth TylerHorth added the C-bug Category: This is a bug. label Sep 22, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Sep 22, 2023
@zirconium-n
Copy link
Contributor

This should not be possible as it would make changing the body of a method potentially a breaking change.

async fn is known prone to auto trait (like Send) leakage problem like this.

@saethlin
Copy link
Member

Related to #115822

@compiler-errors
Copy link
Member

@saethlin how is this related to #115822? This is an inherent async method, which is stable.

@saethlin
Copy link
Member

Jubilee commented that the general auto trait leakage issue here was discussed in that issue, so I was definitely intending to read all the discussion on that issue and provide some context here. Looks like I never got around to that.

@compiler-errors
Copy link
Member

This is unrelated to #115822. This is just another instance of #110338, which has to do with auto trait bounds failing to be proven due to the lifetime erasure we do in generators.

The send bound problem discussed in #115822 has to do with putting bounds on the anonymous associated types that come from async-fn-in-trait.

@fmease fmease added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-async-await Area: Async & Await A-auto-traits Area: auto traits (e.g., `auto trait Send {}`) and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Sep 29, 2023
@traviscross
Copy link
Contributor

@rustbot labels +AsyncAwait-Triaged

We discussed this in a WG-async meeting and are deferring to the analysis by @compiler-errors above.

@rustbot rustbot added the AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. label Oct 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-async-await Area: Async & Await A-auto-traits Area: auto traits (e.g., `auto trait Send {}`) AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants