Streamline Diagnostic
proc macro.
First, it is parameterized by the name of the diagnostic and the DiagCtxt. These are given to `session_diagnostic_derive` and `lint_diagnostic_derive`. But the names are hard-wired as "diag" and "handler" (should be "dcx"), and there's no clear reason for the parameterization. So this commit removes the parameterization and hard-wires the names internally. Once that is done `DiagnosticDeriveBuilder` is reduced to a trivial wrapper around `DiagnosticDeriveKind`, and can be removed. Also, `DiagnosticDerive` and `LintDiagnosticDerive` don't need the `builder` field, because it has been reduced to a kind, and they know their own kind. This avoids the need for some `let`/`else`/`unreachable!` kind checks And `DiagnosticDeriveVariantBuilder` no longer needs a lifetime, because the `parent` field is changed to `kind`, which is now a trivial copy type.
This commit is contained in:
parent
18251c480b
commit
31df50c897
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use crate::diagnostics::diagnostic_builder::{DiagnosticDeriveBuilder, DiagnosticDeriveKind};
|
use crate::diagnostics::diagnostic_builder::DiagnosticDeriveKind;
|
||||||
use crate::diagnostics::error::{span_err, DiagnosticDeriveError};
|
use crate::diagnostics::error::{span_err, DiagnosticDeriveError};
|
||||||
use crate::diagnostics::utils::SetOnce;
|
use crate::diagnostics::utils::SetOnce;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
@ -13,32 +13,21 @@ use synstructure::Structure;
|
|||||||
/// The central struct for constructing the `into_diagnostic` method from an annotated struct.
|
/// The central struct for constructing the `into_diagnostic` method from an annotated struct.
|
||||||
pub(crate) struct DiagnosticDerive<'a> {
|
pub(crate) struct DiagnosticDerive<'a> {
|
||||||
structure: Structure<'a>,
|
structure: Structure<'a>,
|
||||||
builder: DiagnosticDeriveBuilder,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DiagnosticDerive<'a> {
|
impl<'a> DiagnosticDerive<'a> {
|
||||||
pub(crate) fn new(diag: syn::Ident, dcx: syn::Ident, structure: Structure<'a>) -> Self {
|
pub(crate) fn new(structure: Structure<'a>) -> Self {
|
||||||
Self {
|
Self { structure }
|
||||||
builder: DiagnosticDeriveBuilder {
|
|
||||||
diag,
|
|
||||||
kind: DiagnosticDeriveKind::Diagnostic { dcx },
|
|
||||||
},
|
|
||||||
structure,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn into_tokens(self) -> TokenStream {
|
pub(crate) fn into_tokens(self) -> TokenStream {
|
||||||
let DiagnosticDerive { mut structure, mut builder } = self;
|
let DiagnosticDerive { mut structure } = self;
|
||||||
|
let kind = DiagnosticDeriveKind::Diagnostic;
|
||||||
let slugs = RefCell::new(Vec::new());
|
let slugs = RefCell::new(Vec::new());
|
||||||
let implementation = builder.each_variant(&mut structure, |mut builder, variant| {
|
let implementation = kind.each_variant(&mut structure, |mut builder, variant| {
|
||||||
let preamble = builder.preamble(variant);
|
let preamble = builder.preamble(variant);
|
||||||
let body = builder.body(variant);
|
let body = builder.body(variant);
|
||||||
|
|
||||||
let diag = &builder.parent.diag;
|
|
||||||
let DiagnosticDeriveKind::Diagnostic { dcx } = &builder.parent.kind else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
let init = match builder.slug.value_ref() {
|
let init = match builder.slug.value_ref() {
|
||||||
None => {
|
None => {
|
||||||
span_err(builder.span, "diagnostic slug not specified")
|
span_err(builder.span, "diagnostic slug not specified")
|
||||||
@ -62,7 +51,7 @@ impl<'a> DiagnosticDerive<'a> {
|
|||||||
Some(slug) => {
|
Some(slug) => {
|
||||||
slugs.borrow_mut().push(slug.clone());
|
slugs.borrow_mut().push(slug.clone());
|
||||||
quote! {
|
quote! {
|
||||||
let mut #diag = #dcx.struct_diagnostic(crate::fluent_generated::#slug);
|
let mut diag = dcx.struct_diagnostic(crate::fluent_generated::#slug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -73,12 +62,10 @@ impl<'a> DiagnosticDerive<'a> {
|
|||||||
#formatting_init
|
#formatting_init
|
||||||
#preamble
|
#preamble
|
||||||
#body
|
#body
|
||||||
#diag
|
diag
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let DiagnosticDeriveKind::Diagnostic { dcx } = &builder.kind else { unreachable!() };
|
|
||||||
|
|
||||||
// A lifetime of `'a` causes conflicts, but `_sess` is fine.
|
// A lifetime of `'a` causes conflicts, but `_sess` is fine.
|
||||||
let mut imp = structure.gen_impl(quote! {
|
let mut imp = structure.gen_impl(quote! {
|
||||||
gen impl<'_sess, G>
|
gen impl<'_sess, G>
|
||||||
@ -90,7 +77,7 @@ impl<'a> DiagnosticDerive<'a> {
|
|||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn into_diagnostic(
|
fn into_diagnostic(
|
||||||
self,
|
self,
|
||||||
#dcx: &'_sess rustc_errors::DiagCtxt
|
dcx: &'_sess rustc_errors::DiagCtxt
|
||||||
) -> rustc_errors::DiagnosticBuilder<'_sess, G> {
|
) -> rustc_errors::DiagnosticBuilder<'_sess, G> {
|
||||||
#implementation
|
#implementation
|
||||||
}
|
}
|
||||||
@ -106,36 +93,31 @@ impl<'a> DiagnosticDerive<'a> {
|
|||||||
/// The central struct for constructing the `decorate_lint` method from an annotated struct.
|
/// The central struct for constructing the `decorate_lint` method from an annotated struct.
|
||||||
pub(crate) struct LintDiagnosticDerive<'a> {
|
pub(crate) struct LintDiagnosticDerive<'a> {
|
||||||
structure: Structure<'a>,
|
structure: Structure<'a>,
|
||||||
builder: DiagnosticDeriveBuilder,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> LintDiagnosticDerive<'a> {
|
impl<'a> LintDiagnosticDerive<'a> {
|
||||||
pub(crate) fn new(diag: syn::Ident, structure: Structure<'a>) -> Self {
|
pub(crate) fn new(structure: Structure<'a>) -> Self {
|
||||||
Self {
|
Self { structure }
|
||||||
builder: DiagnosticDeriveBuilder { diag, kind: DiagnosticDeriveKind::LintDiagnostic },
|
|
||||||
structure,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn into_tokens(self) -> TokenStream {
|
pub(crate) fn into_tokens(self) -> TokenStream {
|
||||||
let LintDiagnosticDerive { mut structure, mut builder } = self;
|
let LintDiagnosticDerive { mut structure } = self;
|
||||||
|
let kind = DiagnosticDeriveKind::LintDiagnostic;
|
||||||
let implementation = builder.each_variant(&mut structure, |mut builder, variant| {
|
let implementation = kind.each_variant(&mut structure, |mut builder, variant| {
|
||||||
let preamble = builder.preamble(variant);
|
let preamble = builder.preamble(variant);
|
||||||
let body = builder.body(variant);
|
let body = builder.body(variant);
|
||||||
|
|
||||||
let diag = &builder.parent.diag;
|
|
||||||
let formatting_init = &builder.formatting_init;
|
let formatting_init = &builder.formatting_init;
|
||||||
quote! {
|
quote! {
|
||||||
#preamble
|
#preamble
|
||||||
#formatting_init
|
#formatting_init
|
||||||
#body
|
#body
|
||||||
#diag
|
diag
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let slugs = RefCell::new(Vec::new());
|
let slugs = RefCell::new(Vec::new());
|
||||||
let msg = builder.each_variant(&mut structure, |mut builder, variant| {
|
let msg = kind.each_variant(&mut structure, |mut builder, variant| {
|
||||||
// Collect the slug by generating the preamble.
|
// Collect the slug by generating the preamble.
|
||||||
let _ = builder.preamble(variant);
|
let _ = builder.preamble(variant);
|
||||||
|
|
||||||
@ -168,13 +150,12 @@ impl<'a> LintDiagnosticDerive<'a> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let diag = &builder.diag;
|
|
||||||
let mut imp = structure.gen_impl(quote! {
|
let mut imp = structure.gen_impl(quote! {
|
||||||
gen impl<'__a> rustc_errors::DecorateLint<'__a, ()> for @Self {
|
gen impl<'__a> rustc_errors::DecorateLint<'__a, ()> for @Self {
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn decorate_lint<'__b>(
|
fn decorate_lint<'__b>(
|
||||||
self,
|
self,
|
||||||
#diag: &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()>
|
diag: &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()>
|
||||||
) {
|
) {
|
||||||
#implementation;
|
#implementation;
|
||||||
}
|
}
|
||||||
|
@ -17,28 +17,18 @@ use synstructure::{BindingInfo, Structure, VariantInfo};
|
|||||||
use super::utils::SubdiagnosticVariant;
|
use super::utils::SubdiagnosticVariant;
|
||||||
|
|
||||||
/// What kind of diagnostic is being derived - a fatal/error/warning or a lint?
|
/// What kind of diagnostic is being derived - a fatal/error/warning or a lint?
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
pub(crate) enum DiagnosticDeriveKind {
|
pub(crate) enum DiagnosticDeriveKind {
|
||||||
Diagnostic { dcx: syn::Ident },
|
Diagnostic,
|
||||||
LintDiagnostic,
|
LintDiagnostic,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tracks persistent information required for the entire type when building up individual calls to
|
|
||||||
/// diagnostic methods for generated diagnostic derives - both `Diagnostic` for
|
|
||||||
/// fatal/errors/warnings and `LintDiagnostic` for lints.
|
|
||||||
pub(crate) struct DiagnosticDeriveBuilder {
|
|
||||||
/// The identifier to use for the generated `DiagnosticBuilder` instance.
|
|
||||||
pub diag: syn::Ident,
|
|
||||||
/// Kind of diagnostic that should be derived.
|
|
||||||
pub kind: DiagnosticDeriveKind,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Tracks persistent information required for a specific variant when building up individual calls
|
/// Tracks persistent information required for a specific variant when building up individual calls
|
||||||
/// to diagnostic methods for generated diagnostic derives - both `Diagnostic` for
|
/// to diagnostic methods for generated diagnostic derives - both `Diagnostic` for
|
||||||
/// fatal/errors/warnings and `LintDiagnostic` for lints.
|
/// fatal/errors/warnings and `LintDiagnostic` for lints.
|
||||||
pub(crate) struct DiagnosticDeriveVariantBuilder<'parent> {
|
pub(crate) struct DiagnosticDeriveVariantBuilder {
|
||||||
/// The parent builder for the entire type.
|
/// The kind for the entire type.
|
||||||
pub parent: &'parent DiagnosticDeriveBuilder,
|
pub kind: DiagnosticDeriveKind,
|
||||||
|
|
||||||
/// Initialization of format strings for code suggestions.
|
/// Initialization of format strings for code suggestions.
|
||||||
pub formatting_init: TokenStream,
|
pub formatting_init: TokenStream,
|
||||||
@ -59,19 +49,19 @@ pub(crate) struct DiagnosticDeriveVariantBuilder<'parent> {
|
|||||||
pub code: SpannedOption<()>,
|
pub code: SpannedOption<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HasFieldMap for DiagnosticDeriveVariantBuilder<'a> {
|
impl HasFieldMap for DiagnosticDeriveVariantBuilder {
|
||||||
fn get_field_binding(&self, field: &String) -> Option<&TokenStream> {
|
fn get_field_binding(&self, field: &String) -> Option<&TokenStream> {
|
||||||
self.field_map.get(field)
|
self.field_map.get(field)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DiagnosticDeriveBuilder {
|
impl DiagnosticDeriveKind {
|
||||||
/// Call `f` for the struct or for each variant of the enum, returning a `TokenStream` with the
|
/// Call `f` for the struct or for each variant of the enum, returning a `TokenStream` with the
|
||||||
/// tokens from `f` wrapped in an `match` expression. Emits errors for use of derive on unions
|
/// tokens from `f` wrapped in an `match` expression. Emits errors for use of derive on unions
|
||||||
/// or attributes on the type itself when input is an enum.
|
/// or attributes on the type itself when input is an enum.
|
||||||
pub(crate) fn each_variant<'s, F>(&mut self, structure: &mut Structure<'s>, f: F) -> TokenStream
|
pub(crate) fn each_variant<'s, F>(self, structure: &mut Structure<'s>, f: F) -> TokenStream
|
||||||
where
|
where
|
||||||
F: for<'a, 'v> Fn(DiagnosticDeriveVariantBuilder<'a>, &VariantInfo<'v>) -> TokenStream,
|
F: for<'v> Fn(DiagnosticDeriveVariantBuilder, &VariantInfo<'v>) -> TokenStream,
|
||||||
{
|
{
|
||||||
let ast = structure.ast();
|
let ast = structure.ast();
|
||||||
let span = ast.span().unwrap();
|
let span = ast.span().unwrap();
|
||||||
@ -101,7 +91,7 @@ impl DiagnosticDeriveBuilder {
|
|||||||
_ => variant.ast().ident.span().unwrap(),
|
_ => variant.ast().ident.span().unwrap(),
|
||||||
};
|
};
|
||||||
let builder = DiagnosticDeriveVariantBuilder {
|
let builder = DiagnosticDeriveVariantBuilder {
|
||||||
parent: self,
|
kind: self,
|
||||||
span,
|
span,
|
||||||
field_map: build_field_mapping(variant),
|
field_map: build_field_mapping(variant),
|
||||||
formatting_init: TokenStream::new(),
|
formatting_init: TokenStream::new(),
|
||||||
@ -119,7 +109,7 @@ impl DiagnosticDeriveBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
impl DiagnosticDeriveVariantBuilder {
|
||||||
/// Generates calls to `code` and similar functions based on the attributes on the type or
|
/// Generates calls to `code` and similar functions based on the attributes on the type or
|
||||||
/// variant.
|
/// variant.
|
||||||
pub(crate) fn preamble(&mut self, variant: &VariantInfo<'_>) -> TokenStream {
|
pub(crate) fn preamble(&mut self, variant: &VariantInfo<'_>) -> TokenStream {
|
||||||
@ -184,8 +174,6 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
attr: &Attribute,
|
attr: &Attribute,
|
||||||
) -> Result<TokenStream, DiagnosticDeriveError> {
|
) -> Result<TokenStream, DiagnosticDeriveError> {
|
||||||
let diag = &self.parent.diag;
|
|
||||||
|
|
||||||
// Always allow documentation comments.
|
// Always allow documentation comments.
|
||||||
if is_doc_comment(attr) {
|
if is_doc_comment(attr) {
|
||||||
return Ok(quote! {});
|
return Ok(quote! {});
|
||||||
@ -223,7 +211,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||||||
|
|
||||||
let code = nested.parse::<syn::LitStr>()?;
|
let code = nested.parse::<syn::LitStr>()?;
|
||||||
tokens.extend(quote! {
|
tokens.extend(quote! {
|
||||||
#diag.code(rustc_errors::DiagnosticId::Error(#code.to_string()));
|
diag.code(rustc_errors::DiagnosticId::Error(#code.to_string()));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
span_err(path.span().unwrap(), "unknown argument")
|
span_err(path.span().unwrap(), "unknown argument")
|
||||||
@ -257,8 +245,6 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_field_code(&mut self, binding_info: &BindingInfo<'_>) -> TokenStream {
|
fn generate_field_code(&mut self, binding_info: &BindingInfo<'_>) -> TokenStream {
|
||||||
let diag = &self.parent.diag;
|
|
||||||
|
|
||||||
let field = binding_info.ast();
|
let field = binding_info.ast();
|
||||||
let mut field_binding = binding_info.binding.clone();
|
let mut field_binding = binding_info.binding.clone();
|
||||||
field_binding.set_span(field.ty.span());
|
field_binding.set_span(field.ty.span());
|
||||||
@ -267,7 +253,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||||||
let ident = format_ident!("{}", ident); // strip `r#` prefix, if present
|
let ident = format_ident!("{}", ident); // strip `r#` prefix, if present
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#diag.set_arg(
|
diag.set_arg(
|
||||||
stringify!(#ident),
|
stringify!(#ident),
|
||||||
#field_binding
|
#field_binding
|
||||||
);
|
);
|
||||||
@ -322,8 +308,6 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||||||
info: FieldInfo<'_>,
|
info: FieldInfo<'_>,
|
||||||
binding: TokenStream,
|
binding: TokenStream,
|
||||||
) -> Result<TokenStream, DiagnosticDeriveError> {
|
) -> Result<TokenStream, DiagnosticDeriveError> {
|
||||||
let diag = &self.parent.diag;
|
|
||||||
|
|
||||||
let ident = &attr.path().segments.last().unwrap().ident;
|
let ident = &attr.path().segments.last().unwrap().ident;
|
||||||
let name = ident.to_string();
|
let name = ident.to_string();
|
||||||
match (&attr.meta, name.as_str()) {
|
match (&attr.meta, name.as_str()) {
|
||||||
@ -331,12 +315,12 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||||||
// `set_arg` call will not be generated.
|
// `set_arg` call will not be generated.
|
||||||
(Meta::Path(_), "skip_arg") => return Ok(quote! {}),
|
(Meta::Path(_), "skip_arg") => return Ok(quote! {}),
|
||||||
(Meta::Path(_), "primary_span") => {
|
(Meta::Path(_), "primary_span") => {
|
||||||
match self.parent.kind {
|
match self.kind {
|
||||||
DiagnosticDeriveKind::Diagnostic { .. } => {
|
DiagnosticDeriveKind::Diagnostic => {
|
||||||
report_error_if_not_applied_to_span(attr, &info)?;
|
report_error_if_not_applied_to_span(attr, &info)?;
|
||||||
|
|
||||||
return Ok(quote! {
|
return Ok(quote! {
|
||||||
#diag.set_span(#binding);
|
diag.set_span(#binding);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
DiagnosticDeriveKind::LintDiagnostic => {
|
DiagnosticDeriveKind::LintDiagnostic => {
|
||||||
@ -348,13 +332,13 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||||||
}
|
}
|
||||||
(Meta::Path(_), "subdiagnostic") => {
|
(Meta::Path(_), "subdiagnostic") => {
|
||||||
if FieldInnerTy::from_type(&info.binding.ast().ty).will_iterate() {
|
if FieldInnerTy::from_type(&info.binding.ast().ty).will_iterate() {
|
||||||
let DiagnosticDeriveKind::Diagnostic { dcx } = &self.parent.kind else {
|
let DiagnosticDeriveKind::Diagnostic = self.kind else {
|
||||||
// No eager translation for lints.
|
// No eager translation for lints.
|
||||||
return Ok(quote! { #diag.subdiagnostic(#binding); });
|
return Ok(quote! { diag.subdiagnostic(#binding); });
|
||||||
};
|
};
|
||||||
return Ok(quote! { #diag.eager_subdiagnostic(#dcx, #binding); });
|
return Ok(quote! { diag.eager_subdiagnostic(dcx, #binding); });
|
||||||
} else {
|
} else {
|
||||||
return Ok(quote! { #diag.subdiagnostic(#binding); });
|
return Ok(quote! { diag.subdiagnostic(#binding); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Meta::List(meta_list), "subdiagnostic") => {
|
(Meta::List(meta_list), "subdiagnostic") => {
|
||||||
@ -376,15 +360,15 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||||||
return Ok(quote! {});
|
return Ok(quote! {});
|
||||||
}
|
}
|
||||||
|
|
||||||
let dcx = match &self.parent.kind {
|
match &self.kind {
|
||||||
DiagnosticDeriveKind::Diagnostic { dcx } => dcx,
|
DiagnosticDeriveKind::Diagnostic => {}
|
||||||
DiagnosticDeriveKind::LintDiagnostic => {
|
DiagnosticDeriveKind::LintDiagnostic => {
|
||||||
throw_invalid_attr!(attr, |diag| {
|
throw_invalid_attr!(attr, |diag| {
|
||||||
diag.help("eager subdiagnostics are not supported on lints")
|
diag.help("eager subdiagnostics are not supported on lints")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return Ok(quote! { #diag.eager_subdiagnostic(#dcx, #binding); });
|
return Ok(quote! { diag.eager_subdiagnostic(dcx, #binding); });
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
@ -442,7 +426,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||||||
|
|
||||||
self.formatting_init.extend(code_init);
|
self.formatting_init.extend(code_init);
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#diag.span_suggestions_with_style(
|
diag.span_suggestions_with_style(
|
||||||
#span_field,
|
#span_field,
|
||||||
crate::fluent_generated::#slug,
|
crate::fluent_generated::#slug,
|
||||||
#code_field,
|
#code_field,
|
||||||
@ -463,10 +447,9 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||||||
kind: &Ident,
|
kind: &Ident,
|
||||||
fluent_attr_identifier: Path,
|
fluent_attr_identifier: Path,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let diag = &self.parent.diag;
|
|
||||||
let fn_name = format_ident!("span_{}", kind);
|
let fn_name = format_ident!("span_{}", kind);
|
||||||
quote! {
|
quote! {
|
||||||
#diag.#fn_name(
|
diag.#fn_name(
|
||||||
#field_binding,
|
#field_binding,
|
||||||
crate::fluent_generated::#fluent_attr_identifier
|
crate::fluent_generated::#fluent_attr_identifier
|
||||||
);
|
);
|
||||||
@ -476,9 +459,8 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||||||
/// Adds a subdiagnostic by generating a `diag.span_$kind` call with the current slug
|
/// Adds a subdiagnostic by generating a `diag.span_$kind` call with the current slug
|
||||||
/// and `fluent_attr_identifier`.
|
/// and `fluent_attr_identifier`.
|
||||||
fn add_subdiagnostic(&self, kind: &Ident, fluent_attr_identifier: Path) -> TokenStream {
|
fn add_subdiagnostic(&self, kind: &Ident, fluent_attr_identifier: Path) -> TokenStream {
|
||||||
let diag = &self.parent.diag;
|
|
||||||
quote! {
|
quote! {
|
||||||
#diag.#kind(crate::fluent_generated::#fluent_attr_identifier);
|
diag.#kind(crate::fluent_generated::#fluent_attr_identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ mod utils;
|
|||||||
|
|
||||||
use diagnostic::{DiagnosticDerive, LintDiagnosticDerive};
|
use diagnostic::{DiagnosticDerive, LintDiagnosticDerive};
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::format_ident;
|
|
||||||
use subdiagnostic::SubdiagnosticDeriveBuilder;
|
use subdiagnostic::SubdiagnosticDeriveBuilder;
|
||||||
use synstructure::Structure;
|
use synstructure::Structure;
|
||||||
|
|
||||||
@ -57,7 +56,7 @@ use synstructure::Structure;
|
|||||||
/// See rustc dev guide for more examples on using the `#[derive(Diagnostic)]`:
|
/// See rustc dev guide for more examples on using the `#[derive(Diagnostic)]`:
|
||||||
/// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html>
|
/// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html>
|
||||||
pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
|
pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
|
||||||
DiagnosticDerive::new(format_ident!("diag"), format_ident!("handler"), s).into_tokens()
|
DiagnosticDerive::new(s).into_tokens()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implements `#[derive(LintDiagnostic)]`, which allows for lints to be specified as a struct,
|
/// Implements `#[derive(LintDiagnostic)]`, which allows for lints to be specified as a struct,
|
||||||
@ -103,7 +102,7 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
|
|||||||
/// See rustc dev guide for more examples on using the `#[derive(LintDiagnostic)]`:
|
/// See rustc dev guide for more examples on using the `#[derive(LintDiagnostic)]`:
|
||||||
/// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html#reference>
|
/// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html#reference>
|
||||||
pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
|
pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
|
||||||
LintDiagnosticDerive::new(format_ident!("diag"), s).into_tokens()
|
LintDiagnosticDerive::new(s).into_tokens()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implements `#[derive(Subdiagnostic)]`, which allows for labels, notes, helps and
|
/// Implements `#[derive(Subdiagnostic)]`, which allows for labels, notes, helps and
|
||||||
|
Loading…
x
Reference in New Issue
Block a user