about summary refs log tree commit diff
path: root/compiler/rustc_parse_format/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-01-01 08:10:15 +0000
committerbors <bors@rust-lang.org>2025-01-01 08:10:15 +0000
commitbc3e3015b6e449bf1607f1023d2fbc2838ee37af (patch)
tree2de9a6a6ed034eb305f918fdba7ebfd7c05c4f26 /compiler/rustc_parse_format/src
parenta8953d83cfcb7caacc8d68951a32455f28265467 (diff)
parent65cb7c66d0277571f0412d29fd237ea038b8c389 (diff)
downloadrust-bc3e3015b6e449bf1607f1023d2fbc2838ee37af.tar.gz
rust-bc3e3015b6e449bf1607f1023d2fbc2838ee37af.zip
Auto merge of #134992 - Zalathar:rollup-pldy5w6, r=Zalathar
Rollup of 6 pull requests

Successful merges:

 - #131439 (Remove allowing static_mut_refs lint)
 - #133292 (E0277: suggest dereferencing function arguments in more cases)
 - #134877 (add suggestion for wrongly ordered format parameters)
 - #134945 (Some small nits to the borrowck suggestions for mutating a map through index)
 - #134950 (bootstrap: Overhaul and simplify the `tool_check_step!` macro)
 - #134979 (Provide structured suggestion for `impl Default` of type where all fields have defaults)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse_format/src')
-rw-r--r--compiler/rustc_parse_format/src/lib.rs35
1 files changed, 35 insertions, 0 deletions
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 1716f417969..9eb335cb34c 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -221,6 +221,11 @@ pub enum Suggestion {
     /// Remove `r#` from identifier:
     /// `format!("{r#foo}")` -> `format!("{foo}")`
     RemoveRawIdent(InnerSpan),
+    /// Reorder format parameter:
+    /// `format!("{foo:?#}")` -> `format!("{foo:#?}")`
+    /// `format!("{foo:?x}")` -> `format!("{foo:x?}")`
+    /// `format!("{foo:?X}")` -> `format!("{foo:X?}")`
+    ReorderFormatParameter(InnerSpan, string::String),
 }
 
 /// The parser structure for interpreting the input format string. This is
@@ -731,6 +736,12 @@ impl<'a> Parser<'a> {
             }
         } else if self.consume('?') {
             spec.ty = "?";
+            if let Some(&(_, maybe)) = self.cur.peek() {
+                match maybe {
+                    '#' | 'x' | 'X' => self.suggest_format_parameter(maybe),
+                    _ => (),
+                }
+            }
         } else {
             spec.ty = self.word();
             if !spec.ty.is_empty() {
@@ -932,6 +943,30 @@ impl<'a> Parser<'a> {
             }
         }
     }
+
+    fn suggest_format_parameter(&mut self, c: char) {
+        let replacement = match c {
+            '#' => "#?",
+            'x' => "x?",
+            'X' => "X?",
+            _ => return,
+        };
+        let Some(pos) = self.consume_pos(c) else {
+            return;
+        };
+
+        let span = self.span(pos - 1, pos + 1);
+        let pos = self.to_span_index(pos);
+
+        self.errors.insert(0, ParseError {
+            description: format!("expected `}}`, found `{c}`"),
+            note: None,
+            label: "expected `'}'`".into(),
+            span: pos.to(pos),
+            secondary_label: None,
+            suggestion: Suggestion::ReorderFormatParameter(span, format!("{replacement}")),
+        })
+    }
 }
 
 /// Finds the indices of all characters that have been processed and differ between the actual