@@ -97,11 +97,11 @@ register_builtin! {
97
97
( unreachable, Unreachable ) => unreachable_expand,
98
98
( log_syntax, LogSyntax ) => log_syntax_expand,
99
99
( trace_macros, TraceMacros ) => trace_macros_expand,
100
-
101
- EAGER :
102
100
( format_args, FormatArgs ) => format_args_expand,
103
101
( const_format_args, ConstFormatArgs ) => format_args_expand,
104
102
( format_args_nl, FormatArgsNl ) => format_args_nl_expand,
103
+
104
+ EAGER :
105
105
( compile_error, CompileError ) => compile_error_expand,
106
106
( concat, Concat ) => concat_expand,
107
107
( concat_idents, ConcatIdents ) => concat_idents_expand,
@@ -247,160 +247,22 @@ fn format_args_expand_general(
247
247
_db : & dyn ExpandDatabase ,
248
248
_id : MacroCallId ,
249
249
tt : & tt:: Subtree ,
250
- end_string : & str ,
250
+ // FIXME: Make use of this so that mir interpretation works properly
251
+ _end_string : & str ,
251
252
) -> ExpandResult < tt:: Subtree > {
252
- let args = parse_exprs_with_sep ( tt, ',' ) ;
253
-
254
- let expand_error =
255
- ExpandResult :: new ( tt:: Subtree :: empty ( ) , mbe:: ExpandError :: NoMatchingRule . into ( ) ) ;
256
-
257
- let mut key_args = FxHashMap :: default ( ) ;
258
- let mut args = args. into_iter ( ) . filter_map ( |mut arg| {
259
- // Remove `key =`.
260
- if matches ! ( arg. token_trees. get( 1 ) , Some ( tt:: TokenTree :: Leaf ( tt:: Leaf :: Punct ( p) ) ) if p. char == '=' )
261
- {
262
- // but not with `==`
263
- if !matches ! ( arg. token_trees. get( 2 ) , Some ( tt:: TokenTree :: Leaf ( tt:: Leaf :: Punct ( p) ) ) if p. char == '=' )
264
- {
265
- let key = arg. token_trees . drain ( ..2 ) . next ( ) . unwrap ( ) ;
266
- key_args. insert ( key. to_string ( ) , arg) ;
267
- return None ;
268
- }
269
- }
270
- Some ( arg)
271
- } ) . collect :: < Vec < _ > > ( ) . into_iter ( ) ;
272
- // ^^^^^^^ we need this collect, to enforce the side effect of the filter_map closure (building the `key_args`)
273
- let Some ( format_subtree) = args. next ( ) else {
274
- return expand_error;
275
- } ;
276
- let format_string = ( || {
277
- let token_tree = format_subtree. token_trees . get ( 0 ) ?;
278
- match token_tree {
279
- tt:: TokenTree :: Leaf ( l) => match l {
280
- tt:: Leaf :: Literal ( l) => {
281
- if let Some ( mut text) = l. text . strip_prefix ( 'r' ) {
282
- let mut raw_sharps = String :: new ( ) ;
283
- while let Some ( t) = text. strip_prefix ( '#' ) {
284
- text = t;
285
- raw_sharps. push ( '#' ) ;
286
- }
287
- text =
288
- text. strip_suffix ( & raw_sharps) ?. strip_prefix ( '"' ) ?. strip_suffix ( '"' ) ?;
289
- Some ( ( text, l. span , Some ( raw_sharps) ) )
290
- } else {
291
- let text = l. text . strip_prefix ( '"' ) ?. strip_suffix ( '"' ) ?;
292
- let span = l. span ;
293
- Some ( ( text, span, None ) )
294
- }
295
- }
296
- _ => None ,
297
- } ,
298
- tt:: TokenTree :: Subtree ( _) => None ,
299
- }
300
- } ) ( ) ;
301
- let Some ( ( format_string, _format_string_span, raw_sharps) ) = format_string else {
302
- return expand_error;
303
- } ;
304
- let mut format_iter = format_string. chars ( ) . peekable ( ) ;
305
- let mut parts = vec ! [ ] ;
306
- let mut last_part = String :: new ( ) ;
307
- let mut arg_tts = vec ! [ ] ;
308
- let mut err = None ;
309
- while let Some ( c) = format_iter. next ( ) {
310
- // Parsing the format string. See https://doc.rust-lang.org/std/fmt/index.html#syntax for the grammar and more info
311
- match c {
312
- '{' => {
313
- if format_iter. peek ( ) == Some ( & '{' ) {
314
- format_iter. next ( ) ;
315
- last_part. push ( '{' ) ;
316
- continue ;
317
- }
318
- let mut argument = String :: new ( ) ;
319
- while ![ Some ( & '}' ) , Some ( & ':' ) ] . contains ( & format_iter. peek ( ) ) {
320
- argument. push ( match format_iter. next ( ) {
321
- Some ( c) => c,
322
- None => return expand_error,
323
- } ) ;
324
- }
325
- let format_spec = match format_iter. next ( ) . unwrap ( ) {
326
- '}' => "" . to_owned ( ) ,
327
- ':' => {
328
- let mut s = String :: new ( ) ;
329
- while let Some ( c) = format_iter. next ( ) {
330
- if c == '}' {
331
- break ;
332
- }
333
- s. push ( c) ;
334
- }
335
- s
336
- }
337
- _ => unreachable ! ( ) ,
338
- } ;
339
- parts. push ( mem:: take ( & mut last_part) ) ;
340
- let arg_tree = if argument. is_empty ( ) {
341
- match args. next ( ) {
342
- Some ( it) => it,
343
- None => {
344
- err = Some ( mbe:: ExpandError :: NoMatchingRule . into ( ) ) ;
345
- tt:: Subtree :: empty ( )
346
- }
347
- }
348
- } else if let Some ( tree) = key_args. get ( & argument) {
349
- tree. clone ( )
350
- } else {
351
- // FIXME: we should pick the related substring of the `_format_string_span` as the span. You
352
- // can use `.char_indices()` instead of `.char()` for `format_iter` to find the substring interval.
353
- let ident = Ident :: new ( argument, tt:: TokenId :: unspecified ( ) ) ;
354
- quote ! ( #ident)
355
- } ;
356
- let formatter = match & * format_spec {
357
- "?" => quote ! ( :: core:: fmt:: Debug :: fmt) ,
358
- "" => quote ! ( :: core:: fmt:: Display :: fmt) ,
359
- _ => {
360
- // FIXME: implement the rest and return expand error here
361
- quote ! ( :: core:: fmt:: Display :: fmt)
362
- }
363
- } ;
364
- arg_tts. push ( quote ! { :: core:: fmt:: ArgumentV1 :: new( & ( #arg_tree) , #formatter) , } ) ;
365
- }
366
- '}' => {
367
- if format_iter. peek ( ) == Some ( & '}' ) {
368
- format_iter. next ( ) ;
369
- last_part. push ( '}' ) ;
370
- } else {
371
- return expand_error;
372
- }
373
- }
374
- _ => last_part. push ( c) ,
375
- }
376
- }
377
- last_part += end_string;
378
- if !last_part. is_empty ( ) {
379
- parts. push ( last_part) ;
380
- }
381
- let part_tts = parts. into_iter ( ) . map ( |it| {
382
- let text = if let Some ( raw) = & raw_sharps {
383
- format ! ( "r{raw}\" {}\" {raw}" , it) . into ( )
384
- } else {
385
- format ! ( "\" {}\" " , it) . into ( )
386
- } ;
387
- let l = tt:: Literal { span : tt:: TokenId :: unspecified ( ) , text } ;
388
- quote ! ( #l , )
253
+ let pound = quote ! { @PUNCT '#' } ;
254
+ let mut tt = tt. clone ( ) ;
255
+ tt. delimiter . kind = tt:: DelimiterKind :: Parenthesis ;
256
+ return ExpandResult :: ok ( quote ! {
257
+ builtin #pound format_args #tt
389
258
} ) ;
390
- let arg_tts = arg_tts. into_iter ( ) . flat_map ( |arg| arg. token_trees ) ;
391
- let expanded = quote ! {
392
- :: core:: fmt:: Arguments :: new_v1( & [ ##part_tts] , & [ ##arg_tts] )
393
- } ;
394
- ExpandResult { value : expanded, err }
395
259
}
396
260
397
261
fn asm_expand (
398
262
_db : & dyn ExpandDatabase ,
399
263
_id : MacroCallId ,
400
264
tt : & tt:: Subtree ,
401
265
) -> ExpandResult < tt:: Subtree > {
402
- // FIXME: parse asm here
403
-
404
266
// We expand all assembly snippets to `format_args!` invocations to get format syntax
405
267
// highlighting for them.
406
268
0 commit comments