mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 23:24:24 +00:00
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:
commit
d15e5e6ad6
8 changed files with 114 additions and 23 deletions
|
@ -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
1
clippy_lints/foo.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Hello
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
);
|
||||
|
|
20
tests/ui/let_underscore_future.rs
Normal file
20
tests/ui/let_underscore_future.rs
Normal 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;
|
||||
}
|
27
tests/ui/let_underscore_future.stderr
Normal file
27
tests/ui/let_underscore_future.stderr
Normal 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
|
||||
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue