macros: add #[no_arg] to skip set_arg call

A call to `set_arg` is generated for every field of a
`SessionDiagnostic` struct without attributes, but not all types support
being an argument, so `#[no_arg]` is introduced to skip these fields.

Signed-off-by: David Wood <david.wood@huawei.com>
This commit is contained in:
David Wood 2022-03-31 09:02:31 +01:00
parent 8100541d54
commit 70ee0c96fc
4 changed files with 45 additions and 2 deletions

View File

@ -67,6 +67,7 @@ decl_derive!(
warning,
error,
// field attributes
skip_arg,
primary_span,
label,
suggestion,

View File

@ -216,7 +216,12 @@ impl<'a> SessionDiagnosticDerive<'a> {
if field.attrs.is_empty() {
let diag = &builder.diag;
let ident = field_binding.ast().ident.as_ref().unwrap();
quote! { #diag.set_arg(stringify!(#ident), #field_binding.into_diagnostic_arg()); }
quote! {
#diag.set_arg(
stringify!(#ident),
#field_binding.into_diagnostic_arg()
);
}
} else {
quote! {}
}
@ -566,6 +571,11 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
let meta = attr.parse_meta()?;
match meta {
syn::Meta::Path(_) => match name {
"skip_arg" => {
// Don't need to do anything - by virtue of the attribute existing, the
// `set_arg` call will not be generated.
Ok(quote! {})
}
"primary_span" => {
if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
return Ok(quote! {

View File

@ -311,3 +311,23 @@ struct ErrorWithLifetime<'a> {
span: Span,
name: &'a str,
}
#[derive(SessionDiagnostic)]
//~^ ERROR no method named `into_diagnostic_arg` found for struct `Hello` in the current scope
#[error(code = "E0123", slug = "foo")]
struct ArgFieldWithoutSkip {
#[primary_span]
span: Span,
other: Hello,
}
#[derive(SessionDiagnostic)]
#[error(code = "E0123", slug = "foo")]
struct ArgFieldWithSkip {
#[primary_span]
span: Span,
// `Hello` does not implement `IntoDiagnosticArg` so this would result in an error if
// not for `#[skip_arg]`.
#[skip_arg]
other: Hello,
}

View File

@ -274,5 +274,17 @@ error: cannot find attribute `nonsense` in this scope
LL | #[nonsense]
| ^^^^^^^^
error: aborting due to 34 previous errors
error[E0599]: no method named `into_diagnostic_arg` found for struct `Hello` in the current scope
--> $DIR/session-derive-errors.rs:315:10
|
LL | struct Hello {}
| ------------ method `into_diagnostic_arg` not found for this
...
LL | #[derive(SessionDiagnostic)]
| ^^^^^^^^^^^^^^^^^ method not found in `Hello`
|
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 35 previous errors
For more information about this error, try `rustc --explain E0599`.