Skip to content

Commit fbbaa0e

Browse files
committed
Add discarded_futures lint
1 parent 5ac9657 commit fbbaa0e

File tree

8 files changed

+109
-0
lines changed

8 files changed

+109
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5918,6 +5918,7 @@ Released 2018-09-13
59185918
[`disallowed_script_idents`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents
59195919
[`disallowed_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_type
59205920
[`disallowed_types`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types
5921+
[`discarded_future`]: https://rust-lang.github.io/rust-clippy/master/index.html#discarded_future
59215922
[`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression
59225923
[`doc_broken_link`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_broken_link
59235924
[`doc_comment_double_space_linebreaks`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_comment_double_space_linebreaks

clippy_lints/src/declared_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
113113
crate::disallowed_names::DISALLOWED_NAMES_INFO,
114114
crate::disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS_INFO,
115115
crate::disallowed_types::DISALLOWED_TYPES_INFO,
116+
crate::discarded_future::DISCARDED_FUTURE_INFO,
116117
crate::doc::DOC_BROKEN_LINK_INFO,
117118
crate::doc::DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS_INFO,
118119
crate::doc::DOC_INCLUDE_WITHOUT_CFG_INFO,
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use rustc_hir::*;
2+
use rustc_lint::{LateContext, LateLintPass};
3+
use rustc_session::declare_lint_pass;
4+
5+
use clippy_utils::diagnostics::span_lint_and_sugg;
6+
use clippy_utils::source::snippet;
7+
use clippy_utils::ty::implements_trait;
8+
use rustc_errors::Applicability;
9+
use rustc_middle::ty;
10+
use rustc_span::sym;
11+
use clippy_utils::ty::is_type_diagnostic_item;
12+
13+
declare_clippy_lint! {
14+
/// ### What it does
15+
///
16+
/// ### Why restrict this?
17+
///
18+
/// ### Example
19+
/// ```no_run
20+
/// // example code where clippy issues a warning
21+
/// ```
22+
/// Use instead:
23+
/// ```no_run
24+
/// // example code which does not raise clippy warning
25+
/// ```
26+
#[clippy::version = "1.91.0"]
27+
pub DISCARDED_FUTURE,
28+
restriction,
29+
"default lint description"
30+
}
31+
declare_lint_pass!(DiscardedFuture => [DISCARDED_FUTURE]);
32+
33+
impl<'tcx> LateLintPass<'tcx> for DiscardedFuture {
34+
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'tcx>) {
35+
if let StmtKind::Let(let_stmt) = stmt.kind
36+
&& let PatKind::Wild = let_stmt.pat.kind
37+
&& let Some(expr) = let_stmt.init
38+
&& let ty = cx.typeck_results().expr_ty(expr)
39+
&& is_type_diagnostic_item(cx, ty, sym::Result)
40+
&& let ty::Adt(_, substs) = ty.kind()
41+
&& let Some(inner_ty) = substs[0].as_type()
42+
&& let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait()
43+
&& implements_trait(cx, inner_ty, future_trait_def_id, &[])
44+
{
45+
span_lint_and_sugg(
46+
cx,
47+
DISCARDED_FUTURE,
48+
expr.span,
49+
format!("Discarding a Result<Future>: did you mean to call .await on this first?"),
50+
"consider `.await` on it",
51+
format!("{}.await", snippet(cx, expr.span, "..")),
52+
Applicability::MaybeIncorrect,
53+
);
54+
}
55+
}
56+
}

clippy_lints/src/discarded_futures.rs

Whitespace-only changes.

clippy_lints/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ mod disallowed_methods;
118118
mod disallowed_names;
119119
mod disallowed_script_idents;
120120
mod disallowed_types;
121+
mod discarded_future;
121122
mod doc;
122123
mod double_parens;
123124
mod drop_forget_ref;
@@ -831,5 +832,6 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
831832
store.register_late_pass(|_| Box::new(cloned_ref_to_slice_refs::ClonedRefToSliceRefs::new(conf)));
832833
store.register_late_pass(|_| Box::new(infallible_try_from::InfallibleTryFrom));
833834
store.register_late_pass(|_| Box::new(coerce_container_to_any::CoerceContainerToAny));
835+
store.register_late_pass(|_| Box::new(discarded_future::DiscardedFuture));
834836
// add lints here, do not remove this comment, it's used in `new_lint`
835837
}

tests/ui/discarded_future.fixed

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![warn(clippy::discarded_future)]
2+
#![allow(clippy::result_unit_err)]
3+
4+
pub fn result_future() -> Result<impl std::future::Future<Output = ()>, ()> {
5+
Ok(async {
6+
dbg!("hello im in a future");
7+
})
8+
}
9+
10+
pub async fn calls_result_future() {
11+
// some async stuff
12+
let _ = result_future().await;
13+
//~^ discarded_future
14+
// more async stuff
15+
}
16+
17+
fn main() {
18+
19+
}

tests/ui/discarded_future.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![warn(clippy::discarded_future)]
2+
#![allow(clippy::result_unit_err)]
3+
4+
pub fn result_future() -> Result<impl std::future::Future<Output = ()>, ()> {
5+
Ok(async {
6+
dbg!("hello im in a future");
7+
})
8+
}
9+
10+
pub async fn calls_result_future() {
11+
// some async stuff
12+
let _ = result_future();
13+
//~^ discarded_future
14+
// more async stuff
15+
}
16+
17+
fn main() {
18+
19+
}

tests/ui/discarded_future.stderr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: Discarding a Result<Future>: did you mean to call .await on this first?
2+
--> tests/ui/discarded_future.rs:12:13
3+
|
4+
LL | let _ = result_future();
5+
| ^^^^^^^^^^^^^^^ help: consider `.await` on it: `result_future().await`
6+
|
7+
= note: `-D clippy::discarded-future` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::discarded_future)]`
9+
10+
error: aborting due to 1 previous error
11+

0 commit comments

Comments
 (0)