Skip to content

Confusing suggestion for dropping_copy_types #125189

Closed
@thanatos

Description

@thanatos

Code

I had the following code:

    let w_fd = w.as_raw_fd();
    let cmd_stdout = unsafe { Stdio::from_raw_fd(w_fd) };
    let cmd_stderr = unsafe { Stdio::from_raw_fd(w_fd) };
    // Not required, but prevents us from accidentally using it later.
    drop(w_fd);

if we compile this, rustc rightly warns us:

warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
   --> src/main.rs:158:5
    |
158 |     drop(w_fd);
    |     ^^^^^----^
    |          |
    |          argument has type `i32`
    |
    = note: use `let _ = ...` to ignore the expression or result
    = note: `#[warn(dropping_copy_types)]` on by default

This bit, however:

    = note: use `let _ = ...` to ignore the expression or result

… I'm not clear on. Let's take the compiler's suggestion and modify the code:

    // Not required, but prevents us from accidentally using it later.
    let _ = drop(w_fd);

Now we'll get an even more confusing diagnostic:

warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
   --> src/main.rs:158:13
    |
158 |     let _ = drop(w_fd);
    |             ^^^^^----^
    |                  |
    |                  argument has type `i32`
    |
    = note: use `let _ = ...` to ignore the expression or result
    = note: `#[warn(dropping_copy_types)]` on by default

…we're now note'd to do something we're already doing.

A competing interpretation of this diagnostic, in my mind, is that it means to do let _ = <the original expression where we compute w_fd>. But we cannot do that, as we use w_fd. I suppose we could inline all the uses, but I wonder if rustc shouldn't realize that no, the variable must be named / that suggestion breaks the compile. Or, should rustc understand that we cannot let _ = this variable, and that we'd need to inline it? But here there are two inlines, and in the general case, side-effects in the expression could make this tricky.

The higher level thing here is that I was attempting to drop a variable from scope, essentially, by moving it with drop. Obviously, that doesn't work for Copy types. I guess I could use {} to scope w_fd … but unfortunately I need both cmd_stdout and cmd_stderr later.

Current output

warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
   --> src/main.rs:158:5
    |
158 |     drop(w_fd);
    |     ^^^^^----^
    |          |
    |          argument has type `i32`
    |
    = note: use `let _ = ...` to ignore the expression or result
    = note: `#[warn(dropping_copy_types)]` on by default

Desired output

No response

Rationale and extra context

No response

Other cases

No response

Rust Version

rustc 1.76.0 (07dca489a 2024-02-04)
binary: rustc
commit-hash: 07dca489ac2d933c78d3c5158e3f43beefeb02ce
commit-date: 2024-02-04
host: x86_64-unknown-linux-gnu
release: 1.76.0
LLVM version: 17.0.6

Anything else?

No response

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.D-confusingDiagnostics: Confusing error or lint that should be reworked.L-dropping_copy_typesLint: dropping_copy_typesT-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