From a05276620c67a05b50ad3a28ef143a62e08f12b7 Mon Sep 17 00:00:00 2001 From: dswij Date: Tue, 18 Jan 2022 18:41:00 +0800 Subject: [PATCH] fix `needless_question_mark` not considering async fn --- clippy_lints/src/needless_question_mark.rs | 23 ++++++++++++++++++++-- tests/ui/needless_question_mark.fixed | 13 ++++++++++++ tests/ui/needless_question_mark.rs | 13 ++++++++++++ tests/ui/needless_question_mark.stderr | 14 ++++++++++++- 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/needless_question_mark.rs b/clippy_lints/src/needless_question_mark.rs index 0e7ae43ce..d4c823d1c 100644 --- a/clippy_lints/src/needless_question_mark.rs +++ b/clippy_lints/src/needless_question_mark.rs @@ -4,7 +4,7 @@ use clippy_utils::source::snippet; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::LangItem::{OptionSome, ResultOk}; -use rustc_hir::{Body, Expr, ExprKind, LangItem, MatchSource, QPath}; +use rustc_hir::{AsyncGeneratorKind, Block, Body, Expr, ExprKind, GeneratorKind, LangItem, MatchSource, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::TyS; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -88,7 +88,26 @@ impl LateLintPass<'_> for NeedlessQuestionMark { } fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) { - check(cx, body.value.peel_blocks()); + if let Some(GeneratorKind::Async(AsyncGeneratorKind::Fn)) = body.generator_kind { + if let ExprKind::Block( + Block { + expr: + Some(Expr { + kind: ExprKind::DropTemps(async_body), + .. + }), + .. + }, + _, + ) = body.value.kind + { + if let ExprKind::Block(Block { expr: Some(expr), .. }, ..) = async_body.kind { + check(cx, expr); + } + } + } else { + check(cx, body.value.peel_blocks()); + } } } diff --git a/tests/ui/needless_question_mark.fixed b/tests/ui/needless_question_mark.fixed index f1fc81aa1..ba9d15e59 100644 --- a/tests/ui/needless_question_mark.fixed +++ b/tests/ui/needless_question_mark.fixed @@ -125,3 +125,16 @@ pub fn test2() { let x = Some(3); let _x = some_and_qmark_in_macro!(x?); } + +async fn async_option_bad(to: TO) -> Option { + let _ = Some(3); + to.magic +} + +async fn async_deref_ref(s: Option<&String>) -> Option<&str> { + Some(s?) +} + +async fn async_result_bad(s: TR) -> Result { + s.magic +} diff --git a/tests/ui/needless_question_mark.rs b/tests/ui/needless_question_mark.rs index 44a0c5f61..3a6523e8f 100644 --- a/tests/ui/needless_question_mark.rs +++ b/tests/ui/needless_question_mark.rs @@ -125,3 +125,16 @@ pub fn test2() { let x = Some(3); let _x = some_and_qmark_in_macro!(x?); } + +async fn async_option_bad(to: TO) -> Option { + let _ = Some(3); + Some(to.magic?) +} + +async fn async_deref_ref(s: Option<&String>) -> Option<&str> { + Some(s?) +} + +async fn async_result_bad(s: TR) -> Result { + Ok(s.magic?) +} diff --git a/tests/ui/needless_question_mark.stderr b/tests/ui/needless_question_mark.stderr index 57c3d48c7..f8308e24e 100644 --- a/tests/ui/needless_question_mark.stderr +++ b/tests/ui/needless_question_mark.stderr @@ -77,5 +77,17 @@ LL | let _x = some_and_qmark_in_macro!(x?); | = note: this error originates in the macro `some_and_qmark_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 12 previous errors +error: question mark operator is useless here + --> $DIR/needless_question_mark.rs:131:5 + | +LL | Some(to.magic?) + | ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic` + +error: question mark operator is useless here + --> $DIR/needless_question_mark.rs:139:5 + | +LL | Ok(s.magic?) + | ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `s.magic` + +error: aborting due to 14 previous errors