diff options
Diffstat (limited to 'clippy_lints/src/methods/mod.rs')
| -rw-r--r-- | clippy_lints/src/methods/mod.rs | 66 |
1 files changed, 19 insertions, 47 deletions
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index de966cccd11..184aee95efa 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, + 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<'_>, @@ -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); |
