-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Flag let _ = ... as dangerous #8246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
In the the case of amethyst/distill@e7e1d25, I think it would have been caught with I can imagine a new lint that warns on every use of |
Fwiw I've encountered this with profiling score guards as well, this is not really limited to locks. |
For what it's worth the Rust Reference book does state that it is idiomatic for ignoring must-used return values: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
|
See discussion here: rust-lang/rust-clippy#8246 tl;dr: `let _` drops immediately, so for anything that has Guard like behavior, it will not work as expected. `let _enter` will ensure that the guard is dropped at the end of the scope.
See discussion here: rust-lang/rust-clippy#8246 tl;dr: `let _` drops immediately, so for anything that has Guard like behavior, it will not work as expected. `let _enter` will ensure that the guard is dropped at the end of the scope.
What it does
If you write code like this:
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 rust-lang/rust#10488)
If instead you write
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:drop(lock.lock());
(which in this case makes the mistake obvious)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 amethyst/distill@e7e1d25 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 rust-lang/rust#10488Lint 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));
orlet _unused = function_call(x);
The text was updated successfully, but these errors were encountered: