Skip to content

needless_pass_by_value false positive when value used in async move block #13321

Open
@findepi

Description

@findepi

Summary

needless_pass_by_value lint is triggered when a value is moved into a function and referenced in async move block.
If not for the async, it would be correct to flag this as needless_pass_by_value.

Lint Name

needless_pass_by_value

Reproducer

I tried this code:

use std::future::Future;

struct MyStruct {
    a: i32,
    b: i32,
}

fn main() {
    let my = MyStruct { a: 1, b: 2 };
    let _ = async_use(my);
}

fn async_use(my: MyStruct) -> impl Future<Output=i32> {
    async move {
        println!("a: {}, b: {}", my.a, my.b);
        10i32
    }
}

i run cargo clippy -- -Aclippy::all -Wclippy::needless_pass_by_value -D warnings

I saw this happen:

warning: this argument is passed by value, but not consumed in the function body
  --> src/main.rs:13:18
   |
13 | fn async_use(my: MyStruct) -> impl Future<Output=i32> {
   |                  ^^^^^^^^ help: consider taking a reference instead: `&MyStruct`
   |
help: consider marking this type as `Copy`
  --> src/main.rs:3:1
   |
3  | struct MyStruct {
   | ^^^^^^^^^^^^^^^
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
   = note: `-D clippy::needless-pass-by-value` implied by `-D warnings`
   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_value)]`

however, if i follow the advice and make async_use take the reference, cargo build fails with

error[E0700]: hidden type for `impl Future<Output = i32>` captures lifetime that does not appear in bounds
  --> src/main.rs:14:5
   |
13 |   fn async_use(my: &MyStruct) -> impl Future<Output=i32> {
   |                    ---------     ----------------------- opaque type defined here
   |                    |
   |                    hidden type `{async block@src/main.rs:14:5: 17:6}` captures the anonymous lifetime defined here
14 | /     async move {
15 | |         println!("a: {}, b: {}", my.a, my.b);
16 | |         10i32
17 | |     }
   | |_____^
   |
help: to declare that `impl Future<Output = i32>` captures `'_`, you can add an explicit `'_` lifetime bound
   |
13 | fn async_use(my: &MyStruct) -> impl Future<Output=i32> + '_ {
   |                                                        ++++

For more information about this error, try `rustc --explain E0700`.

Version

rustc 1.80.1 (3f5fd8dd4 2024-08-06)
binary: rustc
commit-hash: 3f5fd8dd41153bc5fdca9427e9e05be2c767ba23
commit-date: 2024-08-06
host: aarch64-apple-darwin
release: 1.80.1
LLVM version: 18.1.7

Additional Labels

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't have

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions