Skip to content

Commit e492d02

Browse files
authored
fix: handle core panics in all format lints (rust-lang#16597)
Fixes rust-lang#16411 `core::panic` was missing in the formatting arg lints changelog: fix all format-related lints to handle `core::panic!` macro
2 parents f320b64 + a815656 commit e492d02

10 files changed

+368
-11
lines changed

clippy_utils/src/macros.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[
1919
sym::assert_eq_macro,
2020
sym::assert_macro,
2121
sym::assert_ne_macro,
22+
sym::core_panic_macro,
2223
sym::debug_assert_eq_macro,
2324
sym::debug_assert_macro,
2425
sym::debug_assert_ne_macro,

tests/ui/uninlined_format_args.fixed

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,3 +361,24 @@ fn user_format() {
361361
usr_println!(true, "{local_f64:.1}");
362362
//~^ uninlined_format_args
363363
}
364+
365+
// issue #16411: false negative when #[clippy::format_args] macro uses nested format_args
366+
// without binding the inner args first
367+
#[clippy::format_args]
368+
macro_rules! nested_format_args {
369+
($($arg:tt)*) => {{
370+
// Wraps the user args in another format_args call
371+
::core::format_args!("{}\n", ::core::format_args!($($arg)*))
372+
}};
373+
}
374+
375+
fn nested_format_args_user() {
376+
let local_i32 = 1;
377+
let local_f64 = 2.0;
378+
379+
// false negative: should warn but currently doesn't because the inner format_args
380+
// is not processed when it's used as an argument to another format_args
381+
nested_format_args!("{}", local_i32);
382+
nested_format_args!("val='{}'", local_i32);
383+
nested_format_args!("{:.1}", local_f64);
384+
}

tests/ui/uninlined_format_args.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,24 @@ fn user_format() {
366366
usr_println!(true, "{:.1}", local_f64);
367367
//~^ uninlined_format_args
368368
}
369+
370+
// issue #16411: false negative when #[clippy::format_args] macro uses nested format_args
371+
// without binding the inner args first
372+
#[clippy::format_args]
373+
macro_rules! nested_format_args {
374+
($($arg:tt)*) => {{
375+
// Wraps the user args in another format_args call
376+
::core::format_args!("{}\n", ::core::format_args!($($arg)*))
377+
}};
378+
}
379+
380+
fn nested_format_args_user() {
381+
let local_i32 = 1;
382+
let local_f64 = 2.0;
383+
384+
// false negative: should warn but currently doesn't because the inner format_args
385+
// is not processed when it's used as an argument to another format_args
386+
nested_format_args!("{}", local_i32);
387+
nested_format_args!("val='{}'", local_i32);
388+
nested_format_args!("{:.1}", local_f64);
389+
}

tests/ui/uninlined_format_args_panic.edition2018.fixed

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
//@revisions: edition2018 edition2021
1+
//@revisions: edition2018 edition2021 edition2024
22
//@[edition2018] edition:2018
33
//@[edition2021] edition:2021
4+
//@[edition2024] edition:2024
45

56
#![warn(clippy::uninlined_format_args)]
67
#![allow(clippy::literal_string_with_formatting_args)]
@@ -14,14 +15,17 @@ fn main() {
1415
if var > 0 {
1516
panic!("p1 {}", var);
1617
//~[edition2021]^ uninlined_format_args
18+
//~[edition2024]^^ uninlined_format_args
1719
}
1820
if var > 0 {
1921
panic!("p2 {0}", var);
2022
//~[edition2021]^ uninlined_format_args
23+
//~[edition2024]^^ uninlined_format_args
2124
}
2225
if var > 0 {
2326
panic!("p3 {var}", var = var);
2427
//~[edition2021]^ uninlined_format_args
28+
//~[edition2024]^^ uninlined_format_args
2529
}
2630

2731
#[allow(non_fmt_panics)]
@@ -33,6 +37,34 @@ fn main() {
3337

3438
assert!(var == 1, "p5 {}", var);
3539
//~[edition2021]^ uninlined_format_args
40+
//~[edition2024]^^ uninlined_format_args
3641
debug_assert!(var == 1, "p6 {}", var);
3742
//~[edition2021]^ uninlined_format_args
43+
//~[edition2024]^^ uninlined_format_args
44+
45+
// core::panic! with format string containing text: should warn on 2021+ (issue #16411)
46+
if var > 0 {
47+
core::panic!("p7 {}", var);
48+
//~[edition2021]^ uninlined_format_args
49+
//~[edition2024]^^ uninlined_format_args
50+
}
51+
if var > 0 {
52+
core::panic!("p8 {0}", var);
53+
//~[edition2021]^ uninlined_format_args
54+
//~[edition2024]^^ uninlined_format_args
55+
}
56+
if var > 0 {
57+
core::panic!("p9 {var}", var = var);
58+
//~[edition2021]^ uninlined_format_args
59+
//~[edition2024]^^ uninlined_format_args
60+
}
61+
62+
// std::panic! and core::panic! with only "{}" format string: false negative due to
63+
// panic_display special case in panic_2021 macro - no format_args node is created
64+
if var > 0 {
65+
std::panic!("{}", var);
66+
}
67+
if var > 0 {
68+
core::panic!("{}", var);
69+
}
3870
}

tests/ui/uninlined_format_args_panic.edition2018.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: variables can be used directly in the `format!` string
2-
--> tests/ui/uninlined_format_args_panic.rs:11:5
2+
--> tests/ui/uninlined_format_args_panic.rs:12:5
33
|
44
LL | println!("val='{}'", var);
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^

tests/ui/uninlined_format_args_panic.edition2021.fixed

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
//@revisions: edition2018 edition2021
1+
//@revisions: edition2018 edition2021 edition2024
22
//@[edition2018] edition:2018
33
//@[edition2021] edition:2021
4+
//@[edition2024] edition:2024
45

56
#![warn(clippy::uninlined_format_args)]
67
#![allow(clippy::literal_string_with_formatting_args)]
@@ -14,14 +15,17 @@ fn main() {
1415
if var > 0 {
1516
panic!("p1 {var}");
1617
//~[edition2021]^ uninlined_format_args
18+
//~[edition2024]^^ uninlined_format_args
1719
}
1820
if var > 0 {
1921
panic!("p2 {var}");
2022
//~[edition2021]^ uninlined_format_args
23+
//~[edition2024]^^ uninlined_format_args
2124
}
2225
if var > 0 {
2326
panic!("p3 {var}");
2427
//~[edition2021]^ uninlined_format_args
28+
//~[edition2024]^^ uninlined_format_args
2529
}
2630

2731
#[allow(non_fmt_panics)]
@@ -33,6 +37,34 @@ fn main() {
3337

3438
assert!(var == 1, "p5 {var}");
3539
//~[edition2021]^ uninlined_format_args
40+
//~[edition2024]^^ uninlined_format_args
3641
debug_assert!(var == 1, "p6 {var}");
3742
//~[edition2021]^ uninlined_format_args
43+
//~[edition2024]^^ uninlined_format_args
44+
45+
// core::panic! with format string containing text: should warn on 2021+ (issue #16411)
46+
if var > 0 {
47+
core::panic!("p7 {var}");
48+
//~[edition2021]^ uninlined_format_args
49+
//~[edition2024]^^ uninlined_format_args
50+
}
51+
if var > 0 {
52+
core::panic!("p8 {var}");
53+
//~[edition2021]^ uninlined_format_args
54+
//~[edition2024]^^ uninlined_format_args
55+
}
56+
if var > 0 {
57+
core::panic!("p9 {var}");
58+
//~[edition2021]^ uninlined_format_args
59+
//~[edition2024]^^ uninlined_format_args
60+
}
61+
62+
// std::panic! and core::panic! with only "{}" format string: false negative due to
63+
// panic_display special case in panic_2021 macro - no format_args node is created
64+
if var > 0 {
65+
std::panic!("{}", var);
66+
}
67+
if var > 0 {
68+
core::panic!("{}", var);
69+
}
3870
}

tests/ui/uninlined_format_args_panic.edition2021.stderr

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: variables can be used directly in the `format!` string
2-
--> tests/ui/uninlined_format_args_panic.rs:11:5
2+
--> tests/ui/uninlined_format_args_panic.rs:12:5
33
|
44
LL | println!("val='{}'", var);
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL + println!("val='{var}'");
1313
|
1414

1515
error: variables can be used directly in the `format!` string
16-
--> tests/ui/uninlined_format_args_panic.rs:15:9
16+
--> tests/ui/uninlined_format_args_panic.rs:16:9
1717
|
1818
LL | panic!("p1 {}", var);
1919
| ^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL + panic!("p1 {var}");
2525
|
2626

2727
error: variables can be used directly in the `format!` string
28-
--> tests/ui/uninlined_format_args_panic.rs:19:9
28+
--> tests/ui/uninlined_format_args_panic.rs:21:9
2929
|
3030
LL | panic!("p2 {0}", var);
3131
| ^^^^^^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL + panic!("p2 {var}");
3737
|
3838

3939
error: variables can be used directly in the `format!` string
40-
--> tests/ui/uninlined_format_args_panic.rs:23:9
40+
--> tests/ui/uninlined_format_args_panic.rs:26:9
4141
|
4242
LL | panic!("p3 {var}", var = var);
4343
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL + panic!("p3 {var}");
4949
|
5050

5151
error: variables can be used directly in the `format!` string
52-
--> tests/ui/uninlined_format_args_panic.rs:34:5
52+
--> tests/ui/uninlined_format_args_panic.rs:38:5
5353
|
5454
LL | assert!(var == 1, "p5 {}", var);
5555
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL + assert!(var == 1, "p5 {var}");
6161
|
6262

6363
error: variables can be used directly in the `format!` string
64-
--> tests/ui/uninlined_format_args_panic.rs:36:5
64+
--> tests/ui/uninlined_format_args_panic.rs:41:5
6565
|
6666
LL | debug_assert!(var == 1, "p6 {}", var);
6767
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,5 +72,41 @@ LL - debug_assert!(var == 1, "p6 {}", var);
7272
LL + debug_assert!(var == 1, "p6 {var}");
7373
|
7474

75-
error: aborting due to 6 previous errors
75+
error: variables can be used directly in the `format!` string
76+
--> tests/ui/uninlined_format_args_panic.rs:47:9
77+
|
78+
LL | core::panic!("p7 {}", var);
79+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
80+
|
81+
help: change this to
82+
|
83+
LL - core::panic!("p7 {}", var);
84+
LL + core::panic!("p7 {var}");
85+
|
86+
87+
error: variables can be used directly in the `format!` string
88+
--> tests/ui/uninlined_format_args_panic.rs:52:9
89+
|
90+
LL | core::panic!("p8 {0}", var);
91+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
92+
|
93+
help: change this to
94+
|
95+
LL - core::panic!("p8 {0}", var);
96+
LL + core::panic!("p8 {var}");
97+
|
98+
99+
error: variables can be used directly in the `format!` string
100+
--> tests/ui/uninlined_format_args_panic.rs:57:9
101+
|
102+
LL | core::panic!("p9 {var}", var = var);
103+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
104+
|
105+
help: change this to
106+
|
107+
LL - core::panic!("p9 {var}", var = var);
108+
LL + core::panic!("p9 {var}");
109+
|
110+
111+
error: aborting due to 9 previous errors
76112

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//@revisions: edition2018 edition2021 edition2024
2+
//@[edition2018] edition:2018
3+
//@[edition2021] edition:2021
4+
//@[edition2024] edition:2024
5+
6+
#![warn(clippy::uninlined_format_args)]
7+
#![allow(clippy::literal_string_with_formatting_args)]
8+
9+
fn main() {
10+
let var = 1;
11+
12+
println!("val='{var}'");
13+
//~^ uninlined_format_args
14+
15+
if var > 0 {
16+
panic!("p1 {var}");
17+
//~[edition2021]^ uninlined_format_args
18+
//~[edition2024]^^ uninlined_format_args
19+
}
20+
if var > 0 {
21+
panic!("p2 {var}");
22+
//~[edition2021]^ uninlined_format_args
23+
//~[edition2024]^^ uninlined_format_args
24+
}
25+
if var > 0 {
26+
panic!("p3 {var}");
27+
//~[edition2021]^ uninlined_format_args
28+
//~[edition2024]^^ uninlined_format_args
29+
}
30+
31+
#[allow(non_fmt_panics)]
32+
{
33+
if var > 0 {
34+
panic!("p4 {var}");
35+
}
36+
}
37+
38+
assert!(var == 1, "p5 {var}");
39+
//~[edition2021]^ uninlined_format_args
40+
//~[edition2024]^^ uninlined_format_args
41+
debug_assert!(var == 1, "p6 {var}");
42+
//~[edition2021]^ uninlined_format_args
43+
//~[edition2024]^^ uninlined_format_args
44+
45+
// core::panic! with format string containing text: should warn on 2021+ (issue #16411)
46+
if var > 0 {
47+
core::panic!("p7 {var}");
48+
//~[edition2021]^ uninlined_format_args
49+
//~[edition2024]^^ uninlined_format_args
50+
}
51+
if var > 0 {
52+
core::panic!("p8 {var}");
53+
//~[edition2021]^ uninlined_format_args
54+
//~[edition2024]^^ uninlined_format_args
55+
}
56+
if var > 0 {
57+
core::panic!("p9 {var}");
58+
//~[edition2021]^ uninlined_format_args
59+
//~[edition2024]^^ uninlined_format_args
60+
}
61+
62+
// std::panic! and core::panic! with only "{}" format string: false negative due to
63+
// panic_display special case in panic_2021 macro - no format_args node is created
64+
if var > 0 {
65+
std::panic!("{}", var);
66+
}
67+
if var > 0 {
68+
core::panic!("{}", var);
69+
}
70+
}

0 commit comments

Comments
 (0)