Skip to content

Commit

Permalink
Merge pull request #5 from serde-rs/master
Browse files Browse the repository at this point in the history
Fork Sync: Update from parent repository
  • Loading branch information
github-actions[bot] authored Oct 22, 2024
2 parents b92aae7 + 3415619 commit 3420bfd
Show file tree
Hide file tree
Showing 31 changed files with 654 additions and 61 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ serde = { path = "serde" }
[workspace.dependencies]
proc-macro2 = { version = "1.0.74", default-features = false }
quote = { version = "1.0.35", default-features = false }
syn = { version = "2.0.46", default-features = false }
syn = { version = "2.0.81", default-features = false }
4 changes: 3 additions & 1 deletion serde_derive/src/bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,9 @@ pub fn with_bound(
match bound {
#![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
syn::TypeParamBound::Trait(bound) => self.visit_path(&bound.path),
syn::TypeParamBound::Lifetime(_) | syn::TypeParamBound::Verbatim(_) => {}
syn::TypeParamBound::Lifetime(_)
| syn::TypeParamBound::PreciseCapture(_)
| syn::TypeParamBound::Verbatim(_) => {}
_ => {}
}
}
Expand Down
117 changes: 65 additions & 52 deletions serde_derive/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,11 @@ fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
} else {
let value = match field.attrs.default() {
attr::Default::Default => quote!(_serde::__private::Default::default()),
attr::Default::Path(path) => quote!(#path()),
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
attr::Default::Path(path) => quote_spanned!(path.span()=> #path()),
attr::Default::None => quote!(_serde::__private::PhantomData),
};
quote!(#member: #value)
Expand Down Expand Up @@ -757,7 +761,11 @@ fn deserialize_seq(
attr::Default::Default => Some(quote!(
let __default: Self::Value = _serde::__private::Default::default();
)),
attr::Default::Path(path) => Some(quote!(
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
let __default: Self::Value = #path();
)),
attr::Default::None => {
Expand Down Expand Up @@ -839,7 +847,11 @@ fn deserialize_seq_in_place(
attr::Default::Default => Some(quote!(
let __default: #this_type #ty_generics = _serde::__private::Default::default();
)),
attr::Default::Path(path) => Some(quote!(
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
let __default: #this_type #ty_generics = #path();
)),
attr::Default::None => {
Expand Down Expand Up @@ -873,7 +885,11 @@ fn deserialize_newtype_struct(
}
}
Some(path) => {
quote! {
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(with = "...")]
// ^^^^^
quote_spanned! {path.span()=>
#path(__e)?
}
}
Expand Down Expand Up @@ -956,13 +972,7 @@ fn deserialize_struct(
// Skip fields that shouldn't be deserialized or that were flattened,
// so they don't appear in the storage in their literal form
.filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
.map(|(i, field)| {
(
field.attrs.name().deserialize_name(),
field_i(i),
field.attrs.aliases(),
)
})
.map(|(i, field)| (field_i(i), field.attrs.aliases()))
.collect();

let has_flatten = has_flatten(fields);
Expand Down Expand Up @@ -1022,9 +1032,7 @@ fn deserialize_struct(
let fields_stmt = if has_flatten {
None
} else {
let field_names = field_names_idents
.iter()
.flat_map(|&(_, _, aliases)| aliases);
let field_names = field_names_idents.iter().flat_map(|&(_, aliases)| aliases);

Some(quote! {
#[doc(hidden)]
Expand Down Expand Up @@ -1121,13 +1129,7 @@ fn deserialize_struct_in_place(
.iter()
.enumerate()
.filter(|&(_, field)| !field.attrs.skip_deserializing())
.map(|(i, field)| {
(
field.attrs.name().deserialize_name(),
field_i(i),
field.attrs.aliases(),
)
})
.map(|(i, field)| (field_i(i), field.attrs.aliases()))
.collect();

let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs, false);
Expand All @@ -1139,9 +1141,7 @@ fn deserialize_struct_in_place(
};
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting));
let visit_map = Stmts(deserialize_map_in_place(params, fields, cattrs));
let field_names = field_names_idents
.iter()
.flat_map(|&(_, _, aliases)| aliases);
let field_names = field_names_idents.iter().flat_map(|&(_, aliases)| aliases);
let type_name = cattrs.name().deserialize_name();

let in_place_impl_generics = de_impl_generics.in_place();
Expand Down Expand Up @@ -1232,24 +1232,20 @@ fn prepare_enum_variant_enum(variants: &[Variant]) -> (TokenStream, Stmts) {

let variant_names_idents: Vec<_> = deserialized_variants
.clone()
.map(|(i, variant)| {
(
variant.attrs.name().deserialize_name(),
field_i(i),
variant.attrs.aliases(),
)
})
.map(|(i, variant)| (field_i(i), variant.attrs.aliases()))
.collect();

let fallthrough = deserialized_variants
.position(|(_, variant)| variant.attrs.other())
.map(|other_idx| {
let ignore_variant = variant_names_idents[other_idx].1.clone();
let ignore_variant = variant_names_idents[other_idx].0.clone();
quote!(_serde::__private::Ok(__Field::#ignore_variant))
});

let variants_stmt = {
let variant_names = variant_names_idents.iter().map(|(name, _, _)| name);
let variant_names = variant_names_idents
.iter()
.flat_map(|&(_, aliases)| aliases);
quote! {
#[doc(hidden)]
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
Expand Down Expand Up @@ -2015,14 +2011,14 @@ fn deserialize_untagged_newtype_variant(
}

fn deserialize_generated_identifier(
fields: &[(&str, Ident, &BTreeSet<String>)],
fields: &[(Ident, &BTreeSet<String>)],
has_flatten: bool,
is_variant: bool,
ignore_variant: Option<TokenStream>,
fallthrough: Option<TokenStream>,
) -> Fragment {
let this_value = quote!(__Field);
let field_idents: &Vec<_> = &fields.iter().map(|(_, ident, _)| ident).collect();
let field_idents: &Vec<_> = &fields.iter().map(|(ident, _)| ident).collect();

let visitor_impl = Stmts(deserialize_identifier(
&this_value,
Expand Down Expand Up @@ -2072,7 +2068,7 @@ fn deserialize_generated_identifier(
/// Generates enum and its `Deserialize` implementation that represents each
/// non-skipped field of the struct
fn deserialize_field_identifier(
fields: &[(&str, Ident, &BTreeSet<String>)],
fields: &[(Ident, &BTreeSet<String>)],
cattrs: &attr::Container,
has_flatten: bool,
) -> Stmts {
Expand Down Expand Up @@ -2149,16 +2145,10 @@ fn deserialize_custom_identifier(

let names_idents: Vec<_> = ordinary
.iter()
.map(|variant| {
(
variant.attrs.name().deserialize_name(),
variant.ident.clone(),
variant.attrs.aliases(),
)
})
.map(|variant| (variant.ident.clone(), variant.attrs.aliases()))
.collect();

let names = names_idents.iter().flat_map(|&(_, _, aliases)| aliases);
let names = names_idents.iter().flat_map(|&(_, aliases)| aliases);

let names_const = if fallthrough.is_some() {
None
Expand Down Expand Up @@ -2214,18 +2204,18 @@ fn deserialize_custom_identifier(

fn deserialize_identifier(
this_value: &TokenStream,
fields: &[(&str, Ident, &BTreeSet<String>)],
fields: &[(Ident, &BTreeSet<String>)],
is_variant: bool,
fallthrough: Option<TokenStream>,
fallthrough_borrowed: Option<TokenStream>,
collect_other_fields: bool,
expecting: Option<&str>,
) -> Fragment {
let str_mapping = fields.iter().map(|(_, ident, aliases)| {
let str_mapping = fields.iter().map(|(ident, aliases)| {
// `aliases` also contains a main name
quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
});
let bytes_mapping = fields.iter().map(|(_, ident, aliases)| {
let bytes_mapping = fields.iter().map(|(ident, aliases)| {
// `aliases` also contains a main name
let aliases = aliases
.iter()
Expand Down Expand Up @@ -2380,7 +2370,7 @@ fn deserialize_identifier(
}
}
} else {
let u64_mapping = fields.iter().enumerate().map(|(i, (_, ident, _))| {
let u64_mapping = fields.iter().enumerate().map(|(i, (ident, _))| {
let i = i as u64;
quote!(#i => _serde::__private::Ok(#this_value::#ident))
});
Expand Down Expand Up @@ -2667,7 +2657,11 @@ fn deserialize_map(
attr::Default::Default => Some(quote!(
let __default: Self::Value = _serde::__private::Default::default();
)),
attr::Default::Path(path) => Some(quote!(
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
let __default: Self::Value = #path();
)),
attr::Default::None => {
Expand Down Expand Up @@ -2837,7 +2831,11 @@ fn deserialize_map_in_place(
attr::Default::Default => Some(quote!(
let __default: #this_type #ty_generics = _serde::__private::Default::default();
)),
attr::Default::Path(path) => Some(quote!(
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
let __default: #this_type #ty_generics = #path();
)),
attr::Default::None => {
Expand Down Expand Up @@ -2876,6 +2874,13 @@ fn wrap_deserialize_with(
split_with_de_lifetime(params);
let delife = params.borrowed.de_lifetime();

// If #deserialize_with returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(with = "...")]
// ^^^^^
let value = quote_spanned! {deserialize_with.span()=>
#deserialize_with(__deserializer)?
};
let wrapper = quote! {
#[doc(hidden)]
struct __DeserializeWith #de_impl_generics #where_clause {
Expand All @@ -2890,7 +2895,7 @@ fn wrap_deserialize_with(
__D: _serde::Deserializer<#delife>,
{
_serde::__private::Ok(__DeserializeWith {
value: #deserialize_with(__deserializer)?,
value: #value,
phantom: _serde::__private::PhantomData,
lifetime: _serde::__private::PhantomData,
})
Expand Down Expand Up @@ -2981,7 +2986,11 @@ fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
return quote_expr!(#func());
}
attr::Default::Path(path) => {
return quote_expr!(#path());
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
return Fragment::Expr(quote_spanned!(path.span()=> #path()));
}
attr::Default::None => { /* below */ }
}
Expand Down Expand Up @@ -3024,6 +3033,10 @@ fn expr_is_missing_seq(
return quote_spanned!(span=> #assign_to _serde::__private::Default::default());
}
attr::Default::Path(path) => {
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
return quote_spanned!(path.span()=> #assign_to #path());
}
attr::Default::None => { /* below */ }
Expand Down
9 changes: 5 additions & 4 deletions serde_derive/src/internals/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::iter::FromIterator;
use syn::meta::ParseNestedMeta;
use syn::parse::ParseStream;
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{parse_quote, token, Ident, Lifetime, Token};

// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
Expand Down Expand Up @@ -888,13 +889,13 @@ impl Variant {
ser_path
.path
.segments
.push(Ident::new("serialize", Span::call_site()).into());
.push(Ident::new("serialize", ser_path.span()).into());
serialize_with.set(&meta.path, ser_path);
let mut de_path = path;
de_path
.path
.segments
.push(Ident::new("deserialize", Span::call_site()).into());
.push(Ident::new("deserialize", de_path.span()).into());
deserialize_with.set(&meta.path, de_path);
}
} else if meta.path == SERIALIZE_WITH {
Expand Down Expand Up @@ -1170,13 +1171,13 @@ impl Field {
ser_path
.path
.segments
.push(Ident::new("serialize", Span::call_site()).into());
.push(Ident::new("serialize", ser_path.span()).into());
serialize_with.set(&meta.path, ser_path);
let mut de_path = path;
de_path
.path
.segments
.push(Ident::new("deserialize", Span::call_site()).into());
.push(Ident::new("deserialize", de_path.span()).into());
deserialize_with.set(&meta.path, de_path);
}
} else if meta.path == BOUND {
Expand Down
4 changes: 3 additions & 1 deletion serde_derive/src/internals/receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ impl ReplaceReceiver<'_> {
match bound {
#![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
TypeParamBound::Trait(bound) => self.visit_path_mut(&mut bound.path),
TypeParamBound::Lifetime(_) | TypeParamBound::Verbatim(_) => {}
TypeParamBound::Lifetime(_)
| TypeParamBound::PreciseCapture(_)
| TypeParamBound::Verbatim(_) => {}
_ => {}
}
}
Expand Down
8 changes: 7 additions & 1 deletion serde_derive/src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1220,9 +1220,15 @@ fn wrap_serialize_with(
})
});

quote!({
// If #serialize_with returns wrong type, error will be reported on here.
// We attach span of the path to this piece so error will be reported
// on the #[serde(with = "...")]
// ^^^^^
quote_spanned!(serialize_with.span()=> {
#[doc(hidden)]
struct __SerializeWith #wrapper_impl_generics #where_clause {
// If #field_tys is empty, `values` does not used
#[allow(dead_code)]
values: (#(&'__a #field_tys, )*),
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
}
Expand Down
2 changes: 1 addition & 1 deletion test_suite/tests/test_annotations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ fn test_unknown_field_rename_enum() {
variant: "SailorMoon",
len: 3,
}],
"unknown variant `SailorMoon`, expected `sailor_moon`",
"unknown variant `SailorMoon`, expected `sailor_moon` or `usagi_tsukino`",
);

assert_de_tokens_error::<AliasEnum>(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//! Ensures that error message points to the path in attribute
use serde_derive::Deserialize;

#[derive(Deserialize)]
#[serde(tag = "tag", content = "content")]
enum Enum {
// Newtype variants does not use the provided path, so it is forbidden here
// Newtype(#[serde(default = "main")] u8),
Tuple(
u8,
#[serde(default = "main")] i8,
),
Struct {
#[serde(default = "main")]
f1: u8,
f2: u8,
#[serde(default = "main")]
f3: i8,
},
}

fn main() {}
Loading

0 comments on commit 3420bfd

Please sign in to comment.