Skip to content

Commit b03615b

Browse files
Rollup merge of #157012 - Kokoro2336:fix/issue-156868, r=mejrs
Fix missing note of escaping `{` for braces including whitespaces Fixes #156868 Add note of escaping `{` for braces including whitespaces
2 parents 5bc1fd1 + e2521e6 commit b03615b

3 files changed

Lines changed: 42 additions & 2 deletions

File tree

compiler/rustc_builtin_macros/src/format.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,7 @@ fn report_invalid_references(
987987
// Collect all the implicit positions:
988988
let mut spans = Vec::new();
989989
let mut num_placeholders = 0;
990+
let mut has_white_space_only_missing_arg = false;
990991
for piece in template {
991992
let mut placeholder = None;
992993
// `{arg:.*}`
@@ -1009,13 +1010,21 @@ fn report_invalid_references(
10091010
}
10101011
// `{}`
10111012
if let FormatArgsPiece::Placeholder(FormatPlaceholder {
1012-
argument: FormatArgPosition { kind: FormatArgPositionKind::Implicit, .. },
1013+
argument: FormatArgPosition { kind: FormatArgPositionKind::Implicit, index, .. },
10131014
span,
10141015
..
10151016
}) = piece
10161017
{
10171018
placeholder = *span;
10181019
num_placeholders += 1;
1020+
// Check whether there's any non-space whitespace in the placeholder. If so, we should emit a note suggesting an escaping `{`.
1021+
if index.is_err()
1022+
&& let Some(span) = span
1023+
&& let Ok(snippet) = ecx.source_map().span_to_snippet(*span)
1024+
&& snippet.chars().any(|c| c.is_whitespace() && c != ' ')
1025+
{
1026+
has_white_space_only_missing_arg = true;
1027+
}
10191028
}
10201029
// For `{:.*}`, we only push one span.
10211030
spans.extend(placeholder);
@@ -1071,6 +1080,9 @@ fn report_invalid_references(
10711080
if has_precision_star {
10721081
e.note("positional arguments are zero-based");
10731082
}
1083+
if has_white_space_only_missing_arg {
1084+
e.note("if you intended to print `{`, you can escape it with `{{`");
1085+
}
10741086
} else {
10751087
let mut indexes: Vec<_> = invalid_refs.iter().map(|&(index, _, _, _)| index).collect();
10761088
// Avoid `invalid reference to positional arguments 7 and 7 (there is 1 argument)`

tests/ui/fmt/format-string-error-2.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,15 @@ raw { \n
9191

9292
println!("{x=}");
9393
//~^ ERROR invalid format string: python's f-string debug `=` is not supported in rust, use `dbg(x)` instead
94+
95+
println!(
96+
"fn main() {\n\
97+
\n\
98+
}"
99+
//~^^^ ERROR 1 positional argument in format string
100+
);
101+
102+
// Don't emit note suggesting an escaping `{` for `{ }`.
103+
println!("{ }");
104+
//~^ ERROR 1 positional argument in format string
94105
}

tests/ui/fmt/format-string-error-2.stderr

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,5 +208,22 @@ LL | println!("{x=}");
208208
|
209209
= note: to print `{`, you can escape it using `{{`
210210

211-
error: aborting due to 21 previous errors
211+
error: 1 positional argument in format string, but no arguments were given
212+
--> $DIR/format-string-error-2.rs:96:20
213+
|
214+
LL | "fn main() {\n\
215+
| ____________________^
216+
LL | | \n\
217+
LL | | }"
218+
| |_________^
219+
|
220+
= note: if you intended to print `{`, you can escape it with `{{`
221+
222+
error: 1 positional argument in format string, but no arguments were given
223+
--> $DIR/format-string-error-2.rs:103:15
224+
|
225+
LL | println!("{ }");
226+
| ^^^
227+
228+
error: aborting due to 23 previous errors
212229

0 commit comments

Comments
 (0)