]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/needless_question_mark.rs
Auto merge of #9546 - kraktus:default_not_default_trait, r=xFrednet
[rust.git] / clippy_lints / src / needless_question_mark.rs
index 3ca933ea8fbe3fab84e88f2318e9458146f39669..59b6492e112c05453c4dc24cdbf50d2c070d2ef7 100644 (file)
@@ -4,9 +4,8 @@
 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};
 
 declare_clippy_lint! {
@@ -88,31 +87,57 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
     }
 
     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());
+        }
     }
 }
 
 fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
-    let inner_expr = if_chain! {
+    if_chain! {
         if let ExprKind::Call(path, [arg]) = &expr.kind;
         if let ExprKind::Path(ref qpath) = &path.kind;
-        if is_lang_ctor(cx, qpath, OptionSome) || is_lang_ctor(cx, qpath, ResultOk);
+        let sugg_remove = if is_lang_ctor(cx, qpath, OptionSome) {
+            "Some()"
+        } else if is_lang_ctor(cx, qpath, ResultOk) {
+            "Ok()"
+        } else {
+            return;
+        };
         if let ExprKind::Match(inner_expr_with_q, _, MatchSource::TryDesugar) = &arg.kind;
         if let ExprKind::Call(called, [inner_expr]) = &inner_expr_with_q.kind;
-        if let ExprKind::Path(QPath::LangItem(LangItem::TryTraitBranch, _)) = &called.kind;
+        if let ExprKind::Path(QPath::LangItem(LangItem::TryTraitBranch, ..)) = &called.kind;
         if expr.span.ctxt() == inner_expr.span.ctxt();
         let expr_ty = cx.typeck_results().expr_ty(expr);
         let inner_ty = cx.typeck_results().expr_ty(inner_expr);
-        if TyS::same_type(expr_ty, inner_ty);
-        then { inner_expr } else { return; }
-    };
-    span_lint_and_sugg(
-        cx,
-        NEEDLESS_QUESTION_MARK,
-        expr.span,
-        "question mark operator is useless here",
-        "try",
-        format!("{}", snippet(cx, inner_expr.span, r#""...""#)),
-        Applicability::MachineApplicable,
-    );
+        if expr_ty == inner_ty;
+        then {
+            span_lint_and_sugg(
+                cx,
+                NEEDLESS_QUESTION_MARK,
+                expr.span,
+                "question mark operator is useless here",
+                &format!("try removing question mark and `{sugg_remove}`"),
+                format!("{}", snippet(cx, inner_expr.span, r#""...""#)),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
 }