Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 31eb3b7

Browse files
author
mikerite
authored
Merge pull request rust-lang#3127 from mikerite/fix-2937
Fix 2937
2 parents dd11ffa + 7499cb5 commit 31eb3b7

File tree

3 files changed

+59
-36
lines changed

3 files changed

+59
-36
lines changed

clippy_lints/src/methods/mod.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,12 +1069,19 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa
10691069
/// Checks for the `EXPECT_FUN_CALL` lint.
10701070
fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Span, name: &str, args: &[hir::Expr]) {
10711071
fn extract_format_args(arg: &hir::Expr) -> Option<&hir::HirVec<hir::Expr>> {
1072-
if let hir::ExprKind::AddrOf(_, ref addr_of) = arg.node {
1073-
if let hir::ExprKind::Call(ref inner_fun, ref inner_args) = addr_of.node {
1074-
if is_expn_of(inner_fun.span, "format").is_some() && inner_args.len() == 1 {
1075-
if let hir::ExprKind::Call(_, ref format_args) = inner_args[0].node {
1076-
return Some(format_args);
1077-
}
1072+
let arg = match &arg.node {
1073+
hir::ExprKind::AddrOf(_, expr)=> expr,
1074+
hir::ExprKind::MethodCall(method_name, _, args)
1075+
if method_name.ident.name == "as_str" ||
1076+
method_name.ident.name == "as_ref"
1077+
=> &args[0],
1078+
_ => arg,
1079+
};
1080+
1081+
if let hir::ExprKind::Call(ref inner_fun, ref inner_args) = arg.node {
1082+
if is_expn_of(inner_fun.span, "format").is_some() && inner_args.len() == 1 {
1083+
if let hir::ExprKind::Call(_, ref format_args) = inner_args[0].node {
1084+
return Some(format_args);
10781085
}
10791086
}
10801087
}
@@ -1111,7 +1118,8 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
11111118
| hir::ExprKind::MethodCall(..)
11121119
// These variants are debatable or require further examination
11131120
| hir::ExprKind::If(..)
1114-
| hir::ExprKind::Match(..) => true,
1121+
| hir::ExprKind::Match(..)
1122+
| hir::ExprKind::Block{ .. } => true,
11151123
_ => false,
11161124
}
11171125
}
@@ -1165,7 +1173,7 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
11651173
span_replace_word,
11661174
&format!("use of `{}` followed by a function call", name),
11671175
"try this",
1168-
format!("unwrap_or_else({} panic!({}))", closure, sugg),
1176+
format!("unwrap_or_else({} {{ let msg = {}; panic!(msg) }}))", closure, sugg),
11691177
);
11701178
}
11711179

tests/ui/methods.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#![warn(clippy::all, clippy::pedantic, clippy::option_unwrap_used)]
1515
#![allow(clippy::blacklisted_name, unused, clippy::print_stdout, clippy::non_ascii_literal, clippy::new_without_default,
1616
clippy::new_without_default_derive, clippy::missing_docs_in_private_items, clippy::needless_pass_by_value,
17-
clippy::default_trait_access, clippy::use_self)]
17+
clippy::default_trait_access, clippy::use_self, clippy::useless_format)]
1818

1919
use std::collections::BTreeMap;
2020
use std::collections::HashMap;
@@ -403,6 +403,9 @@ fn expect_fun_call() {
403403
//Issue #2979 - this should not lint
404404
let msg = "bar";
405405
Some("foo").expect(msg);
406+
407+
Some("foo").expect({ &format!("error") });
408+
Some("foo").expect(format!("error").as_ref());
406409
}
407410

408411
/// Checks implementation of `ITER_NTH` lint

tests/ui/methods.stderr

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ error: use of `expect` followed by a function call
361361
--> $DIR/methods.rs:379:26
362362
|
363363
379 | with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
364-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!(format!("Error {}: fake error", error_code).as_str()))`
364+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))`
365365

366366
error: use of `expect` followed by a function call
367367
--> $DIR/methods.rs:389:25
@@ -373,85 +373,97 @@ error: use of `expect` followed by a function call
373373
--> $DIR/methods.rs:392:25
374374
|
375375
392 | with_err_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
376-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| panic!(format!("Error {}: fake error", error_code).as_str()))`
376+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))`
377+
378+
error: use of `expect` followed by a function call
379+
--> $DIR/methods.rs:407:17
380+
|
381+
407 | Some("foo").expect({ &format!("error") });
382+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { let msg = { &format!("error") }; panic!(msg) }))`
383+
384+
error: use of `expect` followed by a function call
385+
--> $DIR/methods.rs:408:17
386+
|
387+
408 | Some("foo").expect(format!("error").as_ref());
388+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("error"))`
377389

