Compare commits

...

13 Commits

Author SHA1 Message Date
David Tolnay 0c6a2bbf79 Release 1.0.160 2023-04-10 22:15:49 -07:00
David Tolnay a80d830f27 Merge pull request #2426 from compiler-errors/dont-doc-private
Make derived serializer/deserializer internals `doc(hidden)`
2023-04-10 22:12:35 -07:00
Michael Goulet 5f3fd9994e Make serializer/deserializer internals doc(hidden) 2023-04-10 21:41:50 -07:00
David Tolnay d6de911855 Release 1.0.159 2023-03-27 22:05:58 -07:00
David Tolnay 04af32230e Merge pull request #2422 from dtolnay/emptyattr
Accept empty #[serde()] attribute
2023-03-27 22:05:18 -07:00
David Tolnay 4cb8d079f8 Accept empty #[serde()] attribute 2023-03-27 22:00:46 -07:00
David Tolnay 6ab55a1e52 Add regression test for issue 2415
Currently fails:

    error: unexpected end of input, unexpected token in nested attribute, expected ident
     --> test_suite/tests/regression/issue2415.rs:4:9
      |
    4 | #[serde()]
      |         ^
2023-03-27 22:00:01 -07:00
David Tolnay acfd19cb46 Release serde_derive_internals 0.27.0 2023-03-20 04:32:49 -07:00
David Tolnay e3058105f0 Release 1.0.158 2023-03-20 04:24:27 -07:00
David Tolnay dc200a6450 Reformat comments of non-public serde_derive internals
Fixes these being treated as "tests" by `cargo test` in serde_derive:

    running 3 tests
    test src/internals/check.rs - internals::check::check_remote_generic (line 23) ... FAILED
    test src/internals/check.rs - internals::check::check_remote_generic (line 29) ... FAILED
    test src/lib.rs - (line 3) ... ok

    failures:

    ---- src/internals/check.rs - internals::check::check_remote_generic (line 23) stdout ----
    error: unknown start of token: \u{2026}
     --> src/internals/check.rs:25:20
      |
    4 | struct Generic<T> {…}
      |                    ^

    error: cannot find attribute `serde` in this scope
     --> src/internals/check.rs:24:3
      |
    3 | #[serde(remote = "Generic")]
      |   ^^^^^
      |
      = note: `serde` is in scope, but it is a crate, not an attribute

    error[E0392]: parameter `T` is never used
     --> src/internals/check.rs:25:16
      |
    4 | struct Generic<T> {…}
      |                ^ unused parameter
      |
      = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
      = help: if you intended `T` to be a const parameter, use `const T: usize` instead

    ---- src/internals/check.rs - internals::check::check_remote_generic (line 29) stdout ----
    error: unknown start of token: \u{2026}
     --> src/internals/check.rs:31:21
      |
    4 | struct ConcreteDef {…}
      |                     ^

    error: cannot find attribute `serde` in this scope
     --> src/internals/check.rs:30:3
      |
    3 | #[serde(remote = "Generic<T>")]
      |   ^^^^^
      |
      = note: `serde` is in scope, but it is a crate, not an attribute
2023-03-20 04:23:46 -07:00
David Tolnay 2c0999a0b9 Merge pull request #2410 from serde-rs/attrvalue
Check for None-delimited group in attribute value
2023-03-20 04:23:33 -07:00
David Tolnay dd460f82a1 Check for None-delimited group in attribute value 2023-03-20 04:16:52 -07:00
David Tolnay c3d637f397 Add regression test for issue 2409 2023-03-20 03:59:43 -07:00
14 changed files with 116 additions and 57 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.157" # remember to update html_root_url and serde_derive dependency version = "1.0.160" # remember to update html_root_url and serde_derive dependency
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs" build = "build.rs"
categories = ["encoding", "no-std"] categories = ["encoding", "no-std"]
@@ -15,7 +15,7 @@ repository = "https://github.com/serde-rs/serde"
rust-version = "1.19" rust-version = "1.19"
[dependencies] [dependencies]
serde_derive = { version = "=1.0.157", optional = true, path = "../serde_derive" } serde_derive = { version = "=1.0.160", optional = true, path = "../serde_derive" }
[dev-dependencies] [dev-dependencies]
serde_derive = { version = "1.0", path = "../serde_derive" } serde_derive = { version = "1.0", path = "../serde_derive" }
+1 -1
View File
@@ -93,7 +93,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here. // Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.157")] #![doc(html_root_url = "https://docs.rs/serde/1.0.160")]
// Support using Serde without the standard library! // Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and // Unstable functionality only if the user asks for it. For tracking and
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.157" # remember to update html_root_url version = "1.0.160" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
categories = ["no-std"] categories = ["no-std"]
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -24,7 +24,7 @@ proc-macro = true
[dependencies] [dependencies]
proc-macro2 = "1.0" proc-macro2 = "1.0"
quote = "1.0" quote = "1.0"
syn = "2.0" syn = "2.0.3"
[dev-dependencies] [dev-dependencies]
serde = { version = "1.0", path = "../serde" } serde = { version = "1.0", path = "../serde" }
+18
View File
@@ -419,6 +419,7 @@ fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fra
let expecting = cattrs.expecting().unwrap_or(&expecting); let expecting = cattrs.expecting().unwrap_or(&expecting);
quote_block! { quote_block! {
#[doc(hidden)]
struct __Visitor; struct __Visitor;
impl<'de> _serde::de::Visitor<'de> for __Visitor { impl<'de> _serde::de::Visitor<'de> for __Visitor {
@@ -515,6 +516,7 @@ fn deserialize_tuple(
}; };
quote_block! { quote_block! {
#[doc(hidden)]
struct __Visitor #de_impl_generics #where_clause { struct __Visitor #de_impl_generics #where_clause {
marker: _serde::__private::PhantomData<#this_type #ty_generics>, marker: _serde::__private::PhantomData<#this_type #ty_generics>,
lifetime: _serde::__private::PhantomData<&#delife ()>, lifetime: _serde::__private::PhantomData<&#delife ()>,
@@ -605,6 +607,7 @@ fn deserialize_tuple_in_place(
let place_life = place_lifetime(); let place_life = place_lifetime();
quote_block! { quote_block! {
#[doc(hidden)]
struct __Visitor #in_place_impl_generics #where_clause { struct __Visitor #in_place_impl_generics #where_clause {
place: &#place_life mut #this_type #ty_generics, place: &#place_life mut #this_type #ty_generics,
lifetime: _serde::__private::PhantomData<&#delife ()>, lifetime: _serde::__private::PhantomData<&#delife ()>,
@@ -1020,6 +1023,7 @@ fn deserialize_struct(
quote_block! { quote_block! {
#field_visitor #field_visitor
#[doc(hidden)]
struct __Visitor #de_impl_generics #where_clause { struct __Visitor #de_impl_generics #where_clause {
marker: _serde::__private::PhantomData<#this_type #ty_generics>, marker: _serde::__private::PhantomData<#this_type #ty_generics>,
lifetime: _serde::__private::PhantomData<&#delife ()>, lifetime: _serde::__private::PhantomData<&#delife ()>,
@@ -1132,6 +1136,7 @@ fn deserialize_struct_in_place(
Some(quote_block! { Some(quote_block! {
#field_visitor #field_visitor
#[doc(hidden)]
struct __Visitor #in_place_impl_generics #where_clause { struct __Visitor #in_place_impl_generics #where_clause {
place: &#place_life mut #this_type #ty_generics, place: &#place_life mut #this_type #ty_generics,
lifetime: _serde::__private::PhantomData<&#delife ()>, lifetime: _serde::__private::PhantomData<&#delife ()>,
@@ -1203,6 +1208,7 @@ fn prepare_enum_variant_enum(
let variants_stmt = { let variants_stmt = {
let variant_names = variant_names_idents.iter().map(|(name, _, _)| name); let variant_names = variant_names_idents.iter().map(|(name, _, _)| name);
quote! { quote! {
#[doc(hidden)]
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ]; const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
} }
}; };
@@ -1275,6 +1281,7 @@ fn deserialize_externally_tagged_enum(
quote_block! { quote_block! {
#variant_visitor #variant_visitor
#[doc(hidden)]
struct __Visitor #de_impl_generics #where_clause { struct __Visitor #de_impl_generics #where_clause {
marker: _serde::__private::PhantomData<#this_type #ty_generics>, marker: _serde::__private::PhantomData<#this_type #ty_generics>,
lifetime: _serde::__private::PhantomData<&#delife ()>, lifetime: _serde::__private::PhantomData<&#delife ()>,
@@ -1522,6 +1529,7 @@ fn deserialize_adjacently_tagged_enum(
#variants_stmt #variants_stmt
#[doc(hidden)]
struct __Seed #de_impl_generics #where_clause { struct __Seed #de_impl_generics #where_clause {
field: __Field, field: __Field,
marker: _serde::__private::PhantomData<#this_type #ty_generics>, marker: _serde::__private::PhantomData<#this_type #ty_generics>,
@@ -1541,6 +1549,7 @@ fn deserialize_adjacently_tagged_enum(
} }
} }
#[doc(hidden)]
struct __Visitor #de_impl_generics #where_clause { struct __Visitor #de_impl_generics #where_clause {
marker: _serde::__private::PhantomData<#this_type #ty_generics>, marker: _serde::__private::PhantomData<#this_type #ty_generics>,
lifetime: _serde::__private::PhantomData<&#delife ()>, lifetime: _serde::__private::PhantomData<&#delife ()>,
@@ -1643,6 +1652,7 @@ fn deserialize_adjacently_tagged_enum(
} }
} }
#[doc(hidden)]
const FIELDS: &'static [&'static str] = &[#tag, #content]; const FIELDS: &'static [&'static str] = &[#tag, #content];
_serde::Deserializer::deserialize_struct( _serde::Deserializer::deserialize_struct(
__deserializer, __deserializer,
@@ -1954,11 +1964,13 @@ fn deserialize_generated_identifier(
quote_block! { quote_block! {
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[doc(hidden)]
enum __Field #lifetime { enum __Field #lifetime {
#(#field_idents,)* #(#field_idents,)*
#ignore_variant #ignore_variant
} }
#[doc(hidden)]
struct __FieldVisitor; struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
@@ -2046,11 +2058,13 @@ fn deserialize_custom_identifier(
None None
} else if is_variant { } else if is_variant {
let variants = quote! { let variants = quote! {
#[doc(hidden)]
const VARIANTS: &'static [&'static str] = &[ #(#names),* ]; const VARIANTS: &'static [&'static str] = &[ #(#names),* ];
}; };
Some(variants) Some(variants)
} else { } else {
let fields = quote! { let fields = quote! {
#[doc(hidden)]
const FIELDS: &'static [&'static str] = &[ #(#names),* ]; const FIELDS: &'static [&'static str] = &[ #(#names),* ];
}; };
Some(fields) Some(fields)
@@ -2072,6 +2086,7 @@ fn deserialize_custom_identifier(
quote_block! { quote_block! {
#names_const #names_const
#[doc(hidden)]
struct __FieldVisitor #de_impl_generics #where_clause { struct __FieldVisitor #de_impl_generics #where_clause {
marker: _serde::__private::PhantomData<#this_type #ty_generics>, marker: _serde::__private::PhantomData<#this_type #ty_generics>,
lifetime: _serde::__private::PhantomData<&#delife ()>, lifetime: _serde::__private::PhantomData<&#delife ()>,
@@ -2406,6 +2421,7 @@ fn deserialize_struct_as_struct_visitor(
.flat_map(|(_, _, aliases)| aliases); .flat_map(|(_, _, aliases)| aliases);
quote_block! { quote_block! {
#[doc(hidden)]
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
} }
}; };
@@ -2684,6 +2700,7 @@ fn deserialize_struct_as_struct_in_place_visitor(
let fields_stmt = { let fields_stmt = {
let field_names = field_names_idents.iter().map(|(name, _, _)| name); let field_names = field_names_idents.iter().map(|(name, _, _)| name);
quote_block! { quote_block! {
#[doc(hidden)]
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
} }
}; };
@@ -2864,6 +2881,7 @@ fn wrap_deserialize_with(
let delife = params.borrowed.de_lifetime(); let delife = params.borrowed.de_lifetime();
let wrapper = quote! { let wrapper = quote! {
#[doc(hidden)]
struct __DeserializeWith #de_impl_generics #where_clause { struct __DeserializeWith #de_impl_generics #where_clause {
value: #value_ty, value: #value_ty,
phantom: _serde::__private::PhantomData<#this_type #ty_generics>, phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
+38 -15
View File
@@ -307,6 +307,12 @@ impl Container {
continue; continue;
} }
if let syn::Meta::List(meta) = &attr.meta {
if meta.tokens.is_empty() {
continue;
}
}
if let Err(err) = attr.parse_nested_meta(|meta| { if let Err(err) = attr.parse_nested_meta(|meta| {
if meta.path == RENAME { if meta.path == RENAME {
// #[serde(rename = "foo")] // #[serde(rename = "foo")]
@@ -762,6 +768,12 @@ impl Variant {
continue; continue;
} }
if let syn::Meta::List(meta) = &attr.meta {
if meta.tokens.is_empty() {
continue;
}
}
if let Err(err) = attr.parse_nested_meta(|meta| { if let Err(err) = attr.parse_nested_meta(|meta| {
if meta.path == RENAME { if meta.path == RENAME {
// #[serde(rename = "foo")] // #[serde(rename = "foo")]
@@ -1033,6 +1045,12 @@ impl Field {
continue; continue;
} }
if let syn::Meta::List(meta) = &attr.meta {
if meta.tokens.is_empty() {
continue;
}
}
if let Err(err) = attr.parse_nested_meta(|meta| { if let Err(err) = attr.parse_nested_meta(|meta| {
if meta.path == RENAME { if meta.path == RENAME {
// #[serde(rename = "foo")] // #[serde(rename = "foo")]
@@ -1381,21 +1399,26 @@ fn get_lit_str2(
meta_item_name: Symbol, meta_item_name: Symbol,
meta: &ParseNestedMeta, meta: &ParseNestedMeta,
) -> syn::Result<Option<syn::LitStr>> { ) -> syn::Result<Option<syn::LitStr>> {
match meta.value()?.parse()? { let expr: syn::Expr = meta.value()?.parse()?;
syn::Expr::Lit(syn::ExprLit { let mut value = &expr;
lit: syn::Lit::Str(lit), while let syn::Expr::Group(e) = value {
.. value = &e.expr;
}) => Ok(Some(lit)), }
expr => { if let syn::Expr::Lit(syn::ExprLit {
cx.error_spanned_by( lit: syn::Lit::Str(lit),
expr, ..
format!( }) = value
"expected serde {} attribute to be a string: `{} = \"...\"`", {
attr_name, meta_item_name Ok(Some(lit.clone()))
), } else {
); cx.error_spanned_by(
Ok(None) expr,
} format!(
"expected serde {} attribute to be a string: `{} = \"...\"`",
attr_name, meta_item_name
),
);
Ok(None)
} }
} }
+31 -32
View File
@@ -3,8 +3,8 @@ use internals::attr::{Identifier, TagType};
use internals::{ungroup, Ctxt, Derive}; use internals::{ungroup, Ctxt, Derive};
use syn::{Member, Type}; use syn::{Member, Type};
/// Cross-cutting checks that require looking at more than a single attrs // Cross-cutting checks that require looking at more than a single attrs object.
/// object. Simpler checks should happen when parsing and building the attrs. // Simpler checks should happen when parsing and building the attrs.
pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) { pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
check_remote_generic(cx, cont); check_remote_generic(cx, cont);
check_getter(cx, cont); check_getter(cx, cont);
@@ -17,18 +17,18 @@ pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
check_from_and_try_from(cx, cont); check_from_and_try_from(cx, cont);
} }
/// Remote derive definition type must have either all of the generics of the // Remote derive definition type must have either all of the generics of the
/// remote type: // remote type:
/// //
/// #[serde(remote = "Generic")] // #[serde(remote = "Generic")]
/// struct Generic<T> {…} // struct Generic<T> {…}
/// //
/// or none of them, i.e. defining impls for one concrete instantiation of the // or none of them, i.e. defining impls for one concrete instantiation of the
/// remote type only: // remote type only:
/// //
/// #[serde(remote = "Generic<T>")] // #[serde(remote = "Generic<T>")]
/// struct ConcreteDef {…} // struct ConcreteDef {…}
/// //
fn check_remote_generic(cx: &Ctxt, cont: &Container) { fn check_remote_generic(cx: &Ctxt, cont: &Container) {
if let Some(remote) = cont.attrs.remote() { if let Some(remote) = cont.attrs.remote() {
let local_has_generic = !cont.generics.params.is_empty(); let local_has_generic = !cont.generics.params.is_empty();
@@ -39,8 +39,8 @@ fn check_remote_generic(cx: &Ctxt, cont: &Container) {
} }
} }
/// Getters are only allowed inside structs (not enums) with the `remote` // Getters are only allowed inside structs (not enums) with the `remote`
/// attribute. // attribute.
fn check_getter(cx: &Ctxt, cont: &Container) { fn check_getter(cx: &Ctxt, cont: &Container) {
match cont.data { match cont.data {
Data::Enum(_) => { Data::Enum(_) => {
@@ -62,7 +62,7 @@ fn check_getter(cx: &Ctxt, cont: &Container) {
} }
} }
/// Flattening has some restrictions we can test. // Flattening has some restrictions we can test.
fn check_flatten(cx: &Ctxt, cont: &Container) { fn check_flatten(cx: &Ctxt, cont: &Container) {
match &cont.data { match &cont.data {
Data::Enum(variants) => { Data::Enum(variants) => {
@@ -101,12 +101,12 @@ fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
} }
} }
/// The `other` attribute must be used at most once and it must be the last // The `other` attribute must be used at most once and it must be the last
/// variant of an enum. // variant of an enum.
/// //
/// Inside a `variant_identifier` all variants must be unit variants. Inside a // Inside a `variant_identifier` all variants must be unit variants. Inside a
/// `field_identifier` all but possibly one variant must be unit variants. The // `field_identifier` all but possibly one variant must be unit variants. The
/// last variant may be a newtype variant which is an implicit "other" case. // last variant may be a newtype variant which is an implicit "other" case.
fn check_identifier(cx: &Ctxt, cont: &Container) { fn check_identifier(cx: &Ctxt, cont: &Container) {
let variants = match &cont.data { let variants = match &cont.data {
Data::Enum(variants) => variants, Data::Enum(variants) => variants,
@@ -189,8 +189,8 @@ fn check_identifier(cx: &Ctxt, cont: &Container) {
} }
} }
/// Skip-(de)serializing attributes are not allowed on variants marked // Skip-(de)serializing attributes are not allowed on variants marked
/// (de)serialize_with. // (de)serialize_with.
fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) { fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
let variants = match &cont.data { let variants = match &cont.data {
Data::Enum(variants) => variants, Data::Enum(variants) => variants,
@@ -264,10 +264,9 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
} }
} }
/// The tag of an internally-tagged struct variant must not be // The tag of an internally-tagged struct variant must not be the same as either
/// the same as either one of its fields, as this would result in // one of its fields, as this would result in duplicate keys in the serialized
/// duplicate keys in the serialized output and/or ambiguity in // output and/or ambiguity in the to-be-deserialized input.
/// the to-be-deserialized input.
fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) { fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
let variants = match &cont.data { let variants = match &cont.data {
Data::Enum(variants) => variants, Data::Enum(variants) => variants,
@@ -313,8 +312,8 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
} }
} }
/// In the case of adjacently-tagged enums, the type and the // In the case of adjacently-tagged enums, the type and the contents tag must
/// contents tag must differ, for the same reason. // differ, for the same reason.
fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) { fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
let (type_tag, content_tag) = match cont.attrs.tag() { let (type_tag, content_tag) = match cont.attrs.tag() {
TagType::Adjacent { tag, content } => (tag, content), TagType::Adjacent { tag, content } => (tag, content),
@@ -332,7 +331,7 @@ fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
} }
} }
/// Enums and unit structs cannot be transparent. // Enums and unit structs cannot be transparent.
fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) { fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
if !cont.attrs.transparent() { if !cont.attrs.transparent() {
return; return;
+1 -1
View File
@@ -13,7 +13,7 @@
//! //!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.157")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.160")]
#![allow(unknown_lints, bare_trait_objects)] #![allow(unknown_lints, bare_trait_objects)]
// Ignored clippy lints // Ignored clippy lints
#![allow( #![allow(
+3
View File
@@ -719,6 +719,7 @@ fn serialize_adjacently_tagged_variant(
let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
quote_block! { quote_block! {
#[doc(hidden)]
struct __AdjacentlyTagged #wrapper_generics #where_clause { struct __AdjacentlyTagged #wrapper_generics #where_clause {
data: (#(&'__a #fields_ty,)*), data: (#(&'__a #fields_ty,)*),
phantom: _serde::__private::PhantomData<#this_type #ty_generics>, phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
@@ -982,6 +983,7 @@ fn serialize_struct_variant_with_flatten(
let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
quote_block! { quote_block! {
#[doc(hidden)]
struct __EnumFlatten #wrapper_generics #where_clause { struct __EnumFlatten #wrapper_generics #where_clause {
data: (#(&'__a #fields_ty,)*), data: (#(&'__a #fields_ty,)*),
phantom: _serde::__private::PhantomData<#this_type #ty_generics>, phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
@@ -1212,6 +1214,7 @@ fn wrap_serialize_with(
}); });
quote!({ quote!({
#[doc(hidden)]
struct __SerializeWith #wrapper_impl_generics #where_clause { struct __SerializeWith #wrapper_impl_generics #where_clause {
values: (#(&'__a #field_tys, )*), values: (#(&'__a #field_tys, )*),
phantom: _serde::__private::PhantomData<#this_type #ty_generics>, phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive_internals" name = "serde_derive_internals"
version = "0.26.0" # remember to update html_root_url version = "0.27.0" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
description = "AST representation used by Serde derive macros. Unstable." description = "AST representation used by Serde derive macros. Unstable."
documentation = "https://docs.rs/serde_derive_internals" documentation = "https://docs.rs/serde_derive_internals"
+1 -1
View File
@@ -1,4 +1,4 @@
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.26.0")] #![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.27.0")]
#![allow(unknown_lints, bare_trait_objects)] #![allow(unknown_lints, bare_trait_objects)]
// Ignored clippy lints // Ignored clippy lints
#![allow( #![allow(
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "1.0.157" # remember to update html_root_url version = "1.0.160" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs" build = "build.rs"
categories = ["development-tools::testing"] categories = ["development-tools::testing"]
+1 -1
View File
@@ -140,7 +140,7 @@
//! # } //! # }
//! ``` //! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.157")] #![doc(html_root_url = "https://docs.rs/serde_test/1.0.160")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
// Ignored clippy lints // Ignored clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))] #![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))]
+11
View File
@@ -0,0 +1,11 @@
use serde::Deserialize;
macro_rules! bug {
($serde_path:literal) => {
#[derive(Deserialize)]
#[serde(crate = $serde_path)]
pub struct Struct;
};
}
bug!("serde");
+5
View File
@@ -0,0 +1,5 @@
use serde_derive::Serialize;
#[derive(Serialize)]
#[serde()]
pub struct S;