Compare commits

...

9 Commits

Author SHA1 Message Date
David Tolnay 1d7899d671 Release 1.0.225 2025-09-15 20:43:08 -07:00
David Tolnay 97168d3a24 Touch up PR 2879 2025-09-15 20:38:57 -07:00
David Tolnay 373b11dda7 Merge pull request 2879 from rcrisanti/fix/silence-deprecation-warnings-derive 2025-09-15 20:26:40 -07:00
David Tolnay 69072f2423 Merge pull request 2931 from Mingun/unify-serde-access 2025-09-15 13:22:24 -07:00
David Tolnay 5b37e8a531 Merge pull request #2980 from dtolnay/private
Use differently named __private module per patch release
2025-09-15 13:20:54 -07:00
Mingun b47f4dfa96 Unify access to the serde namespace
In other places `_serde` name is used to access the `serde` crate, so use it there
2025-09-16 00:36:12 +05:00
David Tolnay cbe98a9888 Use differently named __private module per patch release 2025-09-15 09:53:14 -07:00
David Tolnay 957996f5fb Make all use of __private go through interpolation 2025-09-15 09:48:26 -07:00
Ryan Crisanti ae38b27aee add #[allow(deprecated)] to derive implementations
Allow deprecated in the `Serialize`/`Deserialize`
derive implementations. This allows you to
deprecate structs, enums, struct fields, or enum
variants and not get compiler warnings/errors
about use of deprecated thing. We only do this
if `#[deprecated]` or `#[allow(deprecated)]` exist
on the root object or the variants of the root
object (if it is an enum).

