about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIoaNNUwU <ioannxd@gmail.com>2025-09-02 23:53:54 +0200
committerIoaNNUwU <ioannxd@gmail.com>2025-09-08 17:35:40 +0200
commit1e733b389192b48110779bc1cd8edcaed7c43b0e (patch)
tree634b7a249095214195f860b591daf1ef85865c43
parente656e52ccb33f92ca8bfd7ad78ee5b028ff61a62 (diff)
downloadrust-1e733b389192b48110779bc1cd8edcaed7c43b0e.tar.gz
rust-1e733b389192b48110779bc1cd8edcaed7c43b0e.zip
Implement better suggestions based on additional tests and other code paths
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs58
-rw-r--r--tests/ui/fmt/ifmt-bad-arg.stderr14
-rw-r--r--tests/ui/macros/format-unused-lables.stderr18
-rw-r--r--tests/ui/mir/unsized-extern-static.stderr6
-rw-r--r--tests/ui/suggestions/missing-format-specifiers-issue-68293.rs1
-rw-r--r--tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr10
6 files changed, 78 insertions, 29 deletions
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index ce9bda10721..e5f73188dbd 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<Span>, PositionUsedAs, FormatArgPositionKind)],
     detect_foreign_fmt: bool,
     str_style: Option<usize>,
     fmt_str: &str,
@@ -758,31 +760,47 @@ fn report_missing_placeholders(
             check_foreign!(shell);
         }
     }
-    if !found_foreign {
-        if unused.len() == 1 {
-            diag.span_label(fmt_span, "formatting specifier missing");
+    if !found_foreign && unused.len() == 1 {
+        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 && unused.len() > 1 {
+            diag.note(format!("consider adding {} format specifiers", unused.len()));
         }
-        if used.iter().all(|used| !used) {
+
+        let original_fmt_str = if fmt_str.len() >= 1 { &fmt_str[..fmt_str.len() - 1] } else { "" };
+
+        if show_example && unused.len() == 1 {
             diag.note("format specifiers use curly braces: `{}`");
-        }
 
-        let mut suggest_fixed_fmt = format!("\"{}", &fmt_str[..fmt_str.len() - 1]);
-        for _ in &unused {
-            suggest_fixed_fmt.push_str("{}");
+            diag.span_suggestion_verbose(
+                fmt_span,
+                "consider adding format specifier",
+                format!("\"{}{{}}\"", original_fmt_str),
+                Applicability::MaybeIncorrect,
+            );
         }
-        suggest_fixed_fmt.push('"');
 
-        let suggest_fmt_count = if unused.len() == 1 {
-            "consider adding format specifier".to_string()
-        } else {
-            format!("consider adding {} format specifiers", unused.len())
-        };
-        diag.span_suggestion_verbose(
-            fmt_span,
-            suggest_fmt_count,
-            suggest_fixed_fmt,
-            Applicability::MaybeIncorrect,
-        );
+        if show_example && unused.len() > 1 {
+            diag.note("format specifiers use curly braces: `{}`");
+
+            let mut suggest_fixed_fmt = format!("\"{}", original_fmt_str);
+            for _ in &unused {
+                suggest_fixed_fmt.push_str("{}");
+            }
+            suggest_fixed_fmt.push('"');
+
+            diag.span_suggestion_verbose(
+                fmt_span,
+                format!("consider adding {} format specifiers", unused.len()),
+                suggest_fixed_fmt,
+                Applicability::MaybeIncorrect,
+            );
+        }
     }
 
     diag.emit();
diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr
index 4344aee83c2..6ddc8172901 100644
--- a/tests/ui/fmt/ifmt-bad-arg.stderr
+++ b/tests/ui/fmt/ifmt-bad-arg.stderr
@@ -62,6 +62,12 @@ LL |     format!("", 1, 2);
    |             |   |
    |             |   argument never used
    |             multiple missing formatting specifiers
+   |
+   = note: format specifiers use curly braces: `{}`
+help: consider adding 2 format specifiers
+   |
+LL |     format!("{}{}", 1, 2);
+   |              ++++
 
 error: argument never used
   --> $DIR/ifmt-bad-arg.rs:33:22
@@ -102,6 +108,12 @@ LL |     format!("", foo=2);
    |             --      ^ named argument never used
    |             |
    |             formatting specifier missing
+   |
+   = note: format specifiers use curly braces: `{}`
+help: consider adding format specifier
+   |
+LL |     format!("{}", foo=2);
+   |              ++
 
 error: multiple unused formatting arguments
   --> $DIR/ifmt-bad-arg.rs:38:32
@@ -111,6 +123,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 fad87fa2aee..1c5cdcc2346 100644
--- a/tests/ui/macros/format-unused-lables.stderr
+++ b/tests/ui/macros/format-unused-lables.stderr
@@ -7,6 +7,12 @@ LL |     println!("Test", 123, 456, 789);
    |              |       |    argument never used
    |              |       argument never used
    |              multiple missing formatting specifiers
+   |
+   = note: format specifiers use curly braces: `{}`
+help: 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 +25,12 @@ LL |         456,
    |         ^^^ argument never used
 LL |         789
    |         ^^^ argument never used
+   |
+   = note: format specifiers use curly braces: `{}`
+help: consider adding 3 format specifiers
+   |
+LL |     println!("Test2{}{}{}",
+   |                    ++++++
 
 error: named argument never used
   --> $DIR/format-unused-lables.rs:11:35
@@ -27,6 +39,12 @@ LL |     println!("Some stuff", UNUSED="args");
    |              ------------         ^^^^^^ named argument never used
    |              |
    |              formatting specifier missing
+   |
+   = note: format specifiers use curly braces: `{}`
+help: consider adding 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 93aed3549d7..005dc59d78f 100644
--- a/tests/ui/mir/unsized-extern-static.stderr
+++ b/tests/ui/mir/unsized-extern-static.stderr
@@ -5,6 +5,12 @@ LL |     println!("C", unsafe { &symbol });
    |              ---  ^^^^^^^^^^^^^^^^^^ argument never used
    |              |
    |              formatting specifier missing
+   |
+   = note: format specifiers use curly braces: `{}`
+help: consider adding 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
index e1f8710db5a..2f5e9629441 100644
--- a/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs
+++ b/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs
@@ -29,6 +29,7 @@ fn missing_format_specifiers_multiple_unused_args() {
     //~| 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
index 654c8b0712a..961887a7e3f 100644
--- a/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr
+++ b/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr
@@ -35,11 +35,6 @@ LL |     println!("list: {}, {}", 1, 2, 3);
    |              --------------        ^ argument never used
    |              |
    |              formatting specifier missing
-   |
-help: consider adding format specifier
-   |
-LL |     println!("list: {}, {}{}", 1, 2, 3);
-   |                           ++
 
 error: multiple unused formatting arguments
   --> $DIR/missing-format-specifiers-issue-68293.rs:27:29
@@ -50,10 +45,7 @@ LL |     println!("list: {}", 1, 2, 3);
    |              |              argument never used
    |              multiple missing formatting specifiers
    |
-help: consider adding 2 format specifiers
-   |
-LL |     println!("list: {}{}{}", 1, 2, 3);
-   |                       ++++
+   = note: consider adding 2 format specifiers
 
 error: aborting due to 4 previous errors