diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 6415e55e0b034..a6c8e7d29cc7a 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -565,6 +565,7 @@ fn make_format_args( &used, &args, &pieces, + &invalid_refs, detect_foreign_fmt, str_style, fmt_str, @@ -645,6 +646,7 @@ fn report_missing_placeholders( used: &[bool], args: &FormatArguments, pieces: &[parse::Piece<'_>], + invalid_refs: &[(usize, Option, PositionUsedAs, FormatArgPositionKind)], detect_foreign_fmt: bool, str_style: Option, fmt_str: &str, @@ -762,6 +764,31 @@ fn report_missing_placeholders( diag.span_label(fmt_span, "formatting specifier missing"); } + if !found_foreign && invalid_refs.is_empty() { + // Show example if user didn't use any format specifiers + let show_example = used.iter().all(|used| !used); + + if !show_example { + if unused.len() > 1 { + diag.note(format!("consider adding {} format specifiers", unused.len())); + } + } else { + let original_fmt_str = + if fmt_str.len() >= 1 { &fmt_str[..fmt_str.len() - 1] } else { "" }; + + let msg = if unused.len() == 1 { + "a format specifier".to_string() + } else { + format!("{} format specifiers", unused.len()) + }; + + let sugg = format!("\"{}{}\"", original_fmt_str, "{}".repeat(unused.len())); + let msg = format!("format specifiers use curly braces, consider adding {msg}"); + + diag.span_suggestion_verbose(fmt_span, msg, sugg, Applicability::MaybeIncorrect); + } + } + diag.emit(); } diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr index 4344aee83c2b1..b565b836f211e 100644 --- a/tests/ui/fmt/ifmt-bad-arg.stderr +++ b/tests/ui/fmt/ifmt-bad-arg.stderr @@ -62,6 +62,11 @@ LL | format!("", 1, 2); | | | | | argument never used | multiple missing formatting specifiers + | +help: format specifiers use curly braces, consider adding 2 format specifiers + | +LL | format!("{}{}", 1, 2); + | ++++ error: argument never used --> $DIR/ifmt-bad-arg.rs:33:22 @@ -102,6 +107,11 @@ LL | format!("", foo=2); | -- ^ named argument never used | | | formatting specifier missing + | +help: format specifiers use curly braces, consider adding a format specifier + | +LL | format!("{}", foo=2); + | ++ error: multiple unused formatting arguments --> $DIR/ifmt-bad-arg.rs:38:32 @@ -111,6 +121,8 @@ LL | format!("{} {}", 1, 2, foo=1, bar=2); | | | | | named argument never used | multiple missing formatting specifiers + | + = note: consider adding 2 format specifiers error: duplicate argument named `foo` --> $DIR/ifmt-bad-arg.rs:40:29 diff --git a/tests/ui/macros/format-unused-lables.stderr b/tests/ui/macros/format-unused-lables.stderr index fad87fa2aeea8..90eed8dd86b5a 100644 --- a/tests/ui/macros/format-unused-lables.stderr +++ b/tests/ui/macros/format-unused-lables.stderr @@ -7,6 +7,11 @@ LL | println!("Test", 123, 456, 789); | | | argument never used | | argument never used | multiple missing formatting specifiers + | +help: format specifiers use curly braces, consider adding 3 format specifiers + | +LL | println!("Test{}{}{}", 123, 456, 789); + | ++++++ error: multiple unused formatting arguments --> $DIR/format-unused-lables.rs:6:9 @@ -19,6 +24,11 @@ LL | 456, | ^^^ argument never used LL | 789 | ^^^ argument never used + | +help: format specifiers use curly braces, consider adding 3 format specifiers + | +LL | println!("Test2{}{}{}", + | ++++++ error: named argument never used --> $DIR/format-unused-lables.rs:11:35 @@ -27,6 +37,11 @@ LL | println!("Some stuff", UNUSED="args"); | ------------ ^^^^^^ named argument never used | | | formatting specifier missing + | +help: format specifiers use curly braces, consider adding a format specifier + | +LL | println!("Some stuff{}", UNUSED="args"); + | ++ error: multiple unused formatting arguments --> $DIR/format-unused-lables.rs:14:9 diff --git a/tests/ui/mir/unsized-extern-static.stderr b/tests/ui/mir/unsized-extern-static.stderr index 93aed3549d762..c0810e650ef12 100644 --- a/tests/ui/mir/unsized-extern-static.stderr +++ b/tests/ui/mir/unsized-extern-static.stderr @@ -5,6 +5,11 @@ LL | println!("C", unsafe { &symbol }); | --- ^^^^^^^^^^^^^^^^^^ argument never used | | | formatting specifier missing + | +help: format specifiers use curly braces, consider adding a format specifier + | +LL | println!("C{}", unsafe { &symbol }); + | ++ error[E0277]: the size for values of type `[i8]` cannot be known at compilation time --> $DIR/unsized-extern-static.rs:6:5 diff --git a/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs b/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs new file mode 100644 index 0000000000000..29799624d7821 --- /dev/null +++ b/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs @@ -0,0 +1,35 @@ +fn no_format_specifier_two_unused_args() { + println!("Hello", "World"); + //~^ ERROR argument never used + //~| NOTE formatting specifier missing + //~| NOTE argument never used + //~| HELP format specifiers use curly braces, consider adding a format specifier +} + +fn no_format_specifier_multiple_unused_args() { + println!("list: ", 1, 2, 3); + //~^ ERROR multiple unused formatting arguments + //~| NOTE multiple missing formatting specifiers + //~| NOTE argument never used + //~| NOTE argument never used + //~| NOTE argument never used + //~| HELP format specifiers use curly braces, consider adding 3 format specifiers +} + +fn missing_format_specifiers_one_unused_arg() { + println!("list: {}, {}", 1, 2, 3); + //~^ ERROR argument never used + //~| NOTE formatting specifier missing + //~| NOTE argument never used +} + +fn missing_format_specifiers_multiple_unused_args() { + println!("list: {}", 1, 2, 3); + //~^ ERROR multiple unused formatting arguments + //~| NOTE multiple missing formatting specifiers + //~| NOTE argument never used + //~| NOTE argument never used + //~| NOTE consider adding 2 format specifiers +} + +fn main() { } diff --git a/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr b/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr new file mode 100644 index 0000000000000..081409789f5a4 --- /dev/null +++ b/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr @@ -0,0 +1,49 @@ +error: argument never used + --> $DIR/missing-format-specifiers-issue-68293.rs:2:23 + | +LL | println!("Hello", "World"); + | ------- ^^^^^^^ argument never used + | | + | formatting specifier missing + | +help: format specifiers use curly braces, consider adding a format specifier + | +LL | println!("Hello{}", "World"); + | ++ + +error: multiple unused formatting arguments + --> $DIR/missing-format-specifiers-issue-68293.rs:10:24 + | +LL | println!("list: ", 1, 2, 3); + | -------- ^ ^ ^ argument never used + | | | | + | | | argument never used + | | argument never used + | multiple missing formatting specifiers + | +help: format specifiers use curly braces, consider adding 3 format specifiers + | +LL | println!("list: {}{}{}", 1, 2, 3); + | ++++++ + +error: argument never used + --> $DIR/missing-format-specifiers-issue-68293.rs:20:36 + | +LL | println!("list: {}, {}", 1, 2, 3); + | -------------- ^ argument never used + | | + | formatting specifier missing + +error: multiple unused formatting arguments + --> $DIR/missing-format-specifiers-issue-68293.rs:27:29 + | +LL | println!("list: {}", 1, 2, 3); + | ---------- ^ ^ argument never used + | | | + | | argument never used + | multiple missing formatting specifiers + | + = note: consider adding 2 format specifiers + +error: aborting due to 4 previous errors +