about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros
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 /compiler/rustc_builtin_macros
parente656e52ccb33f92ca8bfd7ad78ee5b028ff61a62 (diff)
downloadrust-1e733b389192b48110779bc1cd8edcaed7c43b0e.tar.gz
rust-1e733b389192b48110779bc1cd8edcaed7c43b0e.zip
Implement better suggestions based on additional tests and other code paths
Diffstat (limited to 'compiler/rustc_builtin_macros')
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs58
1 files changed, 38 insertions, 20 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();