@@ -396,9 +396,7 @@ pub(crate) fn parse_format_string(
396396 . map ( |piece| match piece {
397397 RpfPiece :: Lit ( lit) => Piece :: Lit ( Symbol :: intern ( lit) ) ,
398398 RpfPiece :: NextArgument ( arg) => {
399- warn_on_format_spec ( & arg. format , & mut warnings, span, parser. is_source_literal ) ;
400- let arg = parse_arg ( & arg, mode, & mut warnings, span, parser. is_source_literal ) ;
401- Piece :: Arg ( arg)
399+ Piece :: Arg ( parse_arg ( & arg, mode, & mut warnings, span, parser. is_source_literal ) )
402400 }
403401 } )
404402 . collect ( ) ;
@@ -415,26 +413,33 @@ fn parse_arg(
415413) -> FormatArg {
416414 let span = slice_span ( input_span, arg. position_span . clone ( ) , is_source_literal) ;
417415
418- match arg. position {
416+ let mut check_format = true ;
417+
418+ let ret = match arg. position {
419419 // Something like "hello {name}"
420420 Position :: ArgumentNamed ( name) => match ( mode, Symbol :: intern ( name) ) {
421421 ( Mode :: RustcOnUnimplemented , sym:: ItemContext ) => FormatArg :: ItemContext ,
422422
423- // Like `{This}`, but sugared.
424- // FIXME(mejrs) maybe rename/rework this or something
425- // if we want to apply this to other attrs?
426- ( Mode :: RustcOnUnimplemented , sym:: Trait ) => FormatArg :: Trait ,
423+ // `{This:ty}`
424+ ( Mode :: RustcOnUnimplemented , sym:: This ) => match arg. format . ty {
425+ "resolved" => {
426+ check_format = false ;
427+ FormatArg :: ThisResolved
428+ }
429+ "path" => {
430+ check_format = false ;
431+ FormatArg :: ThisPath
432+ }
433+ _ => FormatArg :: This ,
434+ } ,
427435
428436 // Some diagnostic attributes can use `{This}` to refer to the annotated item.
429437 // For those that don't, we continue and maybe use it as a generic parameter.
430438 //
431439 // FIXME(mejrs) `DiagnosticOnUnimplemented` is intentionally not here;
432440 // that requires lang approval which is best kept for a standalone PR.
433441 (
434- Mode :: RustcOnUnimplemented
435- | Mode :: DiagnosticOnUnknown
436- | Mode :: DiagnosticOnMove
437- | Mode :: DiagnosticOnUnmatchArgs ,
442+ Mode :: DiagnosticOnUnknown | Mode :: DiagnosticOnMove | Mode :: DiagnosticOnUnmatchArgs ,
438443 sym:: This ,
439444 ) => FormatArg :: This ,
440445
@@ -471,11 +476,11 @@ fn parse_arg(
471476 attr : mode. as_str ( ) ,
472477 allowed : mode. allowed_format_arguments ( ) ,
473478 } ) ;
474- return FormatArg :: AsIs ( Symbol :: intern ( & format ! ( "{{{as_is}}}" ) ) ) ;
479+ FormatArg :: AsIs ( Symbol :: intern ( & format ! ( "{{{as_is}}}" ) ) )
475480 }
476481 } ,
477482
478- // `{: 1}` and `{}` are ignored
483+ // `{1}` and `{}` are ignored
479484 Position :: ArgumentIs ( idx) => {
480485 warnings. push ( FormatWarning :: IndexedArgument { span } ) ;
481486 FormatArg :: AsIs ( Symbol :: intern ( & format ! ( "{{{idx}}}" ) ) )
@@ -484,7 +489,11 @@ fn parse_arg(
484489 warnings. push ( FormatWarning :: PositionalArgument { span } ) ;
485490 FormatArg :: AsIs ( sym:: empty_braces)
486491 }
492+ } ;
493+ if check_format {
494+ warn_on_format_spec( & arg. format , warnings, input_span, is_source_literal) ;
487495 }
496+ ret
488497}
489498
490499/// `#[rustc_on_unimplemented]` and `#[diagnostic::...]` don't actually do anything
@@ -495,12 +504,8 @@ fn warn_on_format_spec(
495504 input_span: Span ,
496505 is_source_literal: bool ,
497506) {
498- if spec. ty != "" {
499- let span = spec
500- . ty_span
501- . as_ref ( )
502- . map ( |inner| slice_span ( input_span, inner. clone ( ) , is_source_literal) )
503- . unwrap_or ( input_span) ;
507+ if let Some ( ty_span) = & spec. ty_span {
508+ let span = slice_span ( input_span, ty_span. clone ( ) , is_source_literal) ;
504509 warnings. push ( FormatWarning :: InvalidSpecifier { span } )
505510 }
506511}
0 commit comments