Skip to content

Commit df5a0ee

Browse files
authored
or_fun_call: lint method calls inside map_or first arg (#15074)
<strike>blocked on #15073</strike> Lint method calls inside `map_or` too, so for this, lint will be showed: ```rust Some(4).map_or("asd".to_string().len() as i32, f); ``` previously it worked only for: ```rust Some(4).map_or(slow_fun(), f); ``` https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=bfcda42a6af446e69bc883a8b45eb13c Sorry for multiple `or_fun_call` PRs. changelog: [`or_fun_call`]: lint method calls inside map_or first arg
2 parents 4dcaa80 + 86a1496 commit df5a0ee

File tree

6 files changed

+71
-36
lines changed

6 files changed

+71
-36
lines changed

clippy_lints/src/methods/or_fun_call.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -242,15 +242,23 @@ pub(super) fn check<'tcx>(
242242
let inner_arg = peel_blocks(arg);
243243
for_each_expr(cx, inner_arg, |ex| {
244244
let is_top_most_expr = ex.hir_id == inner_arg.hir_id;
245-
if let hir::ExprKind::Call(fun, fun_args) = ex.kind {
246-
let fun_span = if fun_args.is_empty() && is_top_most_expr {
247-
Some(fun.span)
248-
} else {
249-
None
250-
};
251-
if check_or_fn_call(cx, name, method_span, receiver, arg, Some(lambda), expr.span, fun_span) {
252-
return ControlFlow::Break(());
253-
}
245+
match ex.kind {
246+
hir::ExprKind::Call(fun, fun_args) => {
247+
let fun_span = if fun_args.is_empty() && is_top_most_expr {
248+
Some(fun.span)
249+
} else {
250+
None
251+
};
252+
if check_or_fn_call(cx, name, method_span, receiver, arg, Some(lambda), expr.span, fun_span) {
253+
return ControlFlow::Break(());
254+
}
255+
},
256+
hir::ExprKind::MethodCall(..) => {
257+
if check_or_fn_call(cx, name, method_span, receiver, arg, Some(lambda), expr.span, None) {
258+
return ControlFlow::Break(());
259+
}
260+
},
261+
_ => {},
254262
}
255263
ControlFlow::Continue(())
256264
});

clippy_lints/src/needless_pass_by_value.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,10 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
246246
for (span, suggestion) in clone_spans {
247247
diag.span_suggestion(
248248
span,
249-
span.get_source_text(cx)
250-
.map_or("change the call to".to_owned(), |src| format!("change `{src}` to")),
249+
span.get_source_text(cx).map_or_else(
250+
|| "change the call to".to_owned(),
251+
|src| format!("change `{src}` to"),
252+
),
251253
suggestion,
252254
Applicability::Unspecified,
253255
);
@@ -275,8 +277,10 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
275277
for (span, suggestion) in clone_spans {
276278
diag.span_suggestion(
277279
span,
278-
span.get_source_text(cx)
279-
.map_or("change the call to".to_owned(), |src| format!("change `{src}` to")),
280+
span.get_source_text(cx).map_or_else(
281+
|| "change the call to".to_owned(),
282+
|src| format!("change `{src}` to"),
283+
),
280284
suggestion,
281285
Applicability::Unspecified,
282286
);

clippy_utils/src/diagnostics.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@ fn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) {
2222
{
2323
diag.help(format!(
2424
"for further information visit https://rust-lang.github.io/rust-clippy/{}/index.html#{lint}",
25-
&option_env!("RUST_RELEASE_NUM").map_or("master".to_string(), |n| {
26-
// extract just major + minor version and ignore patch versions
27-
format!("rust-{}", n.rsplit_once('.').unwrap().1)
28-
})
25+
&option_env!("RUST_RELEASE_NUM").map_or_else(
26+
|| "master".to_string(),
27+
|n| {
28+
// extract just major + minor version and ignore patch versions
29+
format!("rust-{}", n.rsplit_once('.').unwrap().1)
30+
}
31+
)
2932
));
3033
}
3134
}

tests/ui/or_fun_call.fixed

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ mod issue8993 {
283283
let _ = Some(4).map_or_else(g, f);
284284
//~^ or_fun_call
285285
let _ = Some(4).map_or(0, f);
286+
let _ = Some(4).map_or_else(|| "asd".to_string().len() as i32, f);
287+
//~^ or_fun_call
286288
}
287289
}
288290

@@ -426,6 +428,8 @@ mod result_map_or {
426428
let _ = x.map_or_else(|_| g(), f);
427429
//~^ or_fun_call
428430
let _ = x.map_or(0, f);
431+
let _ = x.map_or_else(|_| "asd".to_string().len() as i32, f);
432+
//~^ or_fun_call
429433
}
430434
}
431435

tests/ui/or_fun_call.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ mod issue8993 {
283283
let _ = Some(4).map_or(g(), f);
284284
//~^ or_fun_call
285285
let _ = Some(4).map_or(0, f);
286+
let _ = Some(4).map_or("asd".to_string().len() as i32, f);
287+
//~^ or_fun_call
286288
}
287289
}
288290

