mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-12-18 00:53:31 +00:00
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
This commit is contained in:
commit
2d588175ca
10 changed files with 239 additions and 5 deletions
|
@ -1,6 +1,6 @@
|
||||||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
||||||
use clippy_utils::macros::FormatParamKind::{Implicit, Named, Numbered, Starred};
|
use clippy_utils::macros::FormatParamKind::{Implicit, Named, Numbered, Starred};
|
||||||
use clippy_utils::macros::{is_format_macro, FormatArgsExpn, FormatParam, FormatParamUsage};
|
use clippy_utils::macros::{is_format_macro, is_panic, FormatArgsExpn, FormatParam, FormatParamUsage};
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::snippet_opt;
|
||||||
use clippy_utils::ty::implements_trait;
|
use clippy_utils::ty::implements_trait;
|
||||||
use clippy_utils::{is_diag_trait_item, meets_msrv, msrvs};
|
use clippy_utils::{is_diag_trait_item, meets_msrv, msrvs};
|
||||||
|
@ -13,6 +13,8 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment};
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_semver::RustcVersion;
|
use rustc_semver::RustcVersion;
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
|
use rustc_span::def_id::DefId;
|
||||||
|
use rustc_span::edition::Edition::Edition2021;
|
||||||
use rustc_span::{sym, ExpnData, ExpnKind, Span, Symbol};
|
use rustc_span::{sym, ExpnData, ExpnKind, Span, Symbol};
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -149,7 +151,7 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
|
||||||
check_to_string_in_format_args(cx, name, arg.param.value);
|
check_to_string_in_format_args(cx, name, arg.param.value);
|
||||||
}
|
}
|
||||||
if meets_msrv(self.msrv, msrvs::FORMAT_ARGS_CAPTURE) {
|
if meets_msrv(self.msrv, msrvs::FORMAT_ARGS_CAPTURE) {
|
||||||
check_uninlined_args(cx, &format_args, outermost_expn_data.call_site);
|
check_uninlined_args(cx, &format_args, outermost_expn_data.call_site, macro_def_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,10 +160,14 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
|
||||||
extract_msrv_attr!(LateContext);
|
extract_msrv_attr!(LateContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_uninlined_args(cx: &LateContext<'_>, args: &FormatArgsExpn<'_>, call_site: Span) {
|
fn check_uninlined_args(cx: &LateContext<'_>, args: &FormatArgsExpn<'_>, call_site: Span, def_id: DefId) {
|
||||||
if args.format_string.span.from_expansion() {
|
if args.format_string.span.from_expansion() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if call_site.edition() < Edition2021 && is_panic(cx, def_id) {
|
||||||
|
// panic! before 2021 edition considers a single string argument as non-format
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut fixes = Vec::new();
|
let mut fixes = Vec::new();
|
||||||
// If any of the arguments are referenced by an index number,
|
// If any of the arguments are referenced by an index number,
|
||||||
|
|
|
@ -150,6 +150,19 @@ fn tester(fn_arg: i32) {
|
||||||
|
|
||||||
println!(with_span!("{0} {1}" "{1} {0}"), local_i32, local_f64);
|
println!(with_span!("{0} {1}" "{1} {0}"), local_i32, local_f64);
|
||||||
println!("{}", with_span!(span val));
|
println!("{}", with_span!(span val));
|
||||||
|
|
||||||
|
if local_i32 > 0 {
|
||||||
|
panic!("p1 {local_i32}");
|
||||||
|
}
|
||||||
|
if local_i32 > 0 {
|
||||||
|
panic!("p2 {local_i32}");
|
||||||
|
}
|
||||||
|
if local_i32 > 0 {
|
||||||
|
panic!("p3 {local_i32}");
|
||||||
|
}
|
||||||
|
if local_i32 > 0 {
|
||||||
|
panic!("p4 {local_i32}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -150,6 +150,19 @@ fn tester(fn_arg: i32) {
|
||||||
|
|
||||||
println!(with_span!("{0} {1}" "{1} {0}"), local_i32, local_f64);
|
println!(with_span!("{0} {1}" "{1} {0}"), local_i32, local_f64);
|
||||||
println!("{}", with_span!(span val));
|
println!("{}", with_span!(span val));
|
||||||
|
|
||||||
|
if local_i32 > 0 {
|
||||||
|
panic!("p1 {}", local_i32);
|
||||||
|
}
|
||||||
|
if local_i32 > 0 {
|
||||||
|
panic!("p2 {0}", local_i32);
|
||||||
|
}
|
||||||
|
if local_i32 > 0 {
|
||||||
|
panic!("p3 {local_i32}", local_i32 = local_i32);
|
||||||
|
}
|
||||||
|
if local_i32 > 0 {
|
||||||
|
panic!("p4 {local_i32}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -828,7 +828,43 @@ LL + println!("{val}");
|
||||||
|
|
|
|
||||||
|
|
||||||
error: variables can be used directly in the `format!` string
|
error: variables can be used directly in the `format!` string
|
||||||
--> $DIR/uninlined_format_args.rs:168:5
|
--> $DIR/uninlined_format_args.rs:155:9
|
||||||
|
|
|
||||||
|
LL | panic!("p1 {}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - panic!("p1 {}", local_i32);
|
||||||
|
LL + panic!("p1 {local_i32}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:158:9
|
||||||
|
|
|
||||||
|
LL | panic!("p2 {0}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - panic!("p2 {0}", local_i32);
|
||||||
|
LL + panic!("p2 {local_i32}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:161:9
|
||||||
|
|
|
||||||
|
LL | panic!("p3 {local_i32}", local_i32 = local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - panic!("p3 {local_i32}", local_i32 = local_i32);
|
||||||
|
LL + panic!("p3 {local_i32}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:181:5
|
||||||
|
|
|
|
||||||
LL | println!("expand='{}'", local_i32);
|
LL | println!("expand='{}'", local_i32);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -839,5 +875,5 @@ LL - println!("expand='{}'", local_i32);
|
||||||
LL + println!("expand='{local_i32}'");
|
LL + println!("expand='{local_i32}'");
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 70 previous errors
|
error: aborting due to 73 previous errors
|
||||||
|
|
||||||
|
|
27
tests/ui/uninlined_format_args_2018.fixed
Normal file
27
tests/ui/uninlined_format_args_2018.fixed
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// run-rustfix
|
||||||
|
// edition:2018
|
||||||
|
|
||||||
|
#![warn(clippy::uninlined_format_args)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let var = 1;
|
||||||
|
|
||||||
|
println!("val='{var}'");
|
||||||
|
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p1 {}", var);
|
||||||
|
}
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p2 {0}", var);
|
||||||
|
}
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p3 {var}", var = var);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_fmt_panics)]
|
||||||
|
{
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p4 {var}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
tests/ui/uninlined_format_args_2018.rs
Normal file
27
tests/ui/uninlined_format_args_2018.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// run-rustfix
|
||||||
|
// edition:2018
|
||||||
|
|
||||||
|
#![warn(clippy::uninlined_format_args)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let var = 1;
|
||||||
|
|
||||||
|
println!("val='{}'", var);
|
||||||
|
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p1 {}", var);
|
||||||
|
}
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p2 {0}", var);
|
||||||
|
}
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p3 {var}", var = var);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_fmt_panics)]
|
||||||
|
{
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p4 {var}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
tests/ui/uninlined_format_args_2018.stderr
Normal file
15
tests/ui/uninlined_format_args_2018.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args_2018.rs:9:5
|
||||||
|
|
|
||||||
|
LL | println!("val='{}'", var);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::uninlined-format-args` implied by `-D warnings`
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("val='{}'", var);
|
||||||
|
LL + println!("val='{var}'");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
23
tests/ui/uninlined_format_args_2021.fixed
Normal file
23
tests/ui/uninlined_format_args_2021.fixed
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// run-rustfix
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
#![warn(clippy::uninlined_format_args)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let var = 1;
|
||||||
|
|
||||||
|
println!("val='{var}'");
|
||||||
|
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p1 {var}");
|
||||||
|
}
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p2 {var}");
|
||||||
|
}
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p3 {var}");
|
||||||
|
}
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p4 {var}");
|
||||||
|
}
|
||||||
|
}
|
23
tests/ui/uninlined_format_args_2021.rs
Normal file
23
tests/ui/uninlined_format_args_2021.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// run-rustfix
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
#![warn(clippy::uninlined_format_args)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let var = 1;
|
||||||
|
|
||||||
|
println!("val='{}'", var);
|
||||||
|
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p1 {}", var);
|
||||||
|
}
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p2 {0}", var);
|
||||||
|
}
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p3 {var}", var = var);
|
||||||
|
}
|
||||||
|
if var > 0 {
|
||||||
|
panic!("p4 {var}");
|
||||||
|
}
|
||||||
|
}
|
51
tests/ui/uninlined_format_args_2021.stderr
Normal file
51
tests/ui/uninlined_format_args_2021.stderr
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args_2021.rs:9:5
|
||||||
|
|
|
||||||
|
LL | println!("val='{}'", var);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::uninlined-format-args` implied by `-D warnings`
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("val='{}'", var);
|
||||||
|
LL + println!("val='{var}'");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args_2021.rs:12:9
|
||||||
|
|
|
||||||
|
LL | panic!("p1 {}", var);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - panic!("p1 {}", var);
|
||||||
|
LL + panic!("p1 {var}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args_2021.rs:15:9
|
||||||
|
|
|
||||||
|
LL | panic!("p2 {0}", var);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - panic!("p2 {0}", var);
|
||||||
|
LL + panic!("p2 {var}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args_2021.rs:18:9
|
||||||
|
|
|
||||||
|
LL | panic!("p3 {var}", var = var);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - panic!("p3 {var}", var = var);
|
||||||
|
LL + panic!("p3 {var}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
Loading…
Reference in a new issue