Resolves #2195
2025-05-30 15:01:14 -04:00
21 changed files with 565 additions and 335 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.224" version = "1.0.225"
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", "no-std::no-alloc"] categories = ["encoding", "no-std", "no-std::no-alloc"]
@@ -15,7 +15,7 @@ repository = "https://github.com/serde-rs/serde"
rust-version = "1.56" rust-version = "1.56"
[dependencies] [dependencies]
serde_core = { version = "=1.0.224", path = "../serde_core", default-features = false, features = ["result"] } serde_core = { version = "=1.0.225", path = "../serde_core", default-features = false, features = ["result"] }
serde_derive = { version = "1", optional = true, path = "../serde_derive" } serde_derive = { version = "1", optional = true, path = "../serde_derive" }
[package.metadata.playground] [package.metadata.playground]
+16
View File
@@ -1,13 +1,29 @@
use std::env; use std::env;
use std::fs;
use std::path::PathBuf;
use std::process::Command; use std::process::Command;
use std::str; use std::str;
const PRIVATE: &str = "\
#[doc(hidden)]
pub mod __private$$ {
#[doc(hidden)]
pub use crate::private::*;
}
use serde_core::__private$$ as serde_core_private;
";
// The rustc-cfg strings below are *not* public API. Please let us know by // The rustc-cfg strings below are *not* public API. Please let us know by
// opening a GitHub issue if your build environment requires some way to enable // opening a GitHub issue if your build environment requires some way to enable
// these cfgs other than by executing our build script. // these cfgs other than by executing our build script.
fn main() { fn main() {
println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build.rs");
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let patch_version = env::var("CARGO_PKG_VERSION_PATCH").unwrap();
let module = PRIVATE.replace("$$", &patch_version);
fs::write(out_dir.join("private.rs"), module).unwrap();
let minor = match rustc_minor_version() { let minor = match rustc_minor_version() {
Some(minor) => minor, Some(minor) => minor,
None => return, None => return,
+4 -3
View File
@@ -95,7 +95,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.224")] #![doc(html_root_url = "https://docs.rs/serde/1.0.225")]
// 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)]
// Show which crate feature enables conditionally compiled APIs in documentation. // Show which crate feature enables conditionally compiled APIs in documentation.
@@ -239,8 +239,9 @@ mod integer128;
// Used by generated code and doc tests. Not public API. // Used by generated code and doc tests. Not public API.
#[doc(hidden)] #[doc(hidden)]
#[path = "private/mod.rs"] mod private;
pub mod __private;
include!(concat!(env!("OUT_DIR"), "/private.rs"));
// Re-export #[derive(Serialize, Deserialize)]. // Re-export #[derive(Serialize, Deserialize)].
// //
+3 -3
View File
@@ -17,7 +17,7 @@ pub use self::content::{
UntaggedUnitVisitor, UntaggedUnitVisitor,
}; };
pub use serde_core::__private::InPlaceSeed; pub use crate::serde_core_private::InPlaceSeed;
/// If the missing field is of type `Option<T>` then treat is as `None`, /// If the missing field is of type `Option<T>` then treat is as `None`,
/// otherwise it is an error. /// otherwise it is an error.
@@ -216,8 +216,8 @@ mod content {
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny, self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
MapAccess, SeqAccess, Unexpected, Visitor, MapAccess, SeqAccess, Unexpected, Visitor,
}; };
use serde_core::__private::size_hint; use crate::serde_core_private::size_hint;
pub use serde_core::__private::Content; pub use crate::serde_core_private::Content;
pub fn content_as_str<'a, 'de>(content: &'a Content<'de>) -> Option<&'a str> { pub fn content_as_str<'a, 'de>(content: &'a Content<'de>) -> Option<&'a str> {
match *content { match *content {
+1 -1
View File
@@ -12,7 +12,7 @@ pub use crate::lib::option::Option::{self, None, Some};
pub use crate::lib::ptr; pub use crate::lib::ptr;
pub use crate::lib::result::Result::{self, Err, Ok}; pub use crate::lib::result::Result::{self, Err, Ok};
pub use serde_core::__private::string::from_utf8_lossy; pub use crate::serde_core_private::string::from_utf8_lossy;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
pub use crate::lib::{ToString, Vec}; pub use crate::lib::{ToString, Vec};
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_core" name = "serde_core"
version = "1.0.224" version = "1.0.225"
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", "no-std::no-alloc"] categories = ["encoding", "no-std", "no-std::no-alloc"]
@@ -36,7 +36,7 @@ rustdoc-args = [
# is compatible with exactly one serde release because the generated code # is compatible with exactly one serde release because the generated code
# involves nonpublic APIs which are not bound by semver. # involves nonpublic APIs which are not bound by semver.
[target.'cfg(any())'.dependencies] [target.'cfg(any())'.dependencies]
serde_derive = { version = "=1.0.224", path = "../serde_derive" } serde_derive = { version = "=1.0.225", path = "../serde_derive" }
### FEATURES ################################################################# ### FEATURES #################################################################
+15
View File
@@ -1,13 +1,28 @@
use std::env; use std::env;
use std::fs;
use std::path::PathBuf;
use std::process::Command; use std::process::Command;
use std::str; use std::str;
const PRIVATE: &str = "\
#[doc(hidden)]
pub mod __private$$ {
#[doc(hidden)]
pub use crate::private::*;
}
";
// The rustc-cfg strings below are *not* public API. Please let us know by // The rustc-cfg strings below are *not* public API. Please let us know by
// opening a GitHub issue if your build environment requires some way to enable // opening a GitHub issue if your build environment requires some way to enable
// these cfgs other than by executing our build script. // these cfgs other than by executing our build script.
fn main() { fn main() {
println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build.rs");
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let patch_version = env::var("CARGO_PKG_VERSION_PATCH").unwrap();
let module = PRIVATE.replace("$$", &patch_version);
fs::write(out_dir.join("private.rs"), module).unwrap();
let minor = match rustc_minor_version() { let minor = match rustc_minor_version() {
Some(minor) => minor, Some(minor) => minor,
None => return, None => return,
+13 -4
View File
@@ -35,7 +35,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_core/1.0.224")] #![doc(html_root_url = "https://docs.rs/serde_core/1.0.225")]
// 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)]
// Show which crate feature enables conditionally compiled APIs in documentation. // Show which crate feature enables conditionally compiled APIs in documentation.
@@ -252,9 +252,18 @@ pub use crate::ser::{Serialize, Serializer};
// Used by generated code. Not public API. // Used by generated code. Not public API.
#[doc(hidden)] #[doc(hidden)]
#[path = "private/mod.rs"] mod private;
pub mod __private;
use self::__private as private; // Used by declarative macro generated code. Not public API.
#[doc(hidden)]
pub mod __private {
#[doc(hidden)]
pub use crate::private::doc;
#[doc(hidden)]
pub use core::result::Result;
}
include!(concat!(env!("OUT_DIR"), "/private.rs"));
#[cfg(all(not(feature = "std"), no_core_error))] #[cfg(all(not(feature = "std"), no_core_error))]
mod std_error; mod std_error;
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.224" version = "1.0.225"
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", "no-std::no-alloc"] categories = ["no-std", "no-std::no-alloc"]
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
+268 -262
View File
File diff suppressed because it is too large Load Diff
+56
View File
@@ -0,0 +1,56 @@
use proc_macro2::TokenStream;
use quote::quote;
pub fn allow_deprecated(input: &syn::DeriveInput) -> Option<TokenStream> {
if should_allow_deprecated(input) {
Some(quote! { #[allow(deprecated)] })
} else {
None
}
}
/// Determine if an `#[allow(deprecated)]` should be added to the derived impl.
///
/// This should happen if the derive input or an enum variant it contains has
/// one of:
/// - `#[deprecated]`
/// - `#[allow(deprecated)]`
fn should_allow_deprecated(input: &syn::DeriveInput) -> bool {
if contains_deprecated(&input.attrs) {
return true;
}
if let syn::Data::Enum(data_enum) = &input.data {
for variant in &data_enum.variants {
if contains_deprecated(&variant.attrs) {
return true;
}
}
}
false
}
/// Check whether the given attributes contains one of:
/// - `#[deprecated]`
/// - `#[allow(deprecated)]`
fn contains_deprecated(attrs: &[syn::Attribute]) -> bool {
for attr in attrs {
if attr.path().is_ident("deprecated") {
return true;
}
if let syn::Meta::List(meta_list) = &attr.meta {
if meta_list.path.is_ident("allow") {
let mut allow_deprecated = false;
let _ = meta_list.parse_nested_meta(|meta| {
if meta.path.is_ident("deprecated") {
allow_deprecated = true;
}
Ok(())
});
if allow_deprecated {
return true;
}
}
}
}
false
}
+21 -8
View File
@@ -1,6 +1,7 @@
//! A Serde ast, parsed from the Syn ast and ready to generate Rust code. //! A Serde ast, parsed from the Syn ast and ready to generate Rust code.
use crate::internals::{attr, check, Ctxt, Derive}; use crate::internals::{attr, check, Ctxt, Derive};
use proc_macro2::Ident;
use syn::punctuated::Punctuated; use syn::punctuated::Punctuated;
use syn::Token; use syn::Token;
@@ -62,13 +63,17 @@ impl<'a> Container<'a> {
cx: &Ctxt, cx: &Ctxt,
item: &'a syn::DeriveInput, item: &'a syn::DeriveInput,
derive: Derive, derive: Derive,
private: &Ident,
) -> Option<Container<'a>> { ) -> Option<Container<'a>> {
let attrs = attr::Container::from_ast(cx, item); let attrs = attr::Container::from_ast(cx, item);
let mut data = match &item.data { let mut data = match &item.data {
syn::Data::Enum(data) => Data::Enum(enum_from_ast(cx, &data.variants, attrs.default())), syn::Data::Enum(data) => {
Data::Enum(enum_from_ast(cx, &data.variants, attrs.default(), private))
}
syn::Data::Struct(data) => { syn::Data::Struct(data) => {
let (style, fields) = struct_from_ast(cx, &data.fields, None, attrs.default()); let (style, fields) =
struct_from_ast(cx, &data.fields, None, attrs.default(), private);
Data::Struct(style, fields) Data::Struct(style, fields)
} }
syn::Data::Union(_) => { syn::Data::Union(_) => {
@@ -129,13 +134,19 @@ fn enum_from_ast<'a>(
cx: &Ctxt, cx: &Ctxt,
variants: &'a Punctuated<syn::Variant, Token![,]>, variants: &'a Punctuated<syn::Variant, Token![,]>,
container_default: &attr::Default, container_default: &attr::Default,
private: &Ident,
) -> Vec<Variant<'a>> { ) -> Vec<Variant<'a>> {
let variants: Vec<Variant> = variants let variants: Vec<Variant> = variants
.iter() .iter()
.map(|variant| { .map(|variant| {
let attrs = attr::Variant::from_ast(cx, variant); let attrs = attr::Variant::from_ast(cx, variant);
let (style, fields) = let (style, fields) = struct_from_ast(
struct_from_ast(cx, &variant.fields, Some(&attrs), container_default); cx,
&variant.fields,
Some(&attrs),
container_default,
private,
);
Variant { Variant {
ident: variant.ident.clone(), ident: variant.ident.clone(),
attrs, attrs,
@@ -165,19 +176,20 @@ fn struct_from_ast<'a>(
fields: &'a syn::Fields, fields: &'a syn::Fields,
attrs: Option<&attr::Variant>, attrs: Option<&attr::Variant>,
container_default: &attr::Default, container_default: &attr::Default,
private: &Ident,
) -> (Style, Vec<Field<'a>>) { ) -> (Style, Vec<Field<'a>>) {
match fields { match fields {
syn::Fields::Named(fields) => ( syn::Fields::Named(fields) => (
Style::Struct, Style::Struct,
fields_from_ast(cx, &fields.named, attrs, container_default), fields_from_ast(cx, &fields.named, attrs, container_default, private),
), ),
syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => ( syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => (
Style::Newtype, Style::Newtype,
fields_from_ast(cx, &fields.unnamed, attrs, container_default), fields_from_ast(cx, &fields.unnamed, attrs, container_default, private),
), ),
syn::Fields::Unnamed(fields) => ( syn::Fields::Unnamed(fields) => (
Style::Tuple, Style::Tuple,
fields_from_ast(cx, &fields.unnamed, attrs, container_default), fields_from_ast(cx, &fields.unnamed, attrs, container_default, private),
), ),
syn::Fields::Unit => (Style::Unit, Vec::new()), syn::Fields::Unit => (Style::Unit, Vec::new()),
} }
@@ -188,6 +200,7 @@ fn fields_from_ast<'a>(
fields: &'a Punctuated<syn::Field, Token![,]>, fields: &'a Punctuated<syn::Field, Token![,]>,
attrs: Option<&attr::Variant>, attrs: Option<&attr::Variant>,
container_default: &attr::Default, container_default: &attr::Default,
private: &Ident,
) -> Vec<Field<'a>> { ) -> Vec<Field<'a>> {
fields fields
.iter() .iter()
@@ -197,7 +210,7 @@ fn fields_from_ast<'a>(
Some(ident) => syn::Member::Named(ident.clone()), Some(ident) => syn::Member::Named(ident.clone()),
None => syn::Member::Unnamed(i.into()), None => syn::Member::Unnamed(i.into()),
}, },
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default), attrs: attr::Field::from_ast(cx, i, field, attrs, container_default, private),
ty: &field.ty, ty: &field.ty,
original: field, original: field,
}) })
+4 -9
View File
@@ -3,14 +3,13 @@ use crate::internals::symbol::*;
use crate::internals::{ungroup, Ctxt}; use crate::internals::{ungroup, Ctxt};
use proc_macro2::{Spacing, Span, TokenStream, TokenTree}; use proc_macro2::{Spacing, Span, TokenStream, TokenTree};
use quote::ToTokens; use quote::ToTokens;
use std::borrow::Cow;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::iter::FromIterator; use std::iter::FromIterator;
use syn::meta::ParseNestedMeta; use syn::meta::ParseNestedMeta;
use syn::parse::ParseStream; use syn::parse::ParseStream;
use syn::punctuated::Punctuated; use syn::punctuated::Punctuated;
use syn::spanned::Spanned; use syn::spanned::Spanned;
use syn::{parse_quote, token, Ident, Lifetime, Token}; use syn::{token, Ident, Lifetime, Token};
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints // This module handles parsing of `#[serde(...)]` attributes. The entrypoints
// are `attr::Container::from_ast`, `attr::Variant::from_ast`, and // are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
@@ -609,11 +608,6 @@ impl Container {
self.serde_path.as_ref() self.serde_path.as_ref()
} }
pub fn serde_path(&self) -> Cow<syn::Path> {
self.custom_serde_path()
.map_or_else(|| Cow::Owned(parse_quote!(_serde)), Cow::Borrowed)
}
/// Error message generated when type can't be deserialized. /// Error message generated when type can't be deserialized.
/// If `None`, default message will be used /// If `None`, default message will be used
pub fn expecting(&self) -> Option<&str> { pub fn expecting(&self) -> Option<&str> {
@@ -1024,6 +1018,7 @@ impl Field {
field: &syn::Field, field: &syn::Field,
attrs: Option<&Variant>, attrs: Option<&Variant>,
container_default: &Default, container_default: &Default,
private: &Ident,
) -> Self { ) -> Self {
let mut ser_name = Attr::none(cx, RENAME); let mut ser_name = Attr::none(cx, RENAME);
let mut de_name = Attr::none(cx, RENAME); let mut de_name = Attr::none(cx, RENAME);
@@ -1217,7 +1212,7 @@ impl Field {
}; };
let span = Span::call_site(); let span = Span::call_site();
path.segments.push(Ident::new("_serde", span).into()); path.segments.push(Ident::new("_serde", span).into());
path.segments.push(Ident::new("__private", span).into()); path.segments.push(private.clone().into());
path.segments.push(Ident::new("de", span).into()); path.segments.push(Ident::new("de", span).into());
path.segments path.segments
.push(Ident::new("borrow_cow_str", span).into()); .push(Ident::new("borrow_cow_str", span).into());
@@ -1234,7 +1229,7 @@ impl Field {
}; };
let span = Span::call_site(); let span = Span::call_site();
path.segments.push(Ident::new("_serde", span).into()); path.segments.push(Ident::new("_serde", span).into());
path.segments.push(Ident::new("__private", span).into()); path.segments.push(private.clone().into());
path.segments.push(Ident::new("de", span).into()); path.segments.push(Ident::new("de", span).into());
path.segments path.segments
.push(Ident::new("borrow_cow_bytes", span).into()); .push(Ident::new("borrow_cow_bytes", span).into());
+22 -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.224")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.225")]
#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))] #![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
// Ignored clippy lints // Ignored clippy lints
#![allow( #![allow(
@@ -75,6 +75,8 @@ extern crate proc_macro;
mod internals; mod internals;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro2::{Ident, Span};
use quote::{ToTokens, TokenStreamExt as _};
use syn::parse_macro_input; use syn::parse_macro_input;
use syn::DeriveInput; use syn::DeriveInput;
@@ -84,11 +86,30 @@ mod bound;
mod fragment; mod fragment;
mod de; mod de;
mod deprecated;
mod dummy; mod dummy;
mod pretend; mod pretend;
mod ser; mod ser;
mod this; mod this;
#[allow(non_camel_case_types)]
struct private;
impl private {
fn ident(&self) -> Ident {
Ident::new(
concat!("__private", env!("CARGO_PKG_VERSION_PATCH")),
Span::call_site(),
)
}
}
impl ToTokens for private {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
tokens.append(self.ident());
}
}
#[proc_macro_derive(Serialize, attributes(serde))] #[proc_macro_derive(Serialize, attributes(serde))]
pub fn derive_serialize(input: TokenStream) -> TokenStream { pub fn derive_serialize(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput); let mut input = parse_macro_input!(input as DeriveInput);
+12 -9
View File
@@ -1,4 +1,5 @@
use crate::internals::ast::{Container, Data, Field, Style, Variant}; use crate::internals::ast::{Container, Data, Field, Style, Variant};
use crate::private;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote}; use quote::{format_ident, quote};
@@ -83,8 +84,8 @@ fn pretend_fields_used_struct(cont: &Container, fields: &[Field]) -> TokenStream
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i)); let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
quote! { quote! {
match _serde::__private::None::<&#type_ident #ty_generics> { match _serde::#private::None::<&#type_ident #ty_generics> {
_serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {} _serde::#private::Some(#type_ident { #(#members: #placeholders),* }) => {}
_ => {} _ => {}
} }
} }
@@ -96,11 +97,12 @@ fn pretend_fields_used_struct_packed(cont: &Container, fields: &[Field]) -> Toke
let members = fields.iter().map(|field| &field.member).collect::<Vec<_>>(); let members = fields.iter().map(|field| &field.member).collect::<Vec<_>>();
let private2 = private;
quote! { quote! {
match _serde::__private::None::<&#type_ident #ty_generics> { match _serde::#private::None::<&#type_ident #ty_generics> {
_serde::__private::Some(__v @ #type_ident { #(#members: _),* }) => { _serde::#private::Some(__v @ #type_ident { #(#members: _),* }) => {
#( #(
let _ = _serde::__private::ptr::addr_of!(__v.#members); let _ = _serde::#private2::ptr::addr_of!(__v.#members);
)* )*
} }
_ => {} _ => {}
@@ -125,10 +127,11 @@ fn pretend_fields_used_enum(cont: &Container, variants: &[Variant]) -> TokenStre
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let private2 = private;
quote! { quote! {
match _serde::__private::None::<&#type_ident #ty_generics> { match _serde::#private::None::<&#type_ident #ty_generics> {
#( #(
_serde::__private::Some(#patterns) => {} _serde::#private2::Some(#patterns) => {}
)* )*
_ => {} _ => {}
} }
@@ -172,8 +175,8 @@ fn pretend_variants_used(cont: &Container) -> TokenStream {
}; };
quote! { quote! {
match _serde::__private::None { match _serde::#private::None {
_serde::__private::Some((#(#placeholders,)*)) => { _serde::#private::Some((#(#placeholders,)*)) => {
let _ = #type_ident::#variant_ident #turbofish #pat; let _ = #type_ident::#variant_ident #turbofish #pat;
} }
_ => {} _ => {}
+33 -30
View File
@@ -1,8 +1,9 @@
use crate::deprecated::allow_deprecated;
use crate::fragment::{Fragment, Match, Stmts}; use crate::fragment::{Fragment, Match, Stmts};
use crate::internals::ast::{Container, Data, Field, Style, Variant}; use crate::internals::ast::{Container, Data, Field, Style, Variant};
use crate::internals::name::Name; use crate::internals::name::Name;
use crate::internals::{attr, replace_receiver, Ctxt, Derive}; use crate::internals::{attr, replace_receiver, Ctxt, Derive};
use crate::{bound, dummy, pretend, this}; use crate::{bound, dummy, pretend, private, this};
use proc_macro2::{Span, TokenStream}; use proc_macro2::{Span, TokenStream};
use quote::{quote, quote_spanned}; use quote::{quote, quote_spanned};
use syn::spanned::Spanned; use syn::spanned::Spanned;
@@ -12,7 +13,7 @@ pub fn expand_derive_serialize(input: &mut syn::DeriveInput) -> syn::Result<Toke
replace_receiver(input); replace_receiver(input);
let ctxt = Ctxt::new(); let ctxt = Ctxt::new();
let cont = match Container::from_ast(&ctxt, input, Derive::Serialize) { let cont = match Container::from_ast(&ctxt, input, Derive::Serialize, &private.ident()) {
Some(cont) => cont, Some(cont) => cont,
None => return Err(ctxt.check().unwrap_err()), None => return Err(ctxt.check().unwrap_err()),
}; };
@@ -23,17 +24,18 @@ pub fn expand_derive_serialize(input: &mut syn::DeriveInput) -> syn::Result<Toke
let params = Parameters::new(&cont); let params = Parameters::new(&cont);
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl(); let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
let body = Stmts(serialize_body(&cont, &params)); let body = Stmts(serialize_body(&cont, &params));
let serde = cont.attrs.serde_path(); let allow_deprecated = allow_deprecated(input);
let impl_block = if let Some(remote) = cont.attrs.remote() { let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis; let vis = &input.vis;
let used = pretend::pretend_used(&cont, params.is_packed); let used = pretend::pretend_used(&cont, params.is_packed);
quote! { quote! {
#[automatically_derived] #[automatically_derived]
#allow_deprecated
impl #impl_generics #ident #ty_generics #where_clause { impl #impl_generics #ident #ty_generics #where_clause {
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error> #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::#private::Result<__S::Ok, __S::Error>
where where
__S: #serde::Serializer, __S: _serde::Serializer,
{ {
#used #used
#body #body
@@ -43,10 +45,11 @@ pub fn expand_derive_serialize(input: &mut syn::DeriveInput) -> syn::Result<Toke
} else { } else {
quote! { quote! {
#[automatically_derived] #[automatically_derived]
impl #impl_generics #serde::Serialize for #ident #ty_generics #where_clause { #allow_deprecated
fn serialize<__S>(&self, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error> impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::#private::Result<__S::Ok, __S::Error>
where where
__S: #serde::Serializer, __S: _serde::Serializer,
{ {
#body #body
} }
@@ -212,7 +215,7 @@ fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment {
let self_var = &params.self_var; let self_var = &params.self_var;
quote_block! { quote_block! {
_serde::Serialize::serialize( _serde::Serialize::serialize(
&_serde::__private::Into::<#type_into>::into(_serde::__private::Clone::clone(#self_var)), &_serde::#private::Into::<#type_into>::into(_serde::#private::Clone::clone(#self_var)),
__serializer) __serializer)
} }
} }
@@ -382,7 +385,7 @@ fn serialize_struct_as_map(
let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists); let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);
quote_block! { quote_block! {
let #let_mut __serde_state = _serde::Serializer::serialize_map(__serializer, _serde::__private::None)?; let #let_mut __serde_state = _serde::Serializer::serialize_map(__serializer, _serde::#private::None)?;
#tag_field #tag_field
#(#serialize_fields)* #(#serialize_fields)*
_serde::ser::SerializeMap::end(__serde_state) _serde::ser::SerializeMap::end(__serde_state)
@@ -404,7 +407,7 @@ fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Cont
if cattrs.remote().is_some() && cattrs.non_exhaustive() { if cattrs.remote().is_some() && cattrs.non_exhaustive() {
arms.push(quote! { arms.push(quote! {
ref unrecognized => _serde::__private::Err(_serde::ser::Error::custom(_serde::__private::ser::CannotSerializeVariant(unrecognized))), ref unrecognized => _serde::#private::Err(_serde::ser::Error::custom(_serde::#private::ser::CannotSerializeVariant(unrecognized))),
}); });
} }
@@ -431,7 +434,7 @@ fn serialize_variant(
variant_ident variant_ident
); );
let skipped_err = quote! { let skipped_err = quote! {
_serde::__private::Err(_serde::ser::Error::custom(#skipped_msg)) _serde::#private::Err(_serde::ser::Error::custom(#skipped_msg))
}; };
let fields_pat = match variant.style { let fields_pat = match variant.style {
Style::Unit => quote!(), Style::Unit => quote!(),
@@ -585,7 +588,7 @@ fn serialize_internally_tagged_variant(
if let Some(path) = variant.attrs.serialize_with() { if let Some(path) = variant.attrs.serialize_with() {
let ser = wrap_serialize_variant_with(params, path, variant); let ser = wrap_serialize_variant_with(params, path, variant);
return quote_expr! { return quote_expr! {
_serde::__private::ser::serialize_tagged_newtype( _serde::#private::ser::serialize_tagged_newtype(
__serializer, __serializer,
#enum_ident_str, #enum_ident_str,
#variant_ident_str, #variant_ident_str,
@@ -614,7 +617,7 @@ fn serialize_internally_tagged_variant(
} }
let span = field.original.span(); let span = field.original.span();
let func = quote_spanned!(span=> _serde::__private::ser::serialize_tagged_newtype); let func = quote_spanned!(span=> _serde::#private::ser::serialize_tagged_newtype);
quote_expr! { quote_expr! {
#func( #func(
__serializer, __serializer,
@@ -648,7 +651,7 @@ fn serialize_adjacently_tagged_variant(
let type_name = cattrs.name().serialize_name(); let type_name = cattrs.name().serialize_name();
let variant_name = variant.attrs.name().serialize_name(); let variant_name = variant.attrs.name().serialize_name();
let serialize_variant = quote! { let serialize_variant = quote! {
&_serde::__private::ser::AdjacentlyTaggedEnumVariant { &_serde::#private::ser::AdjacentlyTaggedEnumVariant {
enum_name: #type_name, enum_name: #type_name,
variant_index: #variant_index, variant_index: #variant_index,
variant_name: #variant_name, variant_name: #variant_name,
@@ -731,12 +734,12 @@ fn serialize_adjacently_tagged_variant(
#[doc(hidden)] #[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>,
} }
#[automatically_derived] #[automatically_derived]
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause { impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error> fn serialize<__S>(&self, __serializer: __S) -> _serde::#private::Result<__S::Ok, __S::Error>
where where
__S: _serde::Serializer, __S: _serde::Serializer,
{ {
@@ -754,7 +757,7 @@ fn serialize_adjacently_tagged_variant(
_serde::ser::SerializeStruct::serialize_field( _serde::ser::SerializeStruct::serialize_field(
&mut __struct, #content, &__AdjacentlyTagged { &mut __struct, #content, &__AdjacentlyTagged {
data: (#(#fields_ident,)*), data: (#(#fields_ident,)*),
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>, phantom: _serde::#private::PhantomData::<#this_type #ty_generics>,
})?; })?;
_serde::ser::SerializeStruct::end(__struct) _serde::ser::SerializeStruct::end(__struct)
} }
@@ -996,19 +999,19 @@ fn serialize_struct_variant_with_flatten(
#[doc(hidden)] #[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>,
} }
#[automatically_derived] #[automatically_derived]
impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause { impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error> fn serialize<__S>(&self, __serializer: __S) -> _serde::#private::Result<__S::Ok, __S::Error>
where where
__S: _serde::Serializer, __S: _serde::Serializer,
{ {
let (#(#members,)*) = self.data; let (#(#members,)*) = self.data;
let #let_mut __serde_state = _serde::Serializer::serialize_map( let #let_mut __serde_state = _serde::Serializer::serialize_map(
__serializer, __serializer,
_serde::__private::None)?; _serde::#private::None)?;
#(#serialize_fields)* #(#serialize_fields)*
_serde::ser::SerializeMap::end(__serde_state) _serde::ser::SerializeMap::end(__serde_state)
} }
@@ -1021,7 +1024,7 @@ fn serialize_struct_variant_with_flatten(
#variant_name, #variant_name,
&__EnumFlatten { &__EnumFlatten {
data: (#(#members,)*), data: (#(#members,)*),
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>, phantom: _serde::#private::PhantomData::<#this_type #ty_generics>,
}) })
} }
} }
@@ -1029,7 +1032,7 @@ fn serialize_struct_variant_with_flatten(
quote_block! { quote_block! {
let #let_mut __serde_state = _serde::Serializer::serialize_map( let #let_mut __serde_state = _serde::Serializer::serialize_map(
__serializer, __serializer,
_serde::__private::None)?; _serde::#private::None)?;
_serde::ser::SerializeMap::serialize_entry( _serde::ser::SerializeMap::serialize_entry(
&mut __serde_state, &mut __serde_state,
#tag, #tag,
@@ -1043,7 +1046,7 @@ fn serialize_struct_variant_with_flatten(
quote_block! { quote_block! {
let #let_mut __serde_state = _serde::Serializer::serialize_map( let #let_mut __serde_state = _serde::Serializer::serialize_map(
__serializer, __serializer,
_serde::__private::None)?; _serde::#private::None)?;
#(#serialize_fields)* #(#serialize_fields)*
_serde::ser::SerializeMap::end(__serde_state) _serde::ser::SerializeMap::end(__serde_state)
} }
@@ -1132,7 +1135,7 @@ fn serialize_struct_visitor(
let ser = if field.attrs.flatten() { let ser = if field.attrs.flatten() {
let func = quote_spanned!(span=> _serde::Serialize::serialize); let func = quote_spanned!(span=> _serde::Serialize::serialize);
quote! { quote! {
#func(&#field_expr, _serde::__private::ser::FlatMapSerializer(&mut __serde_state))?; #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);
@@ -1239,12 +1242,12 @@ fn wrap_serialize_with(
#[doc(hidden)] #[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>,
} }
#[automatically_derived] #[automatically_derived]
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause { impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
fn serialize<__S>(&#self_var, #serializer_var: __S) -> _serde::__private::Result<__S::Ok, __S::Error> fn serialize<__S>(&#self_var, #serializer_var: __S) -> _serde::#private::Result<__S::Ok, __S::Error>
where where
__S: _serde::Serializer, __S: _serde::Serializer,
{ {
@@ -1254,7 +1257,7 @@ fn wrap_serialize_with(
__SerializeWith { __SerializeWith {
values: (#(#field_exprs, )*), values: (#(#field_exprs, )*),
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>, phantom: _serde::#private::PhantomData::<#this_type #ty_generics>,
} }
}) })
} }
@@ -1290,11 +1293,11 @@ fn get_member(params: &Parameters, field: &Field, member: &Member) -> TokenStrea
quote!(&#self_var.#member) quote!(&#self_var.#member)
}; };
let ty = field.ty; let ty = field.ty;
quote!(_serde::__private::ser::constrain::<#ty>(#inner)) quote!(_serde::#private::ser::constrain::<#ty>(#inner))
} }
(true, Some(getter)) => { (true, Some(getter)) => {
let ty = field.ty; let ty = field.ty;
quote!(_serde::__private::ser::constrain::<#ty>(&#getter(#self_var))) quote!(_serde::#private::ser::constrain::<#ty>(&#getter(#self_var)))
} }
(false, Some(_)) => { (false, Some(_)) => {
unreachable!("getter is only allowed for remote impls"); unreachable!("getter is only allowed for remote impls");
+30
View File
@@ -0,0 +1,30 @@
#![deny(deprecated)]
#![allow(dead_code)]
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
#[deprecated]
enum DeprecatedEnum {
A,
B,
}
#[derive(Serialize, Deserialize)]
#[deprecated]
struct DeprecatedStruct {
a: bool,
}
#[derive(Serialize, Deserialize)]
enum DeprecatedVariant {
A,
#[deprecated]
B,
}
#[derive(Serialize, Deserialize)]
struct DeprecatedField {
#[deprecated]
a: bool,
}
@@ -0,0 +1,20 @@
#![deny(deprecated)]
use serde::Deserializer;
use serde_derive::Deserialize;
#[derive(Deserialize)]
pub struct Struct {
#[serde(deserialize_with = "deprecated_with")]
pub field: i32,
}
#[deprecated]
fn deprecated_with<'de, D>(_deserializer: D) -> Result<i32, D::Error>
where
D: Deserializer<'de>,
{
unimplemented!()
}
fn main() {}
@@ -0,0 +1,11 @@
error: use of deprecated function `deprecated_with`
--> tests/ui/deprecated/deprecated_de_with.rs:8:32
|
8 | #[serde(deserialize_with = "deprecated_with")]
| ^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/ui/deprecated/deprecated_de_with.rs:1:9
|
1 | #![deny(deprecated)]
| ^^^^^^^^^^
@@ -0,0 +1,20 @@
#![deny(deprecated)]
use serde::Serializer;
use serde_derive::Serialize;
#[derive(Serialize)]
pub struct Struct {
#[serde(serialize_with = "deprecated_with")]
pub field: i32,
}
#[deprecated]
fn deprecated_with<S>(_field: &i32, _serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
unimplemented!()
}
fn main() {}
@@ -0,0 +1,11 @@
error: use of deprecated function `deprecated_with`
--> tests/ui/deprecated/deprecated_ser_with.rs:8:30
|
8 | #[serde(serialize_with = "deprecated_with")]
| ^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/ui/deprecated/deprecated_ser_with.rs:1:9
|
1 | #![deny(deprecated)]
| ^^^^^^^^^^