378390
error: called `.iter().nth()` on a Vec. Calling `.get()` is both faster and more readable
379-
--> $DIR/methods.rs:416:23
391+
--> $DIR/methods.rs:419:23
380392
|
381-
416 | let bad_vec = some_vec.iter().nth(3);
393+
419 | let bad_vec = some_vec.iter().nth(3);
382394
| ^^^^^^^^^^^^^^^^^^^^^^
383395
|
384396
= note: `-D clippy::iter-nth` implied by `-D warnings`
385397

386398
error: called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable
387-
--> $DIR/methods.rs:417:26
399+
--> $DIR/methods.rs:420:26
388400
|
389-
417 | let bad_slice = &some_vec[..].iter().nth(3);
401+
420 | let bad_slice = &some_vec[..].iter().nth(3);
390402
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
391403

392404
error: called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable
393-
--> $DIR/methods.rs:418:31
405+
--> $DIR/methods.rs:421:31
394406
|
395-
418 | let bad_boxed_slice = boxed_slice.iter().nth(3);
407+
421 | let bad_boxed_slice = boxed_slice.iter().nth(3);
396408
| ^^^^^^^^^^^^^^^^^^^^^^^^^
397409

398410
error: called `.iter().nth()` on a VecDeque. Calling `.get()` is both faster and more readable
399-
--> $DIR/methods.rs:419:29
411+
--> $DIR/methods.rs:422:29
400412
|
401-
419 | let bad_vec_deque = some_vec_deque.iter().nth(3);
413+
422 | let bad_vec_deque = some_vec_deque.iter().nth(3);
402414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
403415

404416
error: called `.iter_mut().nth()` on a Vec. Calling `.get_mut()` is both faster and more readable
405-
--> $DIR/methods.rs:424:23
417+
--> $DIR/methods.rs:427:23
406418
|
407-
424 | let bad_vec = some_vec.iter_mut().nth(3);
419+
427 | let bad_vec = some_vec.iter_mut().nth(3);
408420
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
409421

410422
error: called `.iter_mut().nth()` on a slice. Calling `.get_mut()` is both faster and more readable
411-
--> $DIR/methods.rs:427:26
423+
--> $DIR/methods.rs:430:26
412424
|
413-
427 | let bad_slice = &some_vec[..].iter_mut().nth(3);
425+
430 | let bad_slice = &some_vec[..].iter_mut().nth(3);
414426
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
415427

416428
error: called `.iter_mut().nth()` on a VecDeque. Calling `.get_mut()` is both faster and more readable
417-
--> $DIR/methods.rs:430:29
429+
--> $DIR/methods.rs:433:29
418430
|
419-
430 | let bad_vec_deque = some_vec_deque.iter_mut().nth(3);
431+
433 | let bad_vec_deque = some_vec_deque.iter_mut().nth(3);
420432
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
421433

422434
error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
423-
--> $DIR/methods.rs:442:13
435+
--> $DIR/methods.rs:445:13
424436
|
425-
442 | let _ = some_vec.iter().skip(42).next();
437+
445 | let _ = some_vec.iter().skip(42).next();
426438
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
427439
|
428440
= note: `-D clippy::iter-skip-next` implied by `-D warnings`
429441

430442
error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
431-
--> $DIR/methods.rs:443:13
443+
--> $DIR/methods.rs:446:13
432444
|
433-
443 | let _ = some_vec.iter().cycle().skip(42).next();
445+
446 | let _ = some_vec.iter().cycle().skip(42).next();
434446
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
435447

436448
error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
437-
--> $DIR/methods.rs:444:13
449+
--> $DIR/methods.rs:447:13
438450
|
439-
444 | let _ = (1..10).skip(10).next();
451+
447 | let _ = (1..10).skip(10).next();
440452
| ^^^^^^^^^^^^^^^^^^^^^^^
441453

442454
error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
443-
--> $DIR/methods.rs:445:14
455+
--> $DIR/methods.rs:448:14
444456
|
445-
445 | let _ = &some_vec[..].iter().skip(3).next();
457+
448 | let _ = &some_vec[..].iter().skip(3).next();
446458
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
447459

448460
error: used unwrap() on an Option value. If you don't want to handle the None case gracefully, consider using expect() to provide a better panic message
449-
--> $DIR/methods.rs:454:13
461+
--> $DIR/methods.rs:457:13
450462
|
451-
454 | let _ = opt.unwrap();
463+
457 | let _ = opt.unwrap();
452464
| ^^^^^^^^^^^^
453465
|
454466
= note: `-D clippy::option-unwrap-used` implied by `-D warnings`
455467

456-
error: aborting due to 56 previous errors
468+
error: aborting due to 58 previous errors
457469

0 commit comments

Comments
 (0)