diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 6dd2161e0f9..1e1bfbb943e 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -478,26 +478,12 @@ impl DiagnosticDeriveBuilder { let formatted_str = self.build_format(&s.value(), s.span()); code.set_once((formatted_str, span)); } - "applicability" => { - applicability = match applicability { - Some(v) => { - span_err( - span, - "applicability cannot be set in both the field and \ - attribute", - ) - .emit(); - Some(v) - } - None => match Applicability::from_str(&s.value()) { - Ok(v) => Some(quote! { #v }), - Err(()) => { - span_err(span, "invalid applicability").emit(); - None - } - }, + "applicability" => match Applicability::from_str(&s.value()) { + Ok(v) => applicability.set_once((quote! { #v }, span)), + Err(()) => { + span_err(span, "invalid applicability").emit(); } - } + }, _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| { diag.help( "only `message`, `code` and `applicability` are valid field \ @@ -516,8 +502,9 @@ impl DiagnosticDeriveBuilder { } } - let applicability = - applicability.unwrap_or_else(|| quote!(rustc_errors::Applicability::Unspecified)); + let applicability = applicability + .value() + .unwrap_or_else(|| quote!(rustc_errors::Applicability::Unspecified)); let name = path.segments.last().unwrap().ident.to_string(); let method = format_ident!("span_{}", name); @@ -559,7 +546,7 @@ impl DiagnosticDeriveBuilder { fn span_and_applicability_of_ty( &self, info: FieldInfo<'_>, - ) -> Result<(TokenStream, Option), DiagnosticDeriveError> { + ) -> Result<(TokenStream, Option<(TokenStream, proc_macro::Span)>), DiagnosticDeriveError> { match &info.ty { // If `ty` is `Span` w/out applicability, then use `Applicability::Unspecified`. ty @ Type::Path(..) if type_matches_path(ty, &["rustc_span", "Span"]) => { @@ -594,14 +581,14 @@ impl DiagnosticDeriveBuilder { let Some((span_idx, _)) = span_idx else { type_err(&tup.span())?; }; - let Some((applicability_idx, _applicability_span)) = applicability_idx else { + let Some((applicability_idx, applicability_span)) = applicability_idx else { type_err(&tup.span())?; }; let binding = &info.binding.binding; let span = quote!(#binding.#span_idx); let applicability = quote!(#binding.#applicability_idx); - Ok((span, Some(applicability))) + Ok((span, Some((applicability, applicability_span)))) } // If `ty` isn't a `Span` or `(Span, Applicability)` then emit an error. _ => throw_span_err!(info.span.unwrap(), "wrong field type for suggestion", |diag| { diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index c774484d8bf..c3d3c23fe5b 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -436,7 +436,7 @@ struct ErrorWithNoteCustomWrongOrder { #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ApplicabilityInBoth { #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] - //~^ ERROR applicability cannot be set in both the field and attribute + //~^ ERROR specified multiple times suggestion: (Span, Applicability), } diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 084a021ac20..f5432b0bf65 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -293,11 +293,17 @@ error: `#[label = ...]` is not a valid attribute LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ -error: applicability cannot be set in both the field and attribute +error: specified multiple times --> $DIR/diagnostic-derive.rs:438:52 | LL | #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: previously specified here + --> $DIR/diagnostic-derive.rs:440:24 + | +LL | suggestion: (Span, Applicability), + | ^^^^^^^^^^^^^ error: invalid applicability --> $DIR/diagnostic-derive.rs:446:52