rust-clippy icon indicating copy to clipboard operation
rust-clippy copied to clipboard

`drop(not_send_value)` ignored for future_not_send

Open mvolfik opened this issue 3 years ago • 4 comments

Summary

drop(not_send_value) seems to be ignored for the future_not_send lint (from nursery)

Playground link

Lint Name

future_not_send

Reproducer

I tried this code:

#![warn(clippy::future_not_send)]
#![feature(negative_impls)]
#![allow(dead_code)]

fn main() {}

#[derive(Debug)]
struct SomethingNotSend;

impl !Send for SomethingNotSend {}

async fn f() {
    let a = SomethingNotSend;
    if true {
        drop(a);
        other().await;
        return;
    }
    println!("{:?}", a);
}

async fn other() {}

I saw this happen:

    Checking playground v0.0.1 (/playground)
warning: future cannot be sent between threads safely
  --> src/main.rs:12:14
   |
12 | async fn f() {
   |              ^ future returned by `f` is not `Send`
   |
note: the lint level is defined here
  --> src/main.rs:1:9
   |
1  | #![warn(clippy::future_not_send)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^
note: future is not `Send` as this value is used across an await
  --> src/main.rs:16:16
   |
13 |     let a = SomethingNotSend;
   |         - has type `SomethingNotSend` which is not `Send`
...
16 |         other().await;
   |                ^^^^^^ await occurs here, with `a` maybe used later
...
20 | }
   | - `a` is later dropped here
   = note: `SomethingNotSend` doesn't implement `std::marker::Send`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#future_not_send

warning: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends its contained lifetimes
  --> src/main.rs:15:9
   |
15 |         drop(a);
   |         ^^^^^^^
   |
   = note: `#[warn(clippy::drop_non_drop)]` on by default
note: argument has type `SomethingNotSend`
  --> src/main.rs:15:14
   |
15 |         drop(a);
   |              ^
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#drop_non_drop

warning: `playground` (bin "playground") generated 2 warnings
    Finished dev [unoptimized + debuginfo] target(s) in 0.50s

I expected the lint to not be shown, as the code is (at least I believe) correct

Version

play.rust-lang.org

Build using the Nightly version: 1.63.0-nightly

(2022-06-03 a6b8c6954829669a5c4f)

Clippy 0.1.63 (2022-06-03 a6b8c69)

Additional Labels

No response

mvolfik avatar Jun 04 '22 22:06 mvolfik

Oops, didn't search for MCVE enough, the branch isn't even necessary, this is flagged too:

#![warn(clippy::future_not_send)]
#![feature(negative_impls)]
#![allow(dead_code)]

fn main() {}

#[derive(Debug)]
struct SomethingNotSend;

impl !Send for SomethingNotSend {}

async fn f() {
    let a = SomethingNotSend;
    drop(a);
    other().await;
}

async fn other() {}

mvolfik avatar Jun 04 '22 22:06 mvolfik

The future doesn't implement Send in that example. This fails to compile:

#![warn(clippy::future_not_send)]
#![feature(negative_impls)]
#![allow(dead_code)]

#[derive(Debug)]
struct SomethingNotSend;

impl !Send for SomethingNotSend {}

async fn f() {
    let a = SomethingNotSend;
    drop(a);
    other().await;
}

async fn other() {}

fn needs_send(_: impl Send) {}

fn main() {
    needs_send(f());
}

Same for the first example.

Jarcho avatar Jun 05 '22 00:06 Jarcho

Hmm, but why?

mvolfik avatar Jun 06 '22 07:06 mvolfik

I'm going to assume the the compiler uses everything in scope at the await point when creating the generator (which a is, even though it's been dropped).

Jarcho avatar Jun 06 '22 16:06 Jarcho