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

manual_async_fn suggestions breaks code if !Send types involved #12664

Open
roy-work opened this issue Apr 10, 2024 · 0 comments
Open

manual_async_fn suggestions breaks code if !Send types involved #12664

roy-work opened this issue Apr 10, 2024 · 0 comments
Labels
C-bug Category: Clippy is not doing the correct thing I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied

Comments

@roy-work
Copy link

roy-work commented Apr 10, 2024

Summary

In suggesting a fn …(…) -> impl Future<Output=T> + Sendasync fn …(…) -> T transformation, clippy can break code where !Send types are involved.

Reproducer

I tried this code:

use std::future::Future;
use std::rc::Rc;

trait Request {
    fn get_body(self) -> impl Future<Output=Vec<u8>> + Send;
}

struct MyRequest {
    _thing: Rc<u8>,
    body: Vec<u8>,
}

impl Request for MyRequest {
    fn get_body(self) -> impl Future<Output=Vec<u8>> + Send {
        async { self.body }
    }
    
    // Clippy's suggestion, which does not compile.
    /*
    async fn get_body(self) -> Vec<u8> {
        self.body
    }
    */
}

fn main() {
}

(Playground)

On this, Clippy emits:

warning: this function can be simplified using the `async fn` syntax
  --> src/main.rs:14:5
   |
14 |     fn get_body(self) -> impl Future<Output=Vec<u8>> + Send {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_async_fn
   = note: `#[warn(clippy::manual_async_fn)]` on by default
help: make the function `async` and return the output of the future directly
   |
14 |     async fn get_body(self) -> Vec<u8> {
   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: move the body of the async block to the enclosing function
   |
14 |     fn get_body(self) -> impl Future<Output=Vec<u8>> + Send { self.body }
   |                                                             ~~~~~~~~~~~~~

Which seems reasonable ish (although the second help feels like it ought to have an async fn signature, given the transformation to the body requires it…). If we trade the commented section (what I believe Clippy's suggestion to be), however, that breaks things:

error: future cannot be sent between threads safely
  --> src/main.rs:21:5
   |
21 |     async fn get_body(self) -> Vec<u8> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `get_body` is not `Send`
   |
   = help: within `impl Future<Output = Vec<u8>>`, the trait `Send` is not implemented for `Rc<u8>`, which is required by `impl Future<Output = Vec<u8>>: Send`
note: captured value is not `Send`
  --> src/main.rs:21:23
   |
21 |     async fn get_body(self) -> Vec<u8> {
   |                       ^^^^ has type `MyRequest` which is not `Send`
note: required by a bound in `Request::{opaque#0}`
  --> src/main.rs:5:56
   |
5  |     fn get_body(self) -> impl Future<Output=Vec<u8>> + Send;
   |                                                        ^^^^ required by this bound in `Request::{opaque#0}`

(In this minimal example, I've made the MyRequest type !Send by involving a Rc. The real-world use case that got tripped up here involved an actix_web::HttpRequest, which is also !Send, again by way of holding onto an Rc.)

Version

On the playground:

Rust 1.77.2 (stable)
Clippy 0.1.77

Locally:

» rustc -vV
rustc 1.77.1 (7cf61ebde 2024-03-27)
binary: rustc
commit-hash: 7cf61ebde7b22796c69757901dd346d0fe70bd97
commit-date: 2024-03-27
host: x86_64-unknown-linux-gnu
release: 1.77.1
LLVM version: 17.0.6

Additional Labels

@rustbot label +I-suggestion-causes-error

@roy-work roy-work added the C-bug Category: Clippy is not doing the correct thing label Apr 10, 2024
@rustbot rustbot added the I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied label Apr 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied
Projects
None yet
Development

No branches or pull requests

2 participants