Skip to content

Commit 2d58817

Browse files
committed
Auto merge of #9605 - nyurik:fix-inline-edition, r=llogiq
fix: uninlined_format_args shouldn't inline panic! before 2021ed Before 2021 edition, `panic!("...")` was not treated as a format string. Clippy autofix of `panic!("{}", foo)` into `panic!("{foo}")` is incorrect. changelog: [`uninlined_format_args`]: Do not inline panic! macros before 2021 edition
2 parents 854015c + 74ba7e1 commit 2d58817

10 files changed

+239
-5
lines changed

clippy_lints/src/format_args.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
22
use clippy_utils::macros::FormatParamKind::{Implicit, Named, Numbered, Starred};
3-
use clippy_utils::macros::{is_format_macro, FormatArgsExpn, FormatParam, FormatParamUsage};
3+
use clippy_utils::macros::{is_format_macro, is_panic, FormatArgsExpn, FormatParam, FormatParamUsage};
44
use clippy_utils::source::snippet_opt;
55
use clippy_utils::ty::implements_trait;
66
use clippy_utils::{is_diag_trait_item, meets_msrv, msrvs};
@@ -13,6 +13,8 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment};
1313
use rustc_middle::ty::Ty;
1414
use rustc_semver::RustcVersion;
1515
use rustc_session::{declare_tool_lint, impl_lint_pass};
16+
use rustc_span::def_id::DefId;
17+
use rustc_span::edition::Edition::Edition2021;
1618
use rustc_span::{sym, ExpnData, ExpnKind, Span, Symbol};
1719

1820
declare_clippy_lint! {
@@ -149,7 +151,7 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
149151
check_to_string_in_format_args(cx, name, arg.param.value);
150152
}
151153
if meets_msrv(self.msrv, msrvs::FORMAT_ARGS_CAPTURE) {
152-
check_uninlined_args(cx, &format_args, outermost_expn_data.call_site);
154+
check_uninlined_args(cx, &format_args, outermost_expn_data.call_site, macro_def_id);
153155
}
154156
}
155157
}
@@ -158,10 +160,14 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
158160
extract_msrv_attr!(LateContext);
159161
}
160162

