|
1 | 1 | use clippy_utils::diagnostics::span_lint_and_sugg;
|
2 |
| -use clippy_utils::eager_or_lazy::is_lazyness_candidate; |
3 |
| -use clippy_utils::is_trait_item; |
| 2 | +use clippy_utils::eager_or_lazy::switch_to_lazy_eval; |
4 | 3 | use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_macro_callsite};
|
5 |
| -use clippy_utils::ty::implements_trait; |
6 |
| -use clippy_utils::ty::{is_type_diagnostic_item, match_type}; |
7 |
| -use clippy_utils::{contains_return, last_path_segment, paths}; |
| 4 | +use clippy_utils::ty::{implements_trait, match_type}; |
| 5 | +use clippy_utils::{contains_return, is_trait_item, last_path_segment, paths}; |
8 | 6 | use if_chain::if_chain;
|
9 | 7 | use rustc_errors::Applicability;
|
10 | 8 | use rustc_hir as hir;
|
11 |
| -use rustc_hir::{BlockCheckMode, UnsafeSource}; |
12 | 9 | use rustc_lint::LateContext;
|
13 |
| -use rustc_middle::ty; |
14 | 10 | use rustc_span::source_map::Span;
|
15 | 11 | use rustc_span::symbol::{kw, sym};
|
16 | 12 | use std::borrow::Cow;
|
@@ -96,25 +92,10 @@ pub(super) fn check<'tcx>(
|
96 | 92 | (&paths::RESULT, true, &["or", "unwrap_or"], "else"),
|
97 | 93 | ];
|
98 | 94 |
|
99 |
| - if let hir::ExprKind::MethodCall(path, _, [self_arg, ..], _) = &arg.kind { |
100 |
| - if path.ident.name == sym::len { |
101 |
| - let ty = cx.typeck_results().expr_ty(self_arg).peel_refs(); |
102 |
| - |
103 |
| - match ty.kind() { |
104 |
| - ty::Slice(_) | ty::Array(_, _) | ty::Str => return, |
105 |
| - _ => (), |
106 |
| - } |
107 |
| - |
108 |
| - if is_type_diagnostic_item(cx, ty, sym::Vec) { |
109 |
| - return; |
110 |
| - } |
111 |
| - } |
112 |
| - } |
113 |
| - |
114 | 95 | if_chain! {
|
115 | 96 | if KNOW_TYPES.iter().any(|k| k.2.contains(&name));
|
116 | 97 |
|
117 |
| - if is_lazyness_candidate(cx, arg); |
| 98 | + if switch_to_lazy_eval(cx, arg); |
118 | 99 | if !contains_return(arg);
|
119 | 100 |
|
120 | 101 | let self_ty = cx.typeck_results().expr_ty(self_expr);
|
@@ -166,26 +147,30 @@ pub(super) fn check<'tcx>(
|
166 | 147 | }
|
167 | 148 | }
|
168 | 149 |
|
169 |
| - if args.len() == 2 { |
170 |
| - match args[1].kind { |
| 150 | + if let [self_arg, arg] = args { |
| 151 | + let inner_arg = if let hir::ExprKind::Block( |
| 152 | + hir::Block { |
| 153 | + stmts: [], |
| 154 | + expr: Some(expr), |
| 155 | + .. |
| 156 | + }, |
| 157 | + _, |
| 158 | + ) = arg.kind |
| 159 | + { |
| 160 | + expr |
| 161 | + } else { |
| 162 | + arg |
| 163 | + }; |
| 164 | + match inner_arg.kind { |
171 | 165 | hir::ExprKind::Call(fun, or_args) => {
|
172 | 166 | let or_has_args = !or_args.is_empty();
|
173 |
| - if !check_unwrap_or_default(cx, name, fun, &args[0], &args[1], or_has_args, expr.span) { |
| 167 | + if !check_unwrap_or_default(cx, name, fun, self_arg, arg, or_has_args, expr.span) { |
174 | 168 | let fun_span = if or_has_args { None } else { Some(fun.span) };
|
175 |
| - check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, fun_span); |
| 169 | + check_general_case(cx, name, method_span, self_arg, arg, expr.span, fun_span); |
176 | 170 | }
|
177 | 171 | },
|
178 | 172 | hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => {
|
179 |
| - check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, None); |
180 |
| - }, |
181 |
| - hir::ExprKind::Block(block, _) |
182 |
| - if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) => |
183 |
| - { |
184 |
| - if let Some(block_expr) = block.expr { |
185 |
| - if let hir::ExprKind::MethodCall(..) = block_expr.kind { |
186 |
| - check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, None); |
187 |
| - } |
188 |
| - } |
| 173 | + check_general_case(cx, name, method_span, self_arg, arg, expr.span, None); |
189 | 174 | },
|
190 | 175 | _ => (),
|
191 | 176 | }
|
|
0 commit comments