rust-lang / rust-lang/rust-clippy

Flag let _ = ... as dangerous

Open
#8,246 3 comments 10 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-lint
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

What it does

If you write code like this:

let _ = lock.lock();

The guard will drop and you will not hold the lock. This catches a lot of people by surprise and has potentially disastrous consequences. (See prior discussion of this here https://github.com/rust-lang/rust/issues/10488)

If instead you write

let _guard = lock.lock();

You will hold the lock until _guard is dropped out of scope. This is almost always what people want for something RAII-like such as a lock (or file handle, DB transaction, etc.)

If the let _ = lock.guard() construction was considered hazardous, we could instead use the following alternatives to be explicit about what we want:

  • Either explicitly drop: drop(lock.lock()); (which in this case makes the mistake obvious)
  • Or name the variable: let _guard = lock.lock();

Because let _ = ... is subtly hazardous, and there are more explicit constructions to do the same thing, I would personally like to ban this pattern in my own code.

NOTE: As a more practical example in real code, I made a fix in some code a while back https://github.com/amethyst/distill/commit/e7e1d254816096dad220cb4571b0cdd6bf245eb9 and originally tried to write it as let _ = self.0.runtime.enter(); which was no different from before. There are also other examples of people hitting this in https://github.com/rust-lang/rust/issues/10488

Lint Name

let_underscore_can_be_hazardous

Category

correctness

Advantage

Potentially catches serious resource management problems

Drawbacks

Lots of people probably like the let _ = X construction for things like receiving a result as a return value and explicitly deciding to not check it. This is by many considered the idiomatic way to ignore a return value.

It would be nice if there was a way to apply this lint only when the returned object is an RAII-style object. (Similar to how unused Results are flagged.) But I'm not sure how practical that would be, especially considering containers and opaque trait objects.

Example

let _ = function_call(x);

Depending on intent, could be written as:

drop(function_call(x)); or let _unused = function_call(x);

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the proposed let _ = ... examples and the prior discussion in rust-lang/rust#10488; the issue names no files, tests, or entry points. Define the lint’s intended scope and handling of RAII-style values versus intentionally ignored results, then verify that the behavior and rationale are documented and tested.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.