|
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