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:
bors 2022-10-12 07:16:23 +00:00
commit 2d588175ca
10 changed files with 239 additions and 5 deletions

View file

@ -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,

View file

@ -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() {

View file

@ -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() {

View file

@ -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

View 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}");
}
}
}

View 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}");
}
}
}

View 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

View 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}");
}
}

View 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}");
}
}

View 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