]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/manual_map.rs
Auto merge of #7478 - DevinR528:preemtive, r=llogiq
[rust.git] / clippy_lints / src / manual_map.rs
index d9b75149b9f13f2ab4911bc0cb1a92a109f6e04f..7dec1595e0d108d270b0223661ed187c6143e101 100644 (file)
@@ -3,29 +3,26 @@
 use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
 use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable};
 use clippy_utils::{
-    can_move_expr_to_closure, in_constant, is_allowed, is_else_clause, is_lang_ctor, match_var, peel_hir_expr_refs,
+    can_move_expr_to_closure, in_constant, is_else_clause, is_lang_ctor, is_lint_allowed, path_to_local_id,
+    peel_hir_expr_refs,
 };
 use rustc_ast::util::parser::PREC_POSTFIX;
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
-use rustc_hir::{Arm, BindingAnnotation, Block, Expr, ExprKind, MatchSource, Mutability, Pat, PatKind};
+use rustc_hir::{Arm, BindingAnnotation, Block, Expr, ExprKind, HirId, MatchSource, Mutability, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::{
-    symbol::{sym, Ident},
-    SyntaxContext,
-};
+use rustc_span::{sym, SyntaxContext};
 
 declare_clippy_lint! {
-    /// **What it does:** Checks for usages of `match` which could be implemented using `map`
-    ///
-    /// **Why is this bad?** Using the `map` method is clearer and more concise.
-    ///
-    /// **Known problems:** None.
+    /// ### What it does
+    /// Checks for usages of `match` which could be implemented using `map`
     ///
-    /// **Example:**
+    /// ### Why is this bad?
+    /// Using the `map` method is clearer and more concise.
     ///
+    /// ### Example
     /// ```rust
     /// match Some(0) {
     ///     Some(x) => Some(x + 1),
@@ -102,12 +99,18 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
                 None => return,
             };
 
+            // These two lints will go back and forth with each other.
             if cx.typeck_results().expr_ty(some_expr) == cx.tcx.types.unit
-                && !is_allowed(cx, OPTION_MAP_UNIT_FN, expr.hir_id)
+                && !is_lint_allowed(cx, OPTION_MAP_UNIT_FN, expr.hir_id)
             {
                 return;
             }
 
+            // `map` won't perform any adjustments.
+            if !cx.typeck_results().expr_adjustments(some_expr).is_empty() {
+                return;
+            }
+
             if !can_move_expr_to_closure(cx, some_expr) {
                 return;
             }
@@ -135,14 +138,14 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
                     scrutinee_str.into()
                 };
 
-            let body_str = if let PatKind::Binding(annotation, _, some_binding, None) = some_pat.kind {
-                match can_pass_as_func(cx, some_binding, some_expr) {
+            let body_str = if let PatKind::Binding(annotation, id, some_binding, None) = some_pat.kind {
+                match can_pass_as_func(cx, id, some_expr) {
                     Some(func) if func.span.ctxt() == some_expr.span.ctxt() => {
                         snippet_with_applicability(cx, func.span, "..", &mut app).into_owned()
                     },
                     _ => {
-                        if match_var(some_expr, some_binding.name)
-                            && !is_allowed(cx, MATCH_AS_REF, expr.hir_id)
+                        if path_to_local_id(some_expr, id)
+                            && !is_lint_allowed(cx, MATCH_AS_REF, expr.hir_id)
                             && binding_ref.is_some()
                         {
                             return;
@@ -193,10 +196,10 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 
 // Checks whether the expression could be passed as a function, or whether a closure is needed.
 // Returns the function to be passed to `map` if it exists.
-fn can_pass_as_func(cx: &LateContext<'tcx>, binding: Ident, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
+fn can_pass_as_func(cx: &LateContext<'tcx>, binding: HirId, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
     match expr.kind {
         ExprKind::Call(func, [arg])
-            if match_var(arg, binding.name) && cx.typeck_results().expr_adjustments(arg).is_empty() =>
+            if path_to_local_id(arg, binding) && cx.typeck_results().expr_adjustments(arg).is_empty() =>
         {
             Some(func)
         },