diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 82f6812026a7d..e405462bbb862 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -382,10 +382,26 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> { return Ok(quote! { #diag.subdiagnostic(#binding); }); } } - (Meta::List(_), "subdiagnostic") => { - throw_invalid_attr!(attr, &meta, |diag| { - diag.help("`subdiagnostic` does not support nested attributes") - }) + (Meta::List(MetaList { ref nested, .. }), "subdiagnostic") => { + if nested.len() == 1 + && let Some(NestedMeta::Meta(Meta::Path(path))) = nested.first() + && path.is_ident("eager") { + let handler = match &self.parent.kind { + DiagnosticDeriveKind::Diagnostic { handler } => handler, + DiagnosticDeriveKind::LintDiagnostic => { + throw_invalid_attr!(attr, &meta, |diag| { + diag.help("eager subdiagnostics are not supported on lints") + }) + } + }; + return Ok(quote! { #diag.eager_subdiagnostic(#handler, #binding); }); + } else { + throw_invalid_attr!(attr, &meta, |diag| { + diag.help( + "`eager` is the only supported nested attribute for `subdiagnostic`", + ) + }) + } } _ => (), } diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index ac916bb60689e..bb3722fe156e0 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -1,5 +1,6 @@ #![feature(allow_internal_unstable)] #![feature(if_let_guard)] +#![feature(let_chains)] #![feature(never_type)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index c19b639a8d581..65d9601e78ab6 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -723,7 +723,6 @@ struct SubdiagnosticEagerLint { #[diag(compiletest_example)] struct SubdiagnosticEagerCorrect { #[subdiagnostic(eager)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute note: Note, } @@ -744,7 +743,6 @@ pub(crate) struct SubdiagnosticWithSuggestion { #[diag(compiletest_example)] struct SubdiagnosticEagerSuggestion { #[subdiagnostic(eager)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute sub: SubdiagnosticWithSuggestion, } diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index f39d32a221cac..13e806a434f63 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -539,7 +539,7 @@ error: `#[subdiagnostic(...)]` is not a valid attribute LL | #[subdiagnostic(bad)] | ^^^^^^^^^^^^^^^^^^^^^ | - = help: `subdiagnostic` does not support nested attributes + = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic = ...]` is not a valid attribute --> $DIR/diagnostic-derive.rs:693:5 @@ -553,7 +553,7 @@ error: `#[subdiagnostic(...)]` is not a valid attribute LL | #[subdiagnostic(bad, bad)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `subdiagnostic` does not support nested attributes + = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:709:5 @@ -561,7 +561,7 @@ error: `#[subdiagnostic(...)]` is not a valid attribute LL | #[subdiagnostic("bad")] | ^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `subdiagnostic` does not support nested attributes + = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:717:5 @@ -569,38 +569,22 @@ error: `#[subdiagnostic(...)]` is not a valid attribute LL | #[subdiagnostic(eager)] | ^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `subdiagnostic` does not support nested attributes - -error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:725:5 - | -LL | #[subdiagnostic(eager)] - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: `subdiagnostic` does not support nested attributes - -error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:746:5 - | -LL | #[subdiagnostic(eager)] - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: `subdiagnostic` does not support nested attributes + = help: eager subdiagnostics are not supported on lints error: expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:777:18 + --> $DIR/diagnostic-derive.rs:775:18 | LL | #[suggestion(code())] | ^^^^^^ error: `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:785:23 + --> $DIR/diagnostic-derive.rs:783:23 | LL | #[suggestion(code(foo))] | ^^^ error: `code = "..."`/`code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:793:18 + --> $DIR/diagnostic-derive.rs:791:18 | LL | #[suggestion(code = 3)] | ^^^^^^^^ @@ -676,7 +660,7 @@ note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC = note: this error originates in the derive macro `Diagnostic` which comes from the expansion of the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 85 previous errors +error: aborting due to 83 previous errors Some errors have detailed explanations: E0277, E0425. For more information about an error, try `rustc --explain E0277`.