Skip to content

Commit 1865357

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

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
@@ -371,7 +371,11 @@ fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
371371
} else {
372372
let value = match field.attrs.default() {
373373
attr::Default::Default => quote!(_serde::__private::Default::default()),
374-
attr::Default::Path(path) => quote!(#path()),
374+
// If #path returns wrong type, error will be reported here (^^^^^).
375+
// We attach span of the path to the function so it will be reported
376+
// on the #[serde(default = "...")]
377+
// ^^^^^
378+
attr::Default::Path(path) => quote_spanned!(path.span()=> #path()),
375379
attr::Default::None => quote!(_serde::__private::PhantomData),
376380
};
377381
quote!(#member: #value)
@@ -751,7 +755,11 @@ fn deserialize_seq(
751755
attr::Default::Default => Some(quote!(
752756
let __default: Self::Value = _serde::__private::Default::default();
753757
)),
754-
attr::Default::Path(path) => Some(quote!(
758+
// If #path returns wrong type, error will be reported here (^^^^^).
759+
// We attach span of the path to the function so it will be reported
760+
// on the #[serde(default = "...")]
761+
// ^^^^^
762+
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
755763
let __default: Self::Value = #path();
756764
)),
757765
attr::Default::None => {
@@ -833,7 +841,11 @@ fn deserialize_seq_in_place(
833841
attr::Default::Default => Some(quote!(
834842
let __default: #this_type #ty_generics = _serde::__private::Default::default();
835843
)),
836-
attr::Default::Path(path) => Some(quote!(
844+
// If #path returns wrong type, error will be reported here (^^^^^).
845+
// We attach span of the path to the function so it will be reported
846+
// on the #[serde(default = "...")]
847+
// ^^^^^
848+
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
837849
let __default: #this_type #ty_generics = #path();
838850
)),
839851
attr::Default::None => {
@@ -867,7 +879,11 @@ fn deserialize_newtype_struct(
867879
}
868880
}
869881
Some(path) => {
870-
quote! {
882+
// If #path returns wrong type, error will be reported here (^^^^^).
883+
// We attach span of the path to the function so it will be reported
884+
// on the #[serde(with = "...")]
885+
// ^^^^^
886+
quote_spanned! {path.span()=>
871887
#path(__e)?
872888
}
873889
}
@@ -2634,7 +2650,11 @@ fn deserialize_map(
26342650
attr::Default::Default => Some(quote!(
26352651
let __default: Self::Value = _serde::__private::Default::default();
26362652
)),
2637-
attr::Default::Path(path) => Some(quote!(
2653+
// If #path returns wrong type, error will be reported here (^^^^^).
2654+
// We attach span of the path to the function so it will be reported
2655+
// on the #[serde(default = "...")]
2656+
// ^^^^^
2657+
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
26382658
let __default: Self::Value = #path();
26392659
)),
26402660
attr::Default::None => {
@@ -2801,7 +2821,11 @@ fn deserialize_map_in_place(
28012821
attr::Default::Default => Some(quote!(
28022822
let __default: #this_type #ty_generics = _serde::__private::Default::default();
28032823
)),
2804-
attr::Default::Path(path) => Some(quote!(
2824+
// If #path returns wrong type, error will be reported here (^^^^^).
2825+
// We attach span of the path to the function so it will be reported
2826+
// on the #[serde(default = "...")]
2827+
// ^^^^^
2828+
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
28052829
let __default: #this_type #ty_generics = #path();
28062830
)),
28072831
attr::Default::None => {
@@ -2840,6 +2864,13 @@ fn wrap_deserialize_with(
28402864
split_with_de_lifetime(params);
28412865
let delife = params.borrowed.de_lifetime();
28422866

2867+
// If #deserialize_with returns wrong type, error will be reported here (^^^^^).
2868+
// We attach span of the path to the function so it will be reported
2869+
// on the #[serde(with = "...")]
2870+
// ^^^^^
2871+
let value = quote_spanned! {deserialize_with.span()=>
2872+
#deserialize_with(__deserializer)?
2873+
};
28432874
let wrapper = quote! {
28442875
#[doc(hidden)]
28452876
struct __DeserializeWith #de_impl_generics #where_clause {
@@ -2854,7 +2885,7 @@ fn wrap_deserialize_with(
28542885
__D: _serde::Deserializer<#delife>,
28552886
{
28562887
_serde::__private::Ok(__DeserializeWith {
2857-
value: #deserialize_with(__deserializer)?,
2888+
value: #value,
28582889
phantom: _serde::__private::PhantomData,
28592890
lifetime: _serde::__private::PhantomData,
28602891
})
@@ -2945,7 +2976,11 @@ fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
29452976
return quote_expr!(#func());
29462977
}
29472978
attr::Default::Path(path) => {
2948-
return quote_expr!(#path());
2979+
// If #path returns wrong type, error will be reported here (^^^^^).
2980+
// We attach span of the path to the function so it will be reported
2981+
// on the #[serde(default = "...")]
2982+
// ^^^^^
2983+
return Fragment::Expr(quote_spanned!(path.span()=> #path()));
29492984
}
29502985
attr::Default::None => { /* below */ }
29512986
}
@@ -2988,6 +3023,10 @@ fn expr_is_missing_seq(
29883023
return quote_spanned!(span=> #assign_to _serde::__private::Default::default());
29893024
}
29903025
attr::Default::Path(path) => {
3026+
// If #path returns wrong type, error will be reported here (^^^^^).
3027+
// We attach span of the path to the function so it will be reported
3028+
// on the #[serde(default = "...")]
3029+
// ^^^^^
29913030
return quote_spanned!(path.span()=> #assign_to #path());
29923031
}
29933032
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
@@ -898,13 +899,13 @@ impl Variant {
898899
ser_path
899900
.path
900901
.segments
901-
.push(Ident::new("serialize", Span::call_site()).into());
902+
.push(Ident::new("serialize", ser_path.span()).into());
902903
serialize_with.set(&meta.path, ser_path);
903904
let mut de_path = path;
904905
de_path
905906
.path
906907
.segments
907-
.push(Ident::new("deserialize", Span::call_site()).into());
908+
.push(Ident::new("deserialize", de_path.span()).into());
908909
deserialize_with.set(&meta.path, de_path);
909910
}
910911
} else if meta.path == SERIALIZE_WITH {
@@ -1180,13 +1181,13 @@ impl Field {
11801181
ser_path
11811182
.path
11821183
.segments
1183-
.push(Ident::new("serialize", Span::call_site()).into());
1184+
.push(Ident::new("serialize", ser_path.span()).into());
11841185
serialize_with.set(&meta.path, ser_path);
11851186
let mut de_path = path;
11861187
de_path
11871188
.path
11881189
.segments
1189-
.push(Ident::new("deserialize", Span::call_site()).into());
1190+
.push(Ident::new("deserialize", de_path.span()).into());
11901191
deserialize_with.set(&meta.path, de_path);
11911192
}
11921193
} else if meta.path == BOUND {

serde_derive/src/ser.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1229,9 +1229,15 @@ fn wrap_serialize_with(
12291229
})
12301230
});
12311231

1232-
quote!({
1232+
// If #serialize_with returns wrong type, error will be reported on here.
1233+
// We attach span of the path to this piece so error will be reported
1234+
// on the #[serde(with = "...")]
1235+
// ^^^^^
1236+
quote_spanned!(serialize_with.span()=> {
12331237
#[doc(hidden)]
12341238
struct __SerializeWith #wrapper_impl_generics #where_clause {
1239+
// If #field_tys is empty, `values` does not used
1240+
#[allow(dead_code)]
12351241
values: (#(&'__a #field_tys, )*),
12361242
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
12371243
}

0 commit comments

Comments
 (0)