diff options
| author | Stuart Cook <Zalathar@users.noreply.github.com> | 2025-01-01 16:35:30 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-01 16:35:30 +1100 |
| commit | 1ea1db5b0875c579c9b9e4d078c2ee4bf0ffe6e5 (patch) | |
| tree | 8bdd10c1ab1834d3237f0139d1b1040e3aac157e | |
| parent | 0204259780aaf73d715709478c3e758607c39570 (diff) | |
| parent | 62c3c9a5ae2072a04ba5f5d84055d38dcd043427 (diff) | |
| download | rust-1ea1db5b0875c579c9b9e4d078c2ee4bf0ffe6e5.tar.gz rust-1ea1db5b0875c579c9b9e4d078c2ee4bf0ffe6e5.zip | |
Rollup merge of #134877 - DavisRayM:129966-format-string-help-message, r=estebank
add suggestion for wrongly ordered format parameters Add suggestion for wrongly ordered format parameters like `?#`. Supersedes #131004 Fix #129966
| -rw-r--r-- | compiler/rustc_builtin_macros/messages.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/errors.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/format.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_parse_format/src/lib.rs | 35 | ||||
| -rw-r--r-- | tests/ui/fmt/suggest-wrongly-order-format-parameter.fixed | 25 | ||||
| -rw-r--r-- | tests/ui/fmt/suggest-wrongly-order-format-parameter.rs | 25 | ||||
| -rw-r--r-- | tests/ui/fmt/suggest-wrongly-order-format-parameter.stderr | 35 |
7 files changed, 140 insertions, 0 deletions
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 7a31d2a2239..4cac7cb93f5 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -197,6 +197,8 @@ builtin_macros_format_redundant_args = redundant {$n -> builtin_macros_format_remove_raw_ident = remove the `r#` +builtin_macros_format_reorder_format_parameter = did you mean `{$replacement}`? + builtin_macros_format_requires_string = requires at least a format string argument builtin_macros_format_string_invalid = invalid format string: {$desc} diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 1abdfdb9c65..6213bd802c7 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -618,6 +618,17 @@ pub(crate) enum InvalidFormatStringSuggestion { #[primary_span] span: Span, }, + #[suggestion( + builtin_macros_format_reorder_format_parameter, + code = "{replacement}", + style = "verbose", + applicability = "machine-applicable" + )] + ReorderFormatParameter { + #[primary_span] + span: Span, + replacement: String, + }, } #[derive(Diagnostic)] diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 0112499c509..5202fe26c40 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -321,6 +321,13 @@ fn make_format_args( e.sugg_ = Some(errors::InvalidFormatStringSuggestion::RemoveRawIdent { span }) } } + parse::Suggestion::ReorderFormatParameter(span, replacement) => { + let span = fmt_span.from_inner(InnerSpan::new(span.start, span.end)); + e.sugg_ = Some(errors::InvalidFormatStringSuggestion::ReorderFormatParameter { + span, + replacement, + }); + } } let guar = ecx.dcx().emit_err(e); return ExpandResult::Ready(Err(guar)); 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 diff --git a/tests/ui/fmt/suggest-wrongly-order-format-parameter.fixed b/tests/ui/fmt/suggest-wrongly-order-format-parameter.fixed new file mode 100644 index 00000000000..a080a65854a --- /dev/null +++ b/tests/ui/fmt/suggest-wrongly-order-format-parameter.fixed @@ -0,0 +1,25 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/129966 +//! +//! Ensure we provide suggestion for wrongly ordered format parameters. + +//@ run-rustfix +#![allow(dead_code)] + +#[derive(Debug)] +struct Foo(u8, u8); + +fn main() { + let f = Foo(1, 2); + + println!("{f:#?}"); + //~^ ERROR invalid format string: expected `}`, found `#` + //~| HELP did you mean `#?`? + + println!("{f:x?}"); + //~^ ERROR invalid format string: expected `}`, found `x` + //~| HELP did you mean `x?`? + + println!("{f:X?}"); + //~^ ERROR invalid format string: expected `}`, found `X` + //~| HELP did you mean `X?`? +} diff --git a/tests/ui/fmt/suggest-wrongly-order-format-parameter.rs b/tests/ui/fmt/suggest-wrongly-order-format-parameter.rs new file mode 100644 index 00000000000..830dafd4479 --- /dev/null +++ b/tests/ui/fmt/suggest-wrongly-order-format-parameter.rs @@ -0,0 +1,25 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/129966 +//! +//! Ensure we provide suggestion for wrongly ordered format parameters. + +//@ run-rustfix +#![allow(dead_code)] + +#[derive(Debug)] +struct Foo(u8, u8); + +fn main() { + let f = Foo(1, 2); + + println!("{f:?#}"); + //~^ ERROR invalid format string: expected `}`, found `#` + //~| HELP did you mean `#?`? + + println!("{f:?x}"); + //~^ ERROR invalid format string: expected `}`, found `x` + //~| HELP did you mean `x?`? + + println!("{f:?X}"); + //~^ ERROR invalid format string: expected `}`, found `X` + //~| HELP did you mean `X?`? +} diff --git a/tests/ui/fmt/suggest-wrongly-order-format-parameter.stderr b/tests/ui/fmt/suggest-wrongly-order-format-parameter.stderr new file mode 100644 index 00000000000..fe693d2e904 --- /dev/null +++ b/tests/ui/fmt/suggest-wrongly-order-format-parameter.stderr @@ -0,0 +1,35 @@ +error: invalid format string: expected `}`, found `#` + --> $DIR/suggest-wrongly-order-format-parameter.rs:14:19 + | +LL | println!("{f:?#}"); + | ^ expected `'}'` in format string + | +help: did you mean `#?`? + | +LL | println!("{f:#?}"); + | ~~ + +error: invalid format string: expected `}`, found `x` + --> $DIR/suggest-wrongly-order-format-parameter.rs:18:19 + | +LL | println!("{f:?x}"); + | ^ expected `'}'` in format string + | +help: did you mean `x?`? + | +LL | println!("{f:x?}"); + | ~~ + +error: invalid format string: expected `}`, found `X` + --> $DIR/suggest-wrongly-order-format-parameter.rs:22:19 + | +LL | println!("{f:?X}"); + | ^ expected `'}'` in format string + | +help: did you mean `X?`? + | +LL | println!("{f:X?}"); + | ~~ + +error: aborting due to 3 previous errors + |
