Skip to content

Commit 70ee0c9

Browse files
committed
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>
1 parent 8100541 commit 70ee0c9

File tree

4 files changed

+45
-2
lines changed

4 files changed

+45
-2
lines changed

compiler/rustc_macros/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ decl_derive!(
6767
warning,
6868
error,
6969
// field attributes
70+
skip_arg,
7071
primary_span,
7172
label,
7273
suggestion,

compiler/rustc_macros/src/session_diagnostic.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,12 @@ impl<'a> SessionDiagnosticDerive<'a> {
216216
if field.attrs.is_empty() {
217217
let diag = &builder.diag;
218218
let ident = field_binding.ast().ident.as_ref().unwrap();
219-
quote! { #diag.set_arg(stringify!(#ident), #field_binding.into_diagnostic_arg()); }
219+
quote! {
220+
#diag.set_arg(
221+
stringify!(#ident),
222+
#field_binding.into_diagnostic_arg()
223+
);
224+
}
220225
} else {
221226
quote! {}
222227
}
@@ -566,6 +571,11 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
566571
let meta = attr.parse_meta()?;
567572
match meta {
568573
syn::Meta::Path(_) => match name {
574+
"skip_arg" => {
575+
// Don't need to do anything - by virtue of the attribute existing, the
576+
// `set_arg` call will not be generated.
577+
Ok(quote! {})
578+
}
569579
"primary_span" => {
570580
if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
571581
return Ok(quote! {

src/test/ui-fulldeps/session-derive-errors.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,3 +311,23 @@ struct ErrorWithLifetime<'a> {
311311
span: Span,
312312
name: &'a str,
313313
}
314+
315+
#[derive(SessionDiagnostic)]
316+
//~^ ERROR no method named `into_diagnostic_arg` found for struct `Hello` in the current scope
317+
#[error(code = "E0123", slug = "foo")]
318+
struct ArgFieldWithoutSkip {
319+
#[primary_span]
320+
span: Span,
321+
other: Hello,
322+
}
323+
324+
#[derive(SessionDiagnostic)]
325+
#[error(code = "E0123", slug = "foo")]
326+
struct ArgFieldWithSkip {
327+
#[primary_span]
328+
span: Span,
329+
// `Hello` does not implement `IntoDiagnosticArg` so this would result in an error if
330+
// not for `#[skip_arg]`.
331+
#[skip_arg]
332+
other: Hello,
333+
}

src/test/ui-fulldeps/session-derive-errors.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,5 +274,17 @@ error: cannot find attribute `nonsense` in this scope
274274
LL | #[nonsense]
275275
| ^^^^^^^^
276276

277-
error: aborting due to 34 previous errors
277+
error[E0599]: no method named `into_diagnostic_arg` found for struct `Hello` in the current scope
278+
--> $DIR/session-derive-errors.rs:315:10
279+
|
280+
LL | struct Hello {}
281+
| ------------ method `into_diagnostic_arg` not found for this
282+
...
283+
LL | #[derive(SessionDiagnostic)]
284+
| ^^^^^^^^^^^^^^^^^ method not found in `Hello`
285+
|
286+
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
287+
288+
error: aborting due to 35 previous errors
278289

290+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)