Auto merge of #9760 - SquareMan:let_underscore_future, r=llogiq

Add new lint [`let_underscore_future`]

This closes #9721
---

changelog: add new lint [`let_underscore_future`]
This commit is contained in:
bors 2022-11-05 21:34:24 +00:00
commit d15e5e6ad6
8 changed files with 114 additions and 23 deletions

View file

@ -4123,6 +4123,7 @@ Released 2018-09-13
[`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero
[`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
[`let_underscore_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop
[`let_underscore_future`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_future
[`let_underscore_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_lock
[`let_underscore_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_must_use
[`let_unit_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value

1
clippy_lints/foo.txt Normal file
View file

@ -0,0 +1 @@
Hello

View file

@ -215,6 +215,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::len_zero::LEN_WITHOUT_IS_EMPTY_INFO,
crate::len_zero::LEN_ZERO_INFO,
crate::let_if_seq::USELESS_LET_IF_SEQ_INFO,
crate::let_underscore::LET_UNDERSCORE_FUTURE_INFO,
crate::let_underscore::LET_UNDERSCORE_LOCK_INFO,
crate::let_underscore::LET_UNDERSCORE_MUST_USE_INFO,
crate::lifetimes::EXTRA_UNUSED_LIFETIMES_INFO,

View file

@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::{is_must_use_ty, match_type};
use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
use clippy_utils::{is_must_use_func_call, paths};
use rustc_hir::{Local, PatKind};
use rustc_lint::{LateContext, LateLintPass};
@ -28,7 +28,7 @@ declare_clippy_lint! {
#[clippy::version = "1.42.0"]
pub LET_UNDERSCORE_MUST_USE,
restriction,
"non-binding let on a `#[must_use]` expression"
"non-binding `let` on a `#[must_use]` expression"
}
declare_clippy_lint! {
@ -56,10 +56,41 @@ declare_clippy_lint! {
#[clippy::version = "1.43.0"]
pub LET_UNDERSCORE_LOCK,
correctness,
"non-binding let on a synchronization lock"
"non-binding `let` on a synchronization lock"
}
declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK]);
declare_clippy_lint! {
/// ### What it does
/// Checks for `let _ = <expr>` where the resulting type of expr implements `Future`
///
/// ### Why is this bad?
/// Futures must be polled for work to be done. The original intention was most likely to await the future
/// and ignore the resulting value.
///
/// ### Example
/// ```rust
/// async fn foo() -> Result<(), ()> {
/// Ok(())
/// }
/// let _ = foo();
/// ```
///
/// Use instead:
/// ```rust
/// # async fn context() {
/// async fn foo() -> Result<(), ()> {
/// Ok(())
/// }
/// let _ = foo().await;
/// # }
/// ```
#[clippy::version = "1.66"]
pub LET_UNDERSCORE_FUTURE,
suspicious,
"non-binding `let` on a future"
}
declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK, LET_UNDERSCORE_FUTURE]);
const SYNC_GUARD_PATHS: [&[&str]; 3] = [
&paths::PARKING_LOT_MUTEX_GUARD,
@ -83,17 +114,27 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
cx,
LET_UNDERSCORE_LOCK,
local.span,
"non-binding let on a synchronization lock",
"non-binding `let` on a synchronization lock",
None,
"consider using an underscore-prefixed named \
binding or dropping explicitly with `std::mem::drop`",
);
} else if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait()
&& implements_trait(cx, cx.typeck_results().expr_ty(init), future_trait_def_id, &[]) {
span_lint_and_help(
cx,
LET_UNDERSCORE_FUTURE,
local.span,
"non-binding `let` on a future",
None,
"consider awaiting the future or dropping explicitly with `std::mem::drop`"
);
} else if is_must_use_ty(cx, cx.typeck_results().expr_ty(init)) {
span_lint_and_help(
cx,
LET_UNDERSCORE_MUST_USE,
local.span,
"non-binding let on an expression with `#[must_use]` type",
"non-binding `let` on an expression with `#[must_use]` type",
None,
"consider explicitly using expression value",
);
@ -102,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
cx,
LET_UNDERSCORE_MUST_USE,
local.span,
"non-binding let on a result of a `#[must_use]` function",
"non-binding `let` on a result of a `#[must_use]` function",
None,
"consider explicitly using function result",
);

View file

@ -0,0 +1,20 @@
use std::future::Future;
async fn some_async_fn() {}
fn sync_side_effects() {}
fn custom() -> impl Future<Output = ()> {
sync_side_effects();
async {}
}
fn do_something_to_future(future: &mut impl Future<Output = ()>) {}
fn main() {
let _ = some_async_fn();
let _ = custom();
let mut future = some_async_fn();
do_something_to_future(&mut future);
let _ = future;
}

