diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs
index 9b4ffc7ea27f6..c2dfc4a147ee3 100644
--- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs
@@ -396,9 +396,7 @@ pub(crate) fn parse_format_string(
.map(|piece| match piece {
RpfPiece::Lit(lit) => Piece::Lit(Symbol::intern(lit)),
RpfPiece::NextArgument(arg) => {
- warn_on_format_spec(&arg.format, &mut warnings, span, parser.is_source_literal);
- let arg = parse_arg(&arg, mode, &mut warnings, span, parser.is_source_literal);
- Piece::Arg(arg)
+ Piece::Arg(parse_arg(&arg, mode, &mut warnings, span, parser.is_source_literal))
}
})
.collect();
@@ -415,15 +413,25 @@ fn parse_arg(
) -> FormatArg {
let span = slice_span(input_span, arg.position_span.clone(), is_source_literal);
- match arg.position {
+ let mut check_format = true;
+
+ let ret = match arg.position {
// Something like "hello {name}"
Position::ArgumentNamed(name) => match (mode, Symbol::intern(name)) {
(Mode::RustcOnUnimplemented, sym::ItemContext) => FormatArg::ItemContext,
- // Like `{This}`, but sugared.
- // FIXME(mejrs) maybe rename/rework this or something
- // if we want to apply this to other attrs?
- (Mode::RustcOnUnimplemented, sym::Trait) => FormatArg::Trait,
+ // `{This:ty}`
+ (Mode::RustcOnUnimplemented, sym::This) => match arg.format.ty {
+ "resolved" => {
+ check_format = false;
+ FormatArg::ThisResolved
+ }
+ "path" => {
+ check_format = false;
+ FormatArg::ThisPath
+ }
+ _ => FormatArg::This,
+ },
// Some diagnostic attributes can use `{This}` to refer to the annotated item.
// For those that don't, we continue and maybe use it as a generic parameter.
@@ -431,10 +439,7 @@ fn parse_arg(
// FIXME(mejrs) `DiagnosticOnUnimplemented` is intentionally not here;
// that requires lang approval which is best kept for a standalone PR.
(
- Mode::RustcOnUnimplemented
- | Mode::DiagnosticOnUnknown
- | Mode::DiagnosticOnMove
- | Mode::DiagnosticOnUnmatchArgs,
+ Mode::DiagnosticOnUnknown | Mode::DiagnosticOnMove | Mode::DiagnosticOnUnmatchArgs,
sym::This,
) => FormatArg::This,
@@ -471,11 +476,11 @@ fn parse_arg(
attr: mode.as_str(),
allowed: mode.allowed_format_arguments(),
});
- return FormatArg::AsIs(Symbol::intern(&format!("{{{as_is}}}")));
+ FormatArg::AsIs(Symbol::intern(&format!("{{{as_is}}}")))
}
},
- // `{:1}` and `{}` are ignored
+ // `{1}` and `{}` are ignored
Position::ArgumentIs(idx) => {
warnings.push(FormatWarning::IndexedArgument { span });
FormatArg::AsIs(Symbol::intern(&format!("{{{idx}}}")))
@@ -484,7 +489,11 @@ fn parse_arg(
warnings.push(FormatWarning::PositionalArgument { span });
FormatArg::AsIs(sym::empty_braces)
}
+ };
+ if check_format {
+ warn_on_format_spec(&arg.format, warnings, input_span, is_source_literal);
}
+ ret
}
/// `#[rustc_on_unimplemented]` and `#[diagnostic::...]` don't actually do anything
@@ -495,12 +504,8 @@ fn warn_on_format_spec(
input_span: Span,
is_source_literal: bool,
) {
- if spec.ty != "" {
- let span = spec
- .ty_span
- .as_ref()
- .map(|inner| slice_span(input_span, inner.clone(), is_source_literal))
- .unwrap_or(input_span);
+ if let Some(ty_span) = &spec.ty_span {
+ let span = slice_span(input_span, ty_span.clone(), is_source_literal);
warnings.push(FormatWarning::InvalidSpecifier { span })
}
}
diff --git a/compiler/rustc_hir/src/attrs/diagnostic.rs b/compiler/rustc_hir/src/attrs/diagnostic.rs
index 7cbb0ea45b969..7d4ae803cee59 100644
--- a/compiler/rustc_hir/src/attrs/diagnostic.rs
+++ b/compiler/rustc_hir/src/attrs/diagnostic.rs
@@ -147,11 +147,12 @@ impl FormatString {
};
ret.push_str(&slf);
}
+ Piece::Arg(FormatArg::This) => ret.push_str(&args.this),
// It's only `rustc_onunimplemented` from here
- Piece::Arg(FormatArg::This) => ret.push_str(&args.this),
- Piece::Arg(FormatArg::Trait) => {
- let _ = fmt::write(&mut ret, format_args!("{}", &args.this_sugared));
+ Piece::Arg(FormatArg::ThisPath) => ret.push_str(&args.this_path),
+ Piece::Arg(FormatArg::ThisResolved) => {
+ let _ = fmt::write(&mut ret, format_args!("{}", &args.this_resolved));
}
Piece::Arg(FormatArg::ItemContext) => ret.push_str(args.item_context),
}
@@ -197,7 +198,7 @@ impl FormatString {
/// ```rust,ignore (just an example)
/// FormatArgs {
/// this: "FromResidual",
-/// this_sugared: "FromResidual