@@ -426,6 +428,8 @@ mod result_map_or {
426428
let _ = x.map_or(g(), f);
427429
//~^ or_fun_call
428430
let _ = x.map_or(0, f);
431+
let _ = x.map_or("asd".to_string().len() as i32, f);
432+
//~^ or_fun_call
429433
}
430434
}
431435

tests/ui/or_fun_call.stderr

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -154,62 +154,68 @@ error: function call inside of `map_or`
154154
LL | let _ = Some(4).map_or(g(), f);
155155
| ^^^^^^^^^^^^^^ help: try: `map_or_else(g, f)`
156156

157+
error: function call inside of `map_or`
158+
--> tests/ui/or_fun_call.rs:286:25
159+
|
160+
LL | let _ = Some(4).map_or("asd".to_string().len() as i32, f);
161+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| "asd".to_string().len() as i32, f)`
162+
157163
error: use of `unwrap_or_else` to construct default value
158-
--> tests/ui/or_fun_call.rs:315:18
164+
--> tests/ui/or_fun_call.rs:317:18
159165
|
160166
LL | with_new.unwrap_or_else(Vec::new);
161167
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
162168

163169
error: use of `unwrap_or_else` to construct default value
164-
--> tests/ui/or_fun_call.rs:319:28
170+
--> tests/ui/or_fun_call.rs:321:28
165171
|
166172
LL | with_default_trait.unwrap_or_else(Default::default);
167173
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
168174

169175
error: use of `unwrap_or_else` to construct default value
170-
--> tests/ui/or_fun_call.rs:323:27
176+
--> tests/ui/or_fun_call.rs:325:27
171177
|
172178
LL | with_default_type.unwrap_or_else(u64::default);
173179
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
174180

175181
error: use of `unwrap_or_else` to construct default value
176-
--> tests/ui/or_fun_call.rs:327:22
182+
--> tests/ui/or_fun_call.rs:329:22
177183
|
178184
LL | real_default.unwrap_or_else(<FakeDefault as Default>::default);
179185
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
180186

181187
error: use of `or_insert_with` to construct default value
182-
--> tests/ui/or_fun_call.rs:331:23
188+
--> tests/ui/or_fun_call.rs:333:23
183189
|
184190
LL | map.entry(42).or_insert_with(String::new);
185191
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
186192

187193
error: use of `or_insert_with` to construct default value
188-
--> tests/ui/or_fun_call.rs:335:25
194+
--> tests/ui/or_fun_call.rs:337:25
189195
|
190196
LL | btree.entry(42).or_insert_with(String::new);
191197
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
192198

193199
error: use of `unwrap_or_else` to construct default value
194-
--> tests/ui/or_fun_call.rs:339:25
200+
--> tests/ui/or_fun_call.rs:341:25
195201
|
196202
LL | let _ = stringy.unwrap_or_else(String::new);
197203
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
198204

199205
error: function call inside of `unwrap_or`
200-
--> tests/ui/or_fun_call.rs:381:17
206+
--> tests/ui/or_fun_call.rs:383:17
201207
|
202208
LL | let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)`
203209
| ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(f)`
204210

205211
error: function call inside of `unwrap_or`
206-
--> tests/ui/or_fun_call.rs:386:17
212+
--> tests/ui/or_fun_call.rs:388:17
207213
|
208214
LL | let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)`
209215
| ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| f() + 1)`
210216

211217
error: function call inside of `unwrap_or`
212-
--> tests/ui/or_fun_call.rs:391:17
218+
--> tests/ui/or_fun_call.rs:393:17
213219
|
214220
LL | let _ = opt.unwrap_or({
215221
| _________________^
@@ -229,52 +235,58 @@ LL ~ });
229235
|
230236

231237
error: function call inside of `map_or`
232-
--> tests/ui/or_fun_call.rs:397:17
238+
--> tests/ui/or_fun_call.rs:399:17
233239
|
234240
LL | let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)`
235241
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| f() + 1, |v| v)`
236242

237243
error: use of `unwrap_or` to construct default value
238-
--> tests/ui/or_fun_call.rs:402:17
244+
--> tests/ui/or_fun_call.rs:404:17
239245
|
240246
LL | let _ = opt.unwrap_or({ i32::default() });
241247
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
242248

243249
error: function call inside of `unwrap_or`
244-
--> tests/ui/or_fun_call.rs:409:21
250+
--> tests/ui/or_fun_call.rs:411:21
245251
|
246252
LL | let _ = opt_foo.unwrap_or(Foo { val: String::default() });
247253
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Foo { val: String::default() })`
248254

