Rust: "path statement with no effect" issued even when `drop` makes effect

Created on 8 Mar 2018  路  3Comments  路  Source: rust-lang/rust

struct Droppy;

impl Drop for Droppy {
    fn drop(&mut self) {
        println!("2");
    }
}

fn main() {
    let q = Droppy;
    (||{
        println!("1");
        q;
    })();
    println!("3");
}

(playground link)

warning: path statement with no effect
  --> src/main.rs:13:9
   |
13 |         q;
   |         ^^
   |
   = note: #[warn(path_statements)] on by default

Removing the "no effect" line definitely has effect.

The warning may instead suggest to explicitly use std::mem::drop if that is what is needed.

A-destructors A-lint C-bug T-compiler

Most helpful comment

let聽_聽=聽q;聽requires聽adding聽move聽before聽closure聽(somewhat suprisingly unlike let _q = q;)

Writing mem::drop(q) instead of let _ = q may be more idiomatic if one wants to emphasize that running Drop::drop is significant.

All 3 comments

Huh, I ran into this a couple weeks ago and typed up an issue, then decided at the last second to back out of it for some reason. Maybe I just figured that writing let _ = q; is more idiomatic anyways.

This lint is old, by the way. Older than older than old. (in Rust years, anyways)

let聽_聽=聽q;聽requires聽adding聽move聽before聽closure聽(somewhat suprisingly unlike let _q = q;)

Writing mem::drop(q) instead of let _ = q may be more idiomatic if one wants to emphasize that running Drop::drop is significant.

Bumping this, as it's relevant to this recent Twitter poll. (See also https://github.com/rust-lang/rust-clippy/issues/5205, https://github.com/rust-lang/rust-clippy/issues/5206.)

When the path statement invokes a move, this lint is plain wrong; as the value has been moved, the old binding is no longer usable. When this move invokes drop glue, this lint is even more wrong, because the drop glue is an observable effect, and removing the statement would change the semantics of the program.

"Path statement with no effect is further potentially damaging, as it may lead the user to write let _ = $path; to silence the warning, which again changes the semantics of the program, because binding to the _ wildcard pattern does actually not perform a move from the place.

I believe the correct behavior for this lint would be to suggest removing path statements that have no associated drop glue, but to suggest drop($path) for types that do have drop glue, signaling clarity of intent.

Was this page helpful?
0 / 5 - 0 ratings