@@ -221,6 +221,11 @@ pub enum Suggestion {
221
221
/// Remove `r#` from identifier:
222
222
/// `format!("{r#foo}")` -> `format!("{foo}")`
223
223
RemoveRawIdent ( InnerSpan ) ,
224
+ /// Reorder format parameter:
225
+ /// `format!("{foo:?#}")` -> `format!("{foo:#?}")`
226
+ /// `format!("{foo:?x}")` -> `format!("{foo:x?}")`
227
+ /// `format!("{foo:?X}")` -> `format!("{foo:X?}")`
228
+ ReorderFormatParameter ( InnerSpan , string:: String ) ,
224
229
}
225
230
226
231
/// The parser structure for interpreting the input format string. This is
@@ -389,6 +394,7 @@ impl<'a> Parser<'a> {
389
394
description : S1 ,
390
395
label : S2 ,
391
396
note : S3 ,
397
+
392
398
span : InnerSpan ,
393
399
) {
394
400
self . errors . push ( ParseError {
@@ -731,6 +737,12 @@ impl<'a> Parser<'a> {
731
737
}
732
738
} else if self . consume ( '?' ) {
733
739
spec. ty = "?" ;
740
+ if let Some ( & ( _, maybe) ) = self . cur . peek ( ) {
741
+ match maybe {
742
+ '#' | 'x' | 'X' => self . suggest_format_parameter ( maybe) ,
743
+ _ => ( ) ,
744
+ }
745
+ }
734
746
} else {
735
747
spec. ty = self . word ( ) ;
736
748
if !spec. ty . is_empty ( ) {
@@ -932,6 +944,30 @@ impl<'a> Parser<'a> {
932
944
}
933
945
}
934
946
}
947
+
948
+ fn suggest_format_parameter ( & mut self , c : char ) {
949
+ let replacement = match c {
950
+ '#' => "#?" ,
951
+ 'x' => "x?" ,
952
+ 'X' => "X?" ,
953
+ _ => return ,
954
+ } ;
955
+ let Some ( pos) = self . consume_pos ( c) else {
956
+ return ;
957
+ } ;
958
+
959
+ let span = self . span ( pos - 1 , pos + 1 ) ;
960
+ let pos = self . to_span_index ( pos) ;
961
+
962
+ self . errors . insert ( 0 , ParseError {
963
+ description : format ! ( "expected `}}`, found `{c}`" ) ,
964
+ note : None ,
965
+ label : "expected `'}'`" . into ( ) ,
966
+ span : pos. to ( pos) ,
967
+ secondary_label : None ,
968
+ suggestion : Suggestion :: ReorderFormatParameter ( span, format ! ( "{replacement}" ) ) ,
969
+ } )
970
+ }
935
971
}
936
972
937
973
/// Finds the indices of all characters that have been processed and differ between the actual
0 commit comments