Use more spans for error messages

This commit is contained in:
hcpl 2018-11-17 18:13:36 +02:00
parent 58b3af4c29
commit 8f3f073017
3 changed files with 43 additions and 20 deletions

View File

@ -357,7 +357,10 @@ fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
let path = match transparent_field.attrs.deserialize_with() { let path = match transparent_field.attrs.deserialize_with() {
Some(path) => quote!(#path), Some(path) => quote!(#path),
None => quote!(_serde::Deserialize::deserialize), None => {
let span = transparent_field.original.span();
quote_spanned!(span=> _serde::Deserialize::deserialize)
},
}; };
let assign = fields.iter().map(|field| { let assign = fields.iter().map(|field| {
@ -797,8 +800,10 @@ fn deserialize_newtype_struct(
let value = match field.attrs.deserialize_with() { let value = match field.attrs.deserialize_with() {
None => { None => {
let span = field.original.span();
let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
quote! { quote! {
try!(<#field_ty as _serde::Deserialize>::deserialize(__e)) try!(#func(__e))
} }
} }
Some(path) => { Some(path) => {
@ -1803,10 +1808,10 @@ fn deserialize_externally_tagged_newtype_variant(
match field.attrs.deserialize_with() { match field.attrs.deserialize_with() {
None => { None => {
let field_ty = field.ty; let field_ty = field.ty;
let span = field.original.span();
let func = quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>);
quote_expr! { quote_expr! {
_serde::export::Result::map( _serde::export::Result::map(#func(__variant), #this::#variant_ident)
_serde::de::VariantAccess::newtype_variant::<#field_ty>(__variant),
#this::#variant_ident)
} }
} }
Some(path) => { Some(path) => {
@ -1831,10 +1836,10 @@ fn deserialize_untagged_newtype_variant(
let field_ty = field.ty; let field_ty = field.ty;
match field.attrs.deserialize_with() { match field.attrs.deserialize_with() {
None => { None => {
let span = field.original.span();
let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
quote_expr! { quote_expr! {
_serde::export::Result::map( _serde::export::Result::map(#func(#deserializer), #this::#variant_ident)
<#field_ty as _serde::Deserialize>::deserialize(#deserializer),
#this::#variant_ident)
} }
} }
Some(path) => { Some(path) => {
@ -2441,7 +2446,10 @@ fn deserialize_map(
.map(|&(field, ref name)| { .map(|&(field, ref name)| {
let field_ty = field.ty; let field_ty = field.ty;
let func = match field.attrs.deserialize_with() { let func = match field.attrs.deserialize_with() {
None => quote!(_serde::de::Deserialize::deserialize), None => {
let span = field.original.span();
quote_spanned!(span=> _serde::de::Deserialize::deserialize)
},
Some(path) => quote!(#path), Some(path) => quote!(#path),
}; };
quote! { quote! {
@ -2793,7 +2801,9 @@ fn wrap_deserialize_variant_with(
fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment { fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
match *field.attrs.default() { match *field.attrs.default() {
attr::Default::Default => { attr::Default::Default => {
return quote_expr!(_serde::export::Default::default()); let span = field.original.span();
let func = quote_spanned!(span=> _serde::export::Default::default);
return quote_expr!(#func());
} }
attr::Default::Path(ref path) => { attr::Default::Path(ref path) => {
return quote_expr!(#path()); return quote_expr!(#path());

View File

@ -62,6 +62,7 @@ mod internals;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use syn::DeriveInput; use syn::DeriveInput;
use syn::spanned::Spanned;
#[macro_use] #[macro_use]
mod bound; mod bound;
@ -77,7 +78,7 @@ mod try;
pub fn derive_serialize(input: TokenStream) -> TokenStream { pub fn derive_serialize(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput); let input = parse_macro_input!(input as DeriveInput);
ser::expand_derive_serialize(&input) ser::expand_derive_serialize(&input)
.unwrap_or_else(compile_error) .unwrap_or_else(|message| compile_error(input.span(), message))
.into() .into()
} }
@ -85,12 +86,12 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream {
pub fn derive_deserialize(input: TokenStream) -> TokenStream { pub fn derive_deserialize(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput); let input = parse_macro_input!(input as DeriveInput);
de::expand_derive_deserialize(&input) de::expand_derive_deserialize(&input)
.unwrap_or_else(compile_error) .unwrap_or_else(|message| compile_error(input.span(), message))
.into() .into()
} }
fn compile_error(message: String) -> proc_macro2::TokenStream { fn compile_error(span: proc_macro2::Span, message: String) -> proc_macro2::TokenStream {
quote! { quote_spanned! {span=>
compile_error!(#message); compile_error!(#message);
} }
} }

View File

@ -200,7 +200,10 @@ fn serialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
let path = match transparent_field.attrs.serialize_with() { let path = match transparent_field.attrs.serialize_with() {
Some(path) => quote!(#path), Some(path) => quote!(#path),
None => quote!(_serde::Serialize::serialize), None => {
let span = transparent_field.original.span();
quote_spanned!(span=> _serde::Serialize::serialize)
},
}; };
quote_block! { quote_block! {
@ -505,8 +508,10 @@ fn serialize_externally_tagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
} }
let span = field.original.span();
let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_variant);
quote_expr! { quote_expr! {
_serde::Serializer::serialize_newtype_variant( #func(
__serializer, __serializer,
#type_name, #type_name,
#variant_index, #variant_index,
@ -579,8 +584,10 @@ fn serialize_internally_tagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
} }
let span = field.original.span();
let func = quote_spanned!(span=> _serde::private::ser::serialize_tagged_newtype);
quote_expr! { quote_expr! {
_serde::private::ser::serialize_tagged_newtype( #func(
__serializer, __serializer,
#enum_ident_str, #enum_ident_str,
#variant_ident_str, #variant_ident_str,
@ -637,12 +644,14 @@ fn serialize_adjacently_tagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
} }
let span = field.original.span();
let func = quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field);
return quote_block! { return quote_block! {
let mut __struct = try!(_serde::Serializer::serialize_struct( let mut __struct = try!(_serde::Serializer::serialize_struct(
__serializer, #type_name, 2)); __serializer, #type_name, 2));
try!(_serde::ser::SerializeStruct::serialize_field( try!(_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name)); &mut __struct, #tag, #variant_name));
try!(_serde::ser::SerializeStruct::serialize_field( try!(#func(
&mut __struct, #content, #field_expr)); &mut __struct, #content, #field_expr));
_serde::ser::SerializeStruct::end(__struct) _serde::ser::SerializeStruct::end(__struct)
}; };
@ -738,8 +747,10 @@ fn serialize_untagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
} }
let span = field.original.span();
let func = quote_spanned!(span=> _serde::Serialize::serialize);
quote_expr! { quote_expr! {
_serde::Serialize::serialize(#field_expr, __serializer) #func(#field_expr, __serializer)
} }
} }
Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields), Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
@ -1079,8 +1090,9 @@ fn serialize_struct_visitor(
let span = field.original.span(); let span = field.original.span();
let ser = if field.attrs.flatten() { let ser = if field.attrs.flatten() {
let func = quote_spanned!(span=> _serde::Serialize::serialize);
quote! { quote! {
try!(_serde::Serialize::serialize(&#field_expr, _serde::private::ser::FlatMapSerializer(&mut __serde_state))); try!(#func(&#field_expr, _serde::private::ser::FlatMapSerializer(&mut __serde_state)));
} }
} else { } else {
let func = struct_trait.serialize_field(span); let func = struct_trait.serialize_field(span);