@@ -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)`
0 commit comments