161-
fn check_uninlined_args(cx: &LateContext<'_>, args: &FormatArgsExpn<'_>, call_site: Span) {
163+
fn check_uninlined_args(cx: &LateContext<'_>, args: &FormatArgsExpn<'_>, call_site: Span, def_id: DefId) {
162164
if args.format_string.span.from_expansion() {
163165
return;
164166
}
167+
if call_site.edition() < Edition2021 && is_panic(cx, def_id) {
168+
// panic! before 2021 edition considers a single string argument as non-format
169+
return;
170+
}
165171

166172
let mut fixes = Vec::new();
167173
// If any of the arguments are referenced by an index number,

tests/ui/uninlined_format_args.fixed

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,19 @@ fn tester(fn_arg: i32) {
150150

151151
println!(with_span!("{0} {1}" "{1} {0}"), local_i32, local_f64);
152152
println!("{}", with_span!(span val));
153+
154+
if local_i32 > 0 {
155+
panic!("p1 {local_i32}");
156+
}
157+
if local_i32 > 0 {
158+
panic!("p2 {local_i32}");
159+
}
160+
if local_i32 > 0 {
161+
panic!("p3 {local_i32}");
162+
}
163+
if local_i32 > 0 {
164+
panic!("p4 {local_i32}");
165+
}
153166
}
154167

155168
fn main() {

tests/ui/uninlined_format_args.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,19 @@ fn tester(fn_arg: i32) {
150150

151151
println!(with_span!("{0} {1}" "{1} {0}"), local_i32, local_f64);
152152
println!("{}", with_span!(span val));
153+
154+
if local_i32 > 0 {
155+
panic!("p1 {}", local_i32);
156+
}
157+
if local_i32 > 0 {
158+
panic!("p2 {0}", local_i32);
159+
}
160+
if local_i32 > 0 {
161+
panic!("p3 {local_i32}", local_i32 = local_i32);
162+
}
163+
if local_i32 > 0 {
164+
panic!("p4 {local_i32}");
165+
}
153166
}
154167

155168
fn main() {

tests/ui/uninlined_format_args.stderr

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,43 @@ LL + println!("{val}");
828828
|
829829

830830
error: variables can be used directly in the `format!` string
831-
--> $DIR/uninlined_format_args.rs:168:5
831+
--> $DIR/uninlined_format_args.rs:155:9
832+
|
833+
LL | panic!("p1 {}", local_i32);
834+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
835+
|
836+
help: change this to
837+
|
838+
LL - panic!("p1 {}", local_i32);
839+
LL + panic!("p1 {local_i32}");
840+
|
841+
842+
error: variables can be used directly in the `format!` string
843+
--> $DIR/uninlined_format_args.rs:158:9
844+
|
845+
LL | panic!("p2 {0}", local_i32);
846+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
847+
|
848+
help: change this to
849+
|
850+
LL - panic!("p2 {0}", local_i32);
851+
LL + panic!("p2 {local_i32}");
852+
|
853+
854+
error: variables can be used directly in the `format!` string
855+
--> $DIR/uninlined_format_args.rs:161:9
856+
|
857+
LL | panic!("p3 {local_i32}", local_i32 = local_i32);
858+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
859+
|
860+
help: change this to
861+
|
862+
LL - panic!("p3 {local_i32}", local_i32 = local_i32);
863+
LL + panic!("p3 {local_i32}");
864+
|
865+
866+
error: variables can be used directly in the `format!` string
867+
--> $DIR/uninlined_format_args.rs:181:5
832868
|
833869
LL | println!("expand='{}'", local_i32);
834870
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -839,5 +875,5 @@ LL - println!("expand='{}'", local_i32);
839875
LL + println!("expand='{local_i32}'");
840876
|
841877

842-
error: aborting due to 70 previous errors
878+
error: aborting due to 73 previous errors
843879

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// run-rustfix
2+
// edition:2018
3+
4+
#![warn(clippy::uninlined_format_args)]
5+
6+
fn main() {
7+
let var = 1;
8+
9+
println!("val='{var}'");
10+
11+
if var > 0 {
12+
panic!("p1 {}", var);
13+
}
14+
if var > 0 {
15+
panic!("p2 {0}", var);
16+
}
17+
if var > 0 {
18+
panic!("p3 {var}", var = var);
19+
}
20+
21+
#[allow(non_fmt_panics)]
22+
{
23+
if var > 0 {
24+
panic!("p4 {var}");
25+
}
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// run-rustfix
2+
// edition:2018
3+
4+
#![warn(clippy::uninlined_format_args)]
5+
6+
fn main() {
7+
let var = 1;
8+
9+
println!("val='{}'", var);
10+
11+
if var > 0 {
12+
panic!("p1 {}", var);
13+
}
14+
if var > 0 {
15+
panic!("p2 {0}", var);
16+
}
17+
if var > 0 {
18+
panic!("p3 {var}", var = var);
19+
}
20+
21+
#[allow(non_fmt_panics)]
22+
{
23+
if var > 0 {
24+
panic!("p4 {var}");
25+
}
26+
}
27+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: variables can be used directly in the `format!` string
2+
--> $DIR/uninlined_format_args_2018.rs:9:5
3+
|
4+
LL | println!("val='{}'", var);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `-D clippy::uninlined-format-args` implied by `-D warnings`
8+
help: change this to
9+
|
10+
LL - println!("val='{}'", var);
11+
LL + println!("val='{var}'");
12+
|
13+
14+
error: aborting due to previous error
15+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// run-rustfix
2+
// edition:2021
3+
4+
#![warn(clippy::uninlined_format_args)]
5+
6+
fn main() {
7+
let var = 1;
8+
9+
println!("val='{var}'");
10+
11+
if var > 0 {
12+
panic!("p1 {var}");
13+
}
14+
if var > 0 {
15+
panic!("p2 {var}");
16+
}
17+
if var > 0 {
18+
panic!("p3 {var}");
19+
}
20+
if var > 0 {
21+
panic!("p4 {var}");
22+
}
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// run-rustfix
2+
// edition:2021
3+
4+
#![warn(clippy::uninlined_format_args)]
5+
6+
fn main() {
7+
let var = 1;
8+
9+
println!("val='{}'", var);
10+
11+
if var > 0 {
12+
panic!("p1 {}", var);
13+
}
14+
if var > 0 {
15+
panic!("p2 {0}", var);
16+
}
17+
if var > 0 {
18+
panic!("p3 {var}", var = var);
19+
}
20+
if var > 0 {
21+
panic!("p4 {var}");
22+
}
23+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
error: variables can be used directly in the `format!` string
2+
--> $DIR/uninlined_format_args_2021.rs:9:5
3+
|
4+
LL | println!("val='{}'", var);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `-D clippy::uninlined-format-args` implied by `-D warnings`
8+
help: change this to
9+
|
10+
LL - println!("val='{}'", var);
11+
LL + println!("val='{var}'");
12+
|
13+
14+
error: variables can be used directly in the `format!` string
15+
--> $DIR/uninlined_format_args_2021.rs:12:9
16+
|
17+
LL | panic!("p1 {}", var);
18+
| ^^^^^^^^^^^^^^^^^^^^
19+
|
20+
help: change this to
21+
|
22+
LL - panic!("p1 {}", var);
23+
LL + panic!("p1 {var}");
24+
|
25+
26+
error: variables can be used directly in the `format!` string
27+
--> $DIR/uninlined_format_args_2021.rs:15:9
28+
|
29+
LL | panic!("p2 {0}", var);
30+
| ^^^^^^^^^^^^^^^^^^^^^
31+
|
32+
help: change this to
33+
|
34+
LL - panic!("p2 {0}", var);
35+
LL + panic!("p2 {var}");
36+
|
37+
38+
error: variables can be used directly in the `format!` string
39+
--> $DIR/uninlined_format_args_2021.rs:18:9
40+
|
41+
LL | panic!("p3 {var}", var = var);
42+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43+
|
44+
help: change this to
45+
|
46+
LL - panic!("p3 {var}", var = var);
47+
LL + panic!("p3 {var}");
48+
|
49+
50+
error: aborting due to 4 previous errors
51+

0 commit comments

Comments
 (0)