Skip to content

Commit 305309f

Browse files
committed
Produce error about mismatched types of #[serde(with = "...")] and #[serde(default = "...")] attributes on the attribute itself
1 parent 16f0a46 commit 305309f

File tree

3 files changed

+59
-13
lines changed

3 files changed

+59
-13
lines changed

serde_derive/src/de.rs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,11 @@ fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
378378
} else {
379379
let value = match field.attrs.default() {
380380
attr::Default::Default => quote!(_serde::__private::Default::default()),
381-
attr::Default::Path(path) => quote!(#path()),
381+
// If #path returns wrong type, error will be reported here (^^^^^).
382+
// We attach span of the path to the function so it will be reported
383+
// on the #[serde(default = "...")]
384+
// ^^^^^
385+
attr::Default::Path(path) => quote_spanned!(path.span()=> #path()),
382386
attr::Default::None => quote!(_serde::__private::PhantomData),
383387
};
384388
quote!(#member: #value)
@@ -758,7 +762,11 @@ fn deserialize_seq(
758762
attr::Default::Default => Some(quote!(
759763
let __default: Self::Value = _serde::__private::Default::default();
760764
)),
761-
attr::Default::Path(path) => Some(quote!(
765+
// If #path returns wrong type, error will be reported here (^^^^^).
766+
// We attach span of the path to the function so it will be reported
767+
// on the #[serde(default = "...")]
768+
// ^^^^^
769+
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
762770
let __default: Self::Value = #path();
763771
)),
764772
attr::Default::None => {
@@ -840,7 +848,11 @@ fn deserialize_seq_in_place(
840848
attr::Default::Default => Some(quote!(
841849
let __default: #this_type #ty_generics = _serde::__private::Default::default();
842850
)),
843-
attr::Default::Path(path) => Some(quote!(
851+
// If #path returns wrong type, error will be reported here (^^^^^).
852+
// We attach span of the path to the function so it will be reported
853+
// on the #[serde(default = "...")]
854+
// ^^^^^
855+
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
844856
let __default: #this_type #ty_generics = #path();
845857
)),
846858
attr::Default::None => {
@@ -874,7 +886,11 @@ fn deserialize_newtype_struct(
874886
}
875887
}
876888
Some(path) => {
877-
quote! {
889+
// If #path returns wrong type, error will be reported here (^^^^^).
890+
// We attach span of the path to the function so it will be reported
891+
// on the #[serde(with = "...")]
892+
// ^^^^^
893+
quote_spanned! {path.span()=>
878894
#path(__e)?
879895
}
880896
}
@@ -2629,7 +2645,11 @@ fn deserialize_map(
26292645
attr::Default::Default => Some(quote!(
26302646
let __default: Self::Value = _serde::__private::Default::default();
26312647
)),
2632-
attr::Default::Path(path) => Some(quote!(
2648+
// If #path returns wrong type, error will be reported here (^^^^^).
2649+
// We attach span of the path to the function so it will be reported
2650+
// on the #[serde(default = "...")]
2651+
// ^^^^^
2652+
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
26332653
let __default: Self::Value = #path();
26342654
)),
26352655
attr::Default::None => {
@@ -2796,7 +2816,11 @@ fn deserialize_map_in_place(
27962816
attr::Default::Default => Some(quote!(
27972817
let __default: #this_type #ty_generics = _serde::__private::Default::default();
27982818
)),
2799-
attr::Default::Path(path) => Some(quote!(
2819+
// If #path returns wrong type, error will be reported here (^^^^^).
2820+
// We attach span of the path to the function so it will be reported
2821+
// on the #[serde(default = "...")]
2822+
// ^^^^^
2823+
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
28002824
let __default: #this_type #ty_generics = #path();
28012825
)),
28022826
attr::Default::None => {
@@ -2835,6 +2859,13 @@ fn wrap_deserialize_with(
28352859
split_with_de_lifetime(params);
28362860
let delife = params.borrowed.de_lifetime();
28372861

2862+
// If #deserialize_with returns wrong type, error will be reported here (^^^^^).
2863+
// We attach span of the path to the function so it will be reported
2864+
// on the #[serde(with = "...")]
2865+
// ^^^^^
2866+
let value = quote_spanned! {deserialize_with.span()=>
2867+
#deserialize_with(__deserializer)?
2868+
};
28382869
let wrapper = quote! {
28392870
#[doc(hidden)]
28402871
struct __DeserializeWith #de_impl_generics #where_clause {
@@ -2849,7 +2880,7 @@ fn wrap_deserialize_with(
28492880
__D: _serde::Deserializer<#delife>,
28502881
{
28512882
_serde::__private::Ok(__DeserializeWith {
2852-
value: #deserialize_with(__deserializer)?,
2883+
value: #value,
28532884
phantom: _serde::__private::PhantomData,
28542885
lifetime: _serde::__private::PhantomData,
28552886
})
@@ -2940,7 +2971,11 @@ fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
29402971
return quote_expr!(#func());
29412972
}
29422973
attr::Default::Path(path) => {
2943-
return quote_expr!(#path());
2974+
// If #path returns wrong type, error will be reported here (^^^^^).
2975+
// We attach span of the path to the function so it will be reported
2976+
// on the #[serde(default = "...")]
2977+
// ^^^^^
2978+
return Fragment::Expr(quote_spanned!(path.span()=> #path()));
29442979
}
29452980
attr::Default::None => { /* below */ }
29462981
}
@@ -2983,6 +3018,10 @@ fn expr_is_missing_seq(
29833018
return quote_spanned!(span=> #assign_to _serde::__private::Default::default());
29843019
}
29853020
attr::Default::Path(path) => {
3021+
// If #path returns wrong type, error will be reported here (^^^^^).
3022+
// We attach span of the path to the function so it will be reported
3023+
// on the #[serde(default = "...")]
3024+
// ^^^^^
29863025
return quote_spanned!(path.span()=> #assign_to #path());
29873026
}
29883027
attr::Default::None => { /* below */ }

serde_derive/src/internals/attr.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::iter::FromIterator;
88
use syn::meta::ParseNestedMeta;
99
use syn::parse::ParseStream;
1010
use syn::punctuated::Punctuated;
11+
use syn::spanned::Spanned;
1112
use syn::{parse_quote, token, Ident, Lifetime, Token};
1213

1314
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
@@ -889,13 +890,13 @@ impl Variant {
889890
ser_path
890891
.path
891892
.segments
892-
.push(Ident::new("serialize", Span::call_site()).into());
893+
.push(Ident::new("serialize", ser_path.span()).into());
893894
serialize_with.set(&meta.path, ser_path);
894895
let mut de_path = path;
895896
de_path
896897
.path
897898
.segments
898-
.push(Ident::new("deserialize", Span::call_site()).into());
899+
.push(Ident::new("deserialize", de_path.span()).into());
899900
deserialize_with.set(&meta.path, de_path);
900901
}
901902
} else if meta.path == SERIALIZE_WITH {
@@ -1171,13 +1172,13 @@ impl Field {
11711172
ser_path
11721173
.path
11731174
.segments
1174-
.push(Ident::new("serialize", Span::call_site()).into());
1175+
.push(Ident::new("serialize", ser_path.span()).into());
11751176
serialize_with.set(&meta.path, ser_path);
11761177
let mut de_path = path;
11771178
de_path
11781179
.path
11791180
.segments
1180-
.push(Ident::new("deserialize", Span::call_site()).into());
1181+
.push(Ident::new("deserialize", de_path.span()).into());
11811182
deserialize_with.set(&meta.path, de_path);
11821183
}
11831184
} else if meta.path == BOUND {

serde_derive/src/ser.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1223,9 +1223,15 @@ fn wrap_serialize_with(
12231223
})
12241224
});
12251225

1226-
quote!({
1226+
// If #serialize_with returns wrong type, error will be reported on here.
1227+
// We attach span of the path to this piece so error will be reported
1228+
// on the #[serde(with = "...")]
1229+
// ^^^^^
1230+
quote_spanned!(serialize_with.span()=> {
12271231
#[doc(hidden)]
12281232
struct __SerializeWith #wrapper_impl_generics #where_clause {
1233+
// If #field_tys is empty, `values` does not used
1234+
#[allow(dead_code)]
12291235
values: (#(&'__a #field_tys, )*),
12301236
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
12311237
}

0 commit comments

Comments
 (0)