about summary refs log tree commit diff
path: root/clippy_lints/src/methods/mod.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-25 06:23:55 +0000
committerbors <bors@rust-lang.org>2020-09-25 06:23:55 +0000
commit6273be6fc26b22f91389a67a30c6633d60cc459d (patch)
tree882bb8c78e662a6130049429d513d3556e299369 /clippy_lints/src/methods/mod.rs
parenta8c60732786626928fe9dceb1ffe0775a2700969 (diff)
parentd1f9cad102b5686f2b827f3c62a02dfe419128a6 (diff)
Auto merge of #77144 - flip1995:clippyup, r=Manishearth
Update Clippy

Bi-weekly Clippy update.

This includes a `Cargo.lock` update (d445493479711389f4dea3a0f433041077ba2088), so probably needs `rollup=never`.

r? `@Manishearth`
Diffstat (limited to 'clippy_lints/src/methods/mod.rs')
-rw-r--r--clippy_lints/src/methods/mod.rs88
1 files changed, 30 insertions, 58 deletions
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index ba69c8266b1..dadd0f8ebb7 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -25,14 +25,15 @@ use rustc_span::source_map::Span;
 use rustc_span::symbol::{sym, SymbolStr};
 
 use crate::consts::{constant, Constant};
+use crate::utils::eager_or_lazy::is_lazyness_candidate;
 use crate::utils::usage::mutated_variables;
 use crate::utils::{
     contains_ty, get_arg_name, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait, in_macro,
-    is_copy, is_ctor_or_promotable_const_function, is_expn_of, is_type_diagnostic_item, iter_input_pats,
-    last_path_segment, match_def_path, match_qpath, match_trait_method, match_type, match_var, method_calls,
-    method_chain_args, paths, remove_blocks, return_ty, single_segment_path, snippet, snippet_with_applicability,
-    snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_note, span_lint_and_sugg,
-    span_lint_and_then, sugg, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq,
+    is_copy, is_expn_of, is_type_diagnostic_item, iter_input_pats, last_path_segment, match_def_path, match_qpath,
+    match_trait_method, match_type, match_var, method_calls, method_chain_args, paths, remove_blocks, return_ty,
+    single_segment_path, snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint,
+    span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then, sugg, walk_ptrs_ty_depth,
+    SpanlessEq,
 };
 
 declare_clippy_lint! {
@@ -1454,18 +1455,21 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
             ["unwrap_or", "map"] => option_map_unwrap_or::lint(cx, expr, arg_lists[1], arg_lists[0], method_spans[1]),
             ["unwrap_or_else", "map"] => {
                 if !lint_map_unwrap_or_else(cx, expr, arg_lists[1], arg_lists[0]) {
-                    unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], true, "unwrap_or");
+                    unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "unwrap_or");
                 }
             },
             ["map_or", ..] => lint_map_or_none(cx, expr, arg_lists[0]),
             ["and_then", ..] => {
-                unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], false, "and");
-                bind_instead_of_map::OptionAndThenSome::lint(cx, expr, arg_lists[0]);
-                bind_instead_of_map::ResultAndThenOk::lint(cx, expr, arg_lists[0]);
+                let biom_option_linted = bind_instead_of_map::OptionAndThenSome::lint(cx, expr, arg_lists[0]);
+                let biom_result_linted = bind_instead_of_map::ResultAndThenOk::lint(cx, expr, arg_lists[0]);
+                if !biom_option_linted && !biom_result_linted {
+                    unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "and");
+                }
             },
             ["or_else", ..] => {
-                unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], false, "or");
-                bind_instead_of_map::ResultOrElseErrInfo::lint(cx, expr, arg_lists[0]);
+                if !bind_instead_of_map::ResultOrElseErrInfo::lint(cx, expr, arg_lists[0]) {
+                    unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "or");
+                }
             },
             ["next", "filter"] => lint_filter_next(cx, expr, arg_lists[1]),
             ["next", "skip_while"] => lint_skip_while_next(cx, expr, arg_lists[1]),
@@ -1508,9 +1512,9 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
             ["is_file", ..] => lint_filetype_is_file(cx, expr, arg_lists[0]),
             ["map", "as_ref"] => lint_option_as_ref_deref(cx, expr, arg_lists[1], arg_lists[0], false),
             ["map", "as_mut"] => lint_option_as_ref_deref(cx, expr, arg_lists[1], arg_lists[0], true),
-            ["unwrap_or_else", ..] => unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], true, "unwrap_or"),
-            ["get_or_insert_with", ..] => unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], true, "get_or_insert"),
-            ["ok_or_else", ..] => unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], true, "ok_or"),
+            ["unwrap_or_else", ..] => unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "unwrap_or"),
+            ["get_or_insert_with", ..] => unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "get_or_insert"),
+            ["ok_or_else", ..] => unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "ok_or"),
             _ => {},
         }
 