249255
error: function call inside of `map_or`
250-
--> tests/ui/or_fun_call.rs:424:19
256+
--> tests/ui/or_fun_call.rs:426:19
251257
|
252258
LL | let _ = x.map_or(g(), |v| v);
253259
| ^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|_| g(), |v| v)`
254260

255261
error: function call inside of `map_or`
256-
--> tests/ui/or_fun_call.rs:426:19
262+
--> tests/ui/or_fun_call.rs:428:19
257263
|
258264
LL | let _ = x.map_or(g(), f);
259265
| ^^^^^^^^^^^^^^ help: try: `map_or_else(|_| g(), f)`
260266

267+
error: function call inside of `map_or`
268+
--> tests/ui/or_fun_call.rs:431:19
269+
|
270+
LL | let _ = x.map_or("asd".to_string().len() as i32, f);
271+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|_| "asd".to_string().len() as i32, f)`
272+
261273
error: function call inside of `get_or_insert`
262-
--> tests/ui/or_fun_call.rs:438:15
274+
--> tests/ui/or_fun_call.rs:442:15
263275
|
264276
LL | let _ = x.get_or_insert(g());
265277
| ^^^^^^^^^^^^^^^^^^ help: try: `get_or_insert_with(g)`
266278

267279
error: function call inside of `and`
268-
--> tests/ui/or_fun_call.rs:448:15
280+
--> tests/ui/or_fun_call.rs:452:15
269281
|
270282
LL | let _ = x.and(g());
271283
| ^^^^^^^^ help: try: `and_then(|_| g())`
272284

273285
error: function call inside of `and`
274-
--> tests/ui/or_fun_call.rs:458:15
286+
--> tests/ui/or_fun_call.rs:462:15
275287
|
276288
LL | let _ = x.and(g());
277289
| ^^^^^^^^ help: try: `and_then(|_| g())`
278290

279-
error: aborting due to 43 previous errors
291+
error: aborting due to 45 previous errors
280292

0 commit comments

Comments
 (0)