View file

@ -0,0 +1,27 @@
error: non-binding `let` on a future
--> $DIR/let_underscore_future.rs:14:5
|
LL | let _ = some_async_fn();
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider awaiting the future or dropping explicitly with `std::mem::drop`
= note: `-D clippy::let-underscore-future` implied by `-D warnings`
error: non-binding `let` on a future
--> $DIR/let_underscore_future.rs:15:5
|
LL | let _ = custom();
| ^^^^^^^^^^^^^^^^^
|
= help: consider awaiting the future or dropping explicitly with `std::mem::drop`
error: non-binding `let` on a future
--> $DIR/let_underscore_future.rs:19:5
|
LL | let _ = future;
| ^^^^^^^^^^^^^^^
|
= help: consider awaiting the future or dropping explicitly with `std::mem::drop`
error: aborting due to 3 previous errors

View file

@ -1,4 +1,4 @@
error: non-binding let on a synchronization lock
error: non-binding `let` on a synchronization lock
--> $DIR/let_underscore_lock.rs:9:5
|
LL | let _ = p_m.lock();
@ -7,7 +7,7 @@ LL | let _ = p_m.lock();
= help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
= note: `-D clippy::let-underscore-lock` implied by `-D warnings`
error: non-binding let on a synchronization lock
error: non-binding `let` on a synchronization lock
--> $DIR/let_underscore_lock.rs:12:5
|
LL | let _ = p_m1.lock();
@ -15,7 +15,7 @@ LL | let _ = p_m1.lock();
|
= help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
error: non-binding let on a synchronization lock
error: non-binding `let` on a synchronization lock
--> $DIR/let_underscore_lock.rs:15:5
|
LL | let _ = p_rw.read();
@ -23,7 +23,7 @@ LL | let _ = p_rw.read();
|
= help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
error: non-binding let on a synchronization lock
error: non-binding `let` on a synchronization lock
--> $DIR/let_underscore_lock.rs:16:5
|
LL | let _ = p_rw.write();

View file

@ -1,4 +1,4 @@
error: non-binding let on a result of a `#[must_use]` function
error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:67:5
|
LL | let _ = f();
@ -7,7 +7,7 @@ LL | let _ = f();
= help: consider explicitly using function result
= note: `-D clippy::let-underscore-must-use` implied by `-D warnings`
error: non-binding let on an expression with `#[must_use]` type
error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:68:5
|
LL | let _ = g();
@ -15,7 +15,7 @@ LL | let _ = g();
|
= help: consider explicitly using expression value
error: non-binding let on a result of a `#[must_use]` function
error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:70:5
|
LL | let _ = l(0_u32);
@ -23,7 +23,7 @@ LL | let _ = l(0_u32);
|
= help: consider explicitly using function result
error: non-binding let on a result of a `#[must_use]` function
error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:74:5
|
LL | let _ = s.f();
@ -31,7 +31,7 @@ LL | let _ = s.f();
|
= help: consider explicitly using function result
error: non-binding let on an expression with `#[must_use]` type
error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:75:5
|
LL | let _ = s.g();
@ -39,7 +39,7 @@ LL | let _ = s.g();
|
= help: consider explicitly using expression value
error: non-binding let on a result of a `#[must_use]` function
error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:78:5
|
LL | let _ = S::h();
@ -47,7 +47,7 @@ LL | let _ = S::h();
|
= help: consider explicitly using function result
error: non-binding let on an expression with `#[must_use]` type
error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:79:5
|
LL | let _ = S::p();
@ -55,7 +55,7 @@ LL | let _ = S::p();
|
= help: consider explicitly using expression value
error: non-binding let on a result of a `#[must_use]` function
error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:81:5
|
LL | let _ = S::a();
@ -63,7 +63,7 @@ LL | let _ = S::a();
|
= help: consider explicitly using function result
error: non-binding let on an expression with `#[must_use]` type
error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:83:5
|
LL | let _ = if true { Ok(()) } else { Err(()) };
@ -71,7 +71,7 @@ LL | let _ = if true { Ok(()) } else { Err(()) };
|
= help: consider explicitly using expression value
error: non-binding let on a result of a `#[must_use]` function
error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:87:5
|
LL | let _ = a.is_ok();
@ -79,7 +79,7 @@ LL | let _ = a.is_ok();
|
= help: consider explicitly using function result
error: non-binding let on an expression with `#[must_use]` type
error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:89:5
|
LL | let _ = a.map(|_| ());
@ -87,7 +87,7 @@ LL | let _ = a.map(|_| ());
|
= help: consider explicitly using expression value
error: non-binding let on an expression with `#[must_use]` type
error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:91:5
|
LL | let _ = a;