@@ -1714,37 +1718,6 @@ fn lint_or_fun_call<'tcx>(
     name: &str,
     args: &'tcx [hir::Expr<'_>],
 ) {
-    // Searches an expression for method calls or function calls that aren't ctors
-    struct FunCallFinder<'a, 'tcx> {
-        cx: &'a LateContext<'tcx>,
-        found: bool,
-    }
-
-    impl<'a, 'tcx> intravisit::Visitor<'tcx> for FunCallFinder<'a, 'tcx> {
-        type Map = Map<'tcx>;
-
-        fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
-            let call_found = match &expr.kind {
-                // ignore enum and struct constructors
-                hir::ExprKind::Call(..) => !is_ctor_or_promotable_const_function(self.cx, expr),
-                hir::ExprKind::MethodCall(..) => true,
-                _ => false,
-            };
-
-            if call_found {
-                self.found |= true;
-            }
-
-            if !self.found {
-                intravisit::walk_expr(self, expr);
-            }
-        }
-
-        fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
-            intravisit::NestedVisitorMap::None
-        }
-    }
-
     /// Checks for `unwrap_or(T::new())` or `unwrap_or(T::default())`.
     fn check_unwrap_or_default(
         cx: &LateContext<'_>,
@@ -1801,14 +1774,14 @@ fn lint_or_fun_call<'tcx>(
     ) {
         if let hir::ExprKind::MethodCall(ref path, _, ref args, _) = &arg.kind {
             if path.ident.as_str() == "len" {
-                let ty = walk_ptrs_ty(cx.typeck_results().expr_ty(&args[0]));
+                let ty = cx.typeck_results().expr_ty(&args[0]).peel_refs();
 
                 match ty.kind() {
                     ty::Slice(_) | ty::Array(_, _) => return,
                     _ => (),
                 }
 
-                if match_type(cx, ty, &paths::VEC) {
+                if is_type_diagnostic_item(cx, ty, sym!(vec_type)) {
                     return;
                 }
             }
@@ -1825,8 +1798,7 @@ fn lint_or_fun_call<'tcx>(
         if_chain! {
             if know_types.iter().any(|k| k.2.contains(&name));
 
-            let mut finder = FunCallFinder { cx: &cx, found: false };
-            if { finder.visit_expr(&arg); finder.found };
+            if is_lazyness_candidate(cx, arg);
             if !contains_return(&arg);
 
             let self_ty = cx.typeck_results().expr_ty(self_expr);
@@ -1909,7 +1881,7 @@ fn lint_expect_fun_call(
                         && (method_name.ident.name == sym!(as_str) || method_name.ident.name == sym!(as_ref))
                         && {
                             let arg_type = cx.typeck_results().expr_ty(&call_args[0]);
-                            let base_type = walk_ptrs_ty(arg_type);
+                            let base_type = arg_type.peel_refs();
                             *base_type.kind() == ty::Str || is_type_diagnostic_item(cx, base_type, sym!(string_type))
                         }
                     {
@@ -2170,7 +2142,7 @@ fn lint_clone_on_copy(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Exp
 }
 
 fn lint_clone_on_ref_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
-    let obj_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(arg));
+    let obj_ty = cx.typeck_results().expr_ty(arg).peel_refs();
 
     if let ty::Adt(_, subst) = obj_ty.kind() {
         let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) {
@@ -2201,7 +2173,7 @@ fn lint_string_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::E
     let arg = &args[1];
     if let Some(arglists) = method_chain_args(arg, &["chars"]) {
         let target = &arglists[0][0];
-        let self_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(target));
+        let self_ty = cx.typeck_results().expr_ty(target).peel_refs();
         let ref_str = if *self_ty.kind() == ty::Str {
             ""
         } else if is_type_diagnostic_item(cx, self_ty, sym!(string_type)) {
@@ -2229,7 +2201,7 @@ fn lint_string_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::E
 }
 
 fn lint_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
-    let obj_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(&args[0]));
+    let obj_ty = cx.typeck_results().expr_ty(&args[0]).peel_refs();
     if is_type_diagnostic_item(cx, obj_ty, sym!(string_type)) {
         lint_string_extend(cx, expr, args);
     }
@@ -2412,7 +2384,7 @@ fn lint_iter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_
         }
     } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(caller_expr), sym!(vec_type))
         || matches!(
-            &walk_ptrs_ty(cx.typeck_results().expr_ty(caller_expr)).kind(),
+            &cx.typeck_results().expr_ty(caller_expr).peel_refs().kind(),
             ty::Array(_, _)
         )
     {
@@ -2615,7 +2587,7 @@ fn derefs_to_slice<'tcx>(
 
 /// lint use of `unwrap()` for `Option`s and `Result`s
 fn lint_unwrap(cx: &LateContext<'_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) {
-    let obj_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(&unwrap_args[0]));
+    let obj_ty = cx.typeck_results().expr_ty(&unwrap_args[0]).peel_refs();
 
     let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) {
         Some((UNWRAP_USED, "an Option", "None"))
@@ -2643,7 +2615,7 @@ fn lint_unwrap(cx: &LateContext<'_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::E
 
 /// lint use of `expect()` for `Option`s and `Result`s
 fn lint_expect(cx: &LateContext<'_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) {
-    let obj_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(&expect_args[0]));
+    let obj_ty = cx.typeck_results().expr_ty(&expect_args[0]).peel_refs();
 
     let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) {
         Some((EXPECT_USED, "an Option", "None"))
@@ -3162,7 +3134,7 @@ fn lint_chars_cmp(
         if segment.ident.name == sym!(Some);
         then {
             let mut applicability = Applicability::MachineApplicable;
-            let self_ty = walk_ptrs_ty(cx.typeck_results().expr_ty_adjusted(&args[0][0]));
+            let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0][0]).peel_refs();
 
             if *self_ty.kind() != ty::Str {
                 return false;
@@ -3374,7 +3346,7 @@ fn lint_into_iter(cx: &LateContext<'_>, expr: &hir::Expr<'_>, self_ref_ty: Ty<'_
             INTO_ITER_ON_REF,
             method_span,
             &format!(
-                "this `.into_iter()` call is equivalent to `.{}()` and will not move the `{}`",
+                "this `.into_iter()` call is equivalent to `.{}()` and will not consume the `{}`",
                 method_name, kind,
             ),
             "call directly",