Make spans a bit better

This commit is contained in:
Michael Goulet 2023-05-03 23:53:44 +00:00
parent 2b9279f313
commit a156bd7714
7 changed files with 48 additions and 46 deletions

View file

@ -9,7 +9,7 @@ use crate::diagnostics::utils::{
FieldInnerTy, FieldMap, HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind,
};
use proc_macro2::{Ident, Span, TokenStream};
use quote::{format_ident, quote};
use quote::{format_ident, quote, quote_spanned};
use syn::Token;
use syn::{parse_quote, spanned::Spanned, Attribute, Meta, Path, Type};
use synstructure::{BindingInfo, Structure, VariantInfo};
@ -251,7 +251,8 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
let diag = &self.parent.diag;
let field = binding_info.ast();
let field_binding = &binding_info.binding;
let mut field_binding = binding_info.binding.clone();
field_binding.set_span(field.ty.span());
let ident = field.ident.as_ref().unwrap();
let ident = format_ident!("{}", ident); // strip `r#` prefix, if present
@ -284,9 +285,9 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
name == "primary_span" && matches!(inner_ty, FieldInnerTy::Vec(_));
let (binding, needs_destructure) = if needs_clone {
// `primary_span` can accept a `Vec<Span>` so don't destructure that.
(quote! { #field_binding.clone() }, false)
(quote_spanned! {inner_ty.span()=> #field_binding.clone() }, false)
} else {
(quote! { #field_binding }, true)
(quote_spanned! {inner_ty.span()=> #field_binding }, true)
};
let generated_code = self

View file

@ -209,18 +209,20 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
}
/// Generates the code for a field with no attributes.
fn generate_field_set_arg(&mut self, binding: &BindingInfo<'_>) -> TokenStream {
let ast = binding.ast();
fn generate_field_set_arg(&mut self, binding_info: &BindingInfo<'_>) -> TokenStream {
let diag = &self.parent.diag;
let ident = ast.ident.as_ref().unwrap();
// strip `r#` prefix, if present
let ident = format_ident!("{}", ident);
let field = binding_info.ast();
let mut field_binding = binding_info.binding.clone();
field_binding.set_span(field.ty.span());
let ident = field.ident.as_ref().unwrap();
let ident = format_ident!("{}", ident); // strip `r#` prefix, if present
quote! {
#diag.set_arg(
stringify!(#ident),
#binding
#field_binding
);
}
}
@ -397,7 +399,8 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
clone_suggestion_code: bool,
) -> Result<TokenStream, DiagnosticDeriveError> {
let span = attr.span().unwrap();
let ident = &list.path.segments.last().unwrap().ident;
let mut ident = list.path.segments.last().unwrap().ident.clone();
ident.set_span(info.ty.span());
let name = ident.to_string();
let name = name.as_str();
@ -496,7 +499,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
.variant
.bindings()
.iter()
.filter(|binding| !binding.ast().attrs.is_empty())
.filter(|binding| !should_generate_set_arg(binding.ast()))
.map(|binding| self.generate_field_attr_code(binding, kind_stats))
.collect();

View file

@ -207,6 +207,12 @@ impl<'ty> FieldInnerTy<'ty> {
FieldInnerTy::Plain(..) => quote! { #inner },
}
}
pub fn span(&self) -> proc_macro2::Span {
match self {
FieldInnerTy::Option(ty) | FieldInnerTy::Vec(ty) | FieldInnerTy::Plain(ty) => ty.span(),
}
}
}
/// Field information passed to the builder. Deliberately omits attrs to discourage the