Skip to content

Commit 954034b

Browse files
authored
Fix manual_find suggests wrongly when return type needs adjustment (#14892)
Closes #14826 changelog: [`manual_find`] fix wrong suggestions when return type needs adjustment
2 parents c12bc22 + 7ffc886 commit 954034b

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

clippy_lints/src/loops/manual_find.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ pub(super) fn check<'tcx>(
8383
)[..],
8484
);
8585
}
86+
87+
// If the return type requires adjustments, we need to add a `.map` after the iterator
88+
let inner_ret_adjust = cx.typeck_results().expr_adjustments(inner_ret);
89+
if !inner_ret_adjust.is_empty() {
90+
snippet.push_str(".map(|v| v as _)");
91+
}
92+
8693
// Extends to `last_stmt` to include semicolon in case of `return None;`
8794
let lint_span = span.to(last_stmt.span).to(last_ret.span);
8895
span_lint_and_then(

tests/ui/manual_find_fixable.fixed

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,13 @@ fn two_bindings(v: Vec<(u8, u8)>) -> Option<u8> {
179179
}
180180

181181
fn main() {}
182+
183+
mod issue14826 {
184+
fn adjust_fixable(needle: &str) -> Option<&'static str> {
185+
["foo", "bar"].iter().find(|&candidate| candidate.eq_ignore_ascii_case(needle)).map(|v| v as _)
186+
}
187+
188+
fn adjust_unfixable(needle: &str) -> Option<*const str> {
189+
["foo", "bar"].iter().find(|&&candidate| candidate.eq_ignore_ascii_case(needle)).copied().map(|v| v as _)
190+
}
191+
}

tests/ui/manual_find_fixable.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,25 @@ fn two_bindings(v: Vec<(u8, u8)>) -> Option<u8> {
251251
}
252252

253253
fn main() {}
254+
255+
mod issue14826 {
256+
fn adjust_fixable(needle: &str) -> Option<&'static str> {
257+
for candidate in &["foo", "bar"] {
258+
//~^ manual_find
259+
if candidate.eq_ignore_ascii_case(needle) {
260+
return Some(candidate);
261+
}
262+
}
263+
None
264+
}
265+
266+
fn adjust_unfixable(needle: &str) -> Option<*const str> {
267+
for &candidate in &["foo", "bar"] {
268+
//~^ manual_find
269+
if candidate.eq_ignore_ascii_case(needle) {
270+
return Some(candidate);
271+
}
272+
}
273+
None
274+
}
275+
}

tests/ui/manual_find_fixable.stderr

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,27 @@ LL | | return Some(x);
139139
LL | | None
140140
| |____________^ help: replace with an iterator: `arr.into_iter().find(|&x| x < 1)`
141141

142-
error: aborting due to 12 previous errors
142+
error: manual implementation of `Iterator::find`
143+
--> tests/ui/manual_find_fixable.rs:257:9
144+
|
145+
LL | / for candidate in &["foo", "bar"] {
146+
LL | |
147+
LL | | if candidate.eq_ignore_ascii_case(needle) {
148+
LL | | return Some(candidate);
149+
... |
150+
LL | | None
151+
| |____________^ help: replace with an iterator: `["foo", "bar"].iter().find(|&candidate| candidate.eq_ignore_ascii_case(needle)).map(|v| v as _)`
152+
153+
error: manual implementation of `Iterator::find`
154+
--> tests/ui/manual_find_fixable.rs:267:9
155+
|
156+
LL | / for &candidate in &["foo", "bar"] {
157+
LL | |
158+
LL | | if candidate.eq_ignore_ascii_case(needle) {
159+
LL | | return Some(candidate);
160+
... |
161+
LL | | None
162+
| |____________^ help: replace with an iterator: `["foo", "bar"].iter().find(|&&candidate| candidate.eq_ignore_ascii_case(needle)).copied().map(|v| v as _)`
163+
164+
error: aborting due to 14 previous errors
143165

0 commit comments

Comments
 (0)