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:
parent
8100541d54
commit
70ee0c96fc
4 changed files with 45 additions and 2 deletions
|
@ -67,6 +67,7 @@ decl_derive!(
|
||||||
warning,
|
warning,
|
||||||
error,
|
error,
|
||||||
// field attributes
|
// field attributes
|
||||||
|
skip_arg,
|
||||||
primary_span,
|
primary_span,
|
||||||
label,
|
label,
|
||||||
suggestion,
|
suggestion,
|
||||||
|
|
|
@ -216,7 +216,12 @@ impl<'a> SessionDiagnosticDerive<'a> {
|
||||||
if field.attrs.is_empty() {
|
if field.attrs.is_empty() {
|
||||||
let diag = &builder.diag;
|
let diag = &builder.diag;
|
||||||
let ident = field_binding.ast().ident.as_ref().unwrap();
|
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 {
|
} else {
|
||||||
quote! {}
|
quote! {}
|
||||||
}
|
}
|
||||||
|
@ -566,6 +571,11 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
|
||||||
let meta = attr.parse_meta()?;
|
let meta = attr.parse_meta()?;
|
||||||
match meta {
|
match meta {
|
||||||
syn::Meta::Path(_) => match name {
|
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" => {
|
"primary_span" => {
|
||||||
if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
|
if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
|
||||||
return Ok(quote! {
|
return Ok(quote! {
|
||||||
|
|
|
@ -311,3 +311,23 @@ struct ErrorWithLifetime<'a> {
|
||||||
span: Span,
|
span: Span,
|
||||||
name: &'a str,
|
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,
|
||||||
|
}
|
||||||
|
|
|
@ -274,5 +274,17 @@ error: cannot find attribute `nonsense` in this scope
|
||||||
LL | #[nonsense]
|
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`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue