Compare commits

...

6 Commits

Author SHA1 Message Date
David Tolnay 7ad836e6a9 Release 1.0.33 2018-03-15 10:03:42 -07:00
David Tolnay 72ecb9064c Fix parsing of qself in paths in attributes 2018-03-15 10:02:40 -07:00
David Tolnay 23c6eb3b40 Release 1.0.32 2018-03-13 11:31:26 -07:00
David Tolnay b8c9a66d75 Release 1.0.31 2018-03-13 10:18:35 -07:00
David Tolnay 56b2e39dda Fix panic when a reference has unspecified lifetime
This will fail later in compilation anyway, but serde_derive needs to
not crash before then.

    #[derive(Deserialize)]
    struct A {
        field: &str,
    }

    error[E0106]: missing lifetime specifier
      --> src/main.rs
       |
       |     field: &str,
       |            ^ expected lifetime parameter
2018-03-13 09:56:38 -07:00
David Tolnay 5bc805329e Drop impl should only panic if not already panicking 2018-03-13 09:42:07 -07:00
13 changed files with 69 additions and 46 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.30" # remember to update html_root_url
version = "1.0.33" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
+1 -1
View File
@@ -79,7 +79,7 @@
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.30")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.33")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.30" # remember to update html_root_url
version = "1.0.33" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -25,7 +25,7 @@ proc-macro = true
[dependencies]
proc-macro2 = "0.2"
quote = "0.4"
serde_derive_internals = { version = "=0.20.0", default-features = false, path = "../serde_derive_internals" }
serde_derive_internals = { version = "=0.21.0", default-features = false, path = "../serde_derive_internals" }
syn = { version = "0.12", features = ["visit"] }
[dev-dependencies]
+3 -3
View File
@@ -2273,7 +2273,7 @@ fn field_i(i: usize) -> Ident {
fn wrap_deserialize_with(
params: &Parameters,
value_ty: &Tokens,
deserialize_with: &syn::Path,
deserialize_with: &syn::ExprPath,
) -> (Tokens, Tokens) {
let this = &params.this;
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
@@ -2308,7 +2308,7 @@ fn wrap_deserialize_with(
fn wrap_deserialize_field_with(
params: &Parameters,
field_ty: &syn::Type,
deserialize_with: &syn::Path,
deserialize_with: &syn::ExprPath,
) -> (Tokens, Tokens) {
wrap_deserialize_with(params, &quote!(#field_ty), deserialize_with)
}
@@ -2316,7 +2316,7 @@ fn wrap_deserialize_field_with(
fn wrap_deserialize_variant_with(
params: &Parameters,
variant: &Variant,
deserialize_with: &syn::Path,
deserialize_with: &syn::ExprPath,
) -> (Tokens, Tokens, Tokens) {
let this = &params.this;
let variant_ident = &variant.ident;
+1 -1
View File
@@ -22,7 +22,7 @@
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.30")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.33")]
#![cfg_attr(feature = "cargo-clippy", allow(enum_variant_names, redundant_field_names,
too_many_arguments, used_underscore_binding))]
// The `quote!` macro requires deep recursion.
+3 -3
View File
@@ -902,7 +902,7 @@ fn serialize_struct_visitor(
fn wrap_serialize_field_with(
params: &Parameters,
field_ty: &syn::Type,
serialize_with: &syn::Path,
serialize_with: &syn::ExprPath,
field_expr: &Tokens,
) -> Tokens {
wrap_serialize_with(params, serialize_with, &[field_ty], &[quote!(#field_expr)])
@@ -910,7 +910,7 @@ fn wrap_serialize_field_with(
fn wrap_serialize_variant_with(
params: &Parameters,
serialize_with: &syn::Path,
serialize_with: &syn::ExprPath,
variant: &Variant,
) -> Tokens {
let field_tys: Vec<_> = variant.fields.iter().map(|field| field.ty).collect();
@@ -935,7 +935,7 @@ fn wrap_serialize_variant_with(
fn wrap_serialize_with(
params: &Parameters,
serialize_with: &syn::Path,
serialize_with: &syn::ExprPath,
field_tys: &[&syn::Type],
field_exprs: &[Tokens],
) -> Tokens {
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive_internals"
version = "0.20.0" # remember to update html_root_url
version = "0.21.0" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "AST representation used by Serde derive macros. Unstable."
+45 -30
View File
@@ -243,7 +243,7 @@ impl Container {
// Parse `#[serde(default = "...")]`
Meta(NameValue(ref m)) if m.ident == "default" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
match item.data {
syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Named(_), .. }) => {
default.set(Default::Path(path));
@@ -510,8 +510,8 @@ pub struct Variant {
skip_deserializing: bool,
skip_serializing: bool,
other: bool,
serialize_with: Option<syn::Path>,
deserialize_with: Option<syn::Path>,
serialize_with: Option<syn::ExprPath>,
deserialize_with: Option<syn::ExprPath>,
borrow: Option<syn::Meta>,
}
@@ -577,26 +577,26 @@ impl Variant {
// Parse `#[serde(with = "...")]`
Meta(NameValue(ref m)) if m.ident == "with" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
let mut ser_path = path.clone();
ser_path.segments.push(Ident::new("serialize", Span::call_site()).into());
ser_path.path.segments.push(Ident::new("serialize", Span::call_site()).into());
serialize_with.set(ser_path);
let mut de_path = path;
de_path.segments.push(Ident::new("deserialize", Span::call_site()).into());
de_path.path.segments.push(Ident::new("deserialize", Span::call_site()).into());
deserialize_with.set(de_path);
}
}
// Parse `#[serde(serialize_with = "...")]`
Meta(NameValue(ref m)) if m.ident == "serialize_with" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
serialize_with.set(path);
}
}
// Parse `#[serde(deserialize_with = "...")]`
Meta(NameValue(ref m)) if m.ident == "deserialize_with" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
deserialize_with.set(path);
}
}
@@ -675,11 +675,11 @@ impl Variant {
self.other
}
pub fn serialize_with(&self) -> Option<&syn::Path> {
pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
self.serialize_with.as_ref()
}
pub fn deserialize_with(&self) -> Option<&syn::Path> {
pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
self.deserialize_with.as_ref()
}
}
@@ -691,14 +691,14 @@ pub struct Field {
de_renamed: bool,
skip_serializing: bool,
skip_deserializing: bool,
skip_serializing_if: Option<syn::Path>,
skip_serializing_if: Option<syn::ExprPath>,
default: Default,
serialize_with: Option<syn::Path>,
deserialize_with: Option<syn::Path>,
serialize_with: Option<syn::ExprPath>,
deserialize_with: Option<syn::ExprPath>,
ser_bound: Option<Vec<syn::WherePredicate>>,
de_bound: Option<Vec<syn::WherePredicate>>,
borrowed_lifetimes: BTreeSet<syn::Lifetime>,
getter: Option<syn::Path>,
getter: Option<syn::ExprPath>,
}
/// Represents the default to use for a field when deserializing.
@@ -708,7 +708,7 @@ pub enum Default {
/// The default is given by `std::default::Default::default()`.
Default,
/// The default is given by this function.
Path(syn::Path),
Path(syn::ExprPath),
}
impl Field {
@@ -775,7 +775,7 @@ impl Field {
// Parse `#[serde(default = "...")]`
Meta(NameValue(ref m)) if m.ident == "default" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
default.set(Default::Path(path));
}
}
@@ -798,33 +798,33 @@ impl Field {
// Parse `#[serde(skip_serializing_if = "...")]`
Meta(NameValue(ref m)) if m.ident == "skip_serializing_if" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
skip_serializing_if.set(path);
}
}
// Parse `#[serde(serialize_with = "...")]`
Meta(NameValue(ref m)) if m.ident == "serialize_with" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
serialize_with.set(path);
}
}
// Parse `#[serde(deserialize_with = "...")]`
Meta(NameValue(ref m)) if m.ident == "deserialize_with" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
deserialize_with.set(path);
}
}
// Parse `#[serde(with = "...")]`
Meta(NameValue(ref m)) if m.ident == "with" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
let mut ser_path = path.clone();
ser_path.segments.push(Ident::new("serialize", Span::call_site()).into());
ser_path.path.segments.push(Ident::new("serialize", Span::call_site()).into());
serialize_with.set(ser_path);
let mut de_path = path;
de_path.segments.push(Ident::new("deserialize", Span::call_site()).into());
de_path.path.segments.push(Ident::new("deserialize", Span::call_site()).into());
deserialize_with.set(de_path);
}
}
@@ -873,7 +873,7 @@ impl Field {
// Parse `#[serde(getter = "...")]`
Meta(NameValue(ref m)) if m.ident == "getter" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
getter.set(path);
}
}
@@ -921,7 +921,12 @@ impl Field {
path.segments.push(Ident::new("private", Span::def_site()).into());
path.segments.push(Ident::new("de", Span::def_site()).into());
path.segments.push(Ident::new("borrow_cow_str", Span::def_site()).into());
deserialize_with.set_if_none(path);
let expr = syn::ExprPath {
attrs: Vec::new(),
qself: None,
path: path,
};
deserialize_with.set_if_none(expr);
} else if is_cow(&field.ty, is_slice_u8) {
let mut path = syn::Path {
leading_colon: None,
@@ -931,12 +936,17 @@ impl Field {
path.segments.push(Ident::new("private", Span::def_site()).into());
path.segments.push(Ident::new("de", Span::def_site()).into());
path.segments.push(Ident::new("borrow_cow_bytes", Span::def_site()).into());
deserialize_with.set_if_none(path);
let expr = syn::ExprPath {
attrs: Vec::new(),
qself: None,
path: path,
};
deserialize_with.set_if_none(expr);
}
} else if is_rptr(&field.ty, is_str) || is_rptr(&field.ty, is_slice_u8) {
// Types &str and &[u8] are always implicitly borrowed. No need for
// a #[serde(borrow)].
borrowed_lifetimes = borrowable_lifetimes(cx, &ident, &field.ty).unwrap();
collect_lifetimes(&field.ty, &mut borrowed_lifetimes);
}
let ser_name = ser_name.get();
@@ -984,7 +994,7 @@ impl Field {
self.skip_deserializing
}
pub fn skip_serializing_if(&self) -> Option<&syn::Path> {
pub fn skip_serializing_if(&self) -> Option<&syn::ExprPath> {
self.skip_serializing_if.as_ref()
}
@@ -992,11 +1002,11 @@ impl Field {
&self.default
}
pub fn serialize_with(&self) -> Option<&syn::Path> {
pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
self.serialize_with.as_ref()
}
pub fn deserialize_with(&self) -> Option<&syn::Path> {
pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
self.deserialize_with.as_ref()
}
@@ -1012,7 +1022,7 @@ impl Field {
&self.borrowed_lifetimes
}
pub fn getter(&self) -> Option<&syn::Path> {
pub fn getter(&self) -> Option<&syn::ExprPath> {
self.getter.as_ref()
}
}
@@ -1107,6 +1117,11 @@ fn parse_lit_into_path(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn
parse_lit_str(string).map_err(|_| cx.error(format!("failed to parse path: {:?}", string.value())))
}
fn parse_lit_into_expr_path(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::ExprPath, ()> {
let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
parse_lit_str(string).map_err(|_| cx.error(format!("failed to parse path: {:?}", string.value())))
}
fn parse_lit_into_where(
cx: &Ctxt,
attr_name: &str,
+2 -1
View File
@@ -8,6 +8,7 @@
use std::fmt::Display;
use std::cell::RefCell;
use std::thread;
#[derive(Default)]
pub struct Ctxt {
@@ -48,7 +49,7 @@ impl Ctxt {
impl Drop for Ctxt {
fn drop(&mut self) {
if self.errors.borrow().is_some() {
if !thread::panicking() && self.errors.borrow().is_some() {
panic!("forgot to check for errors");
}
}
+1 -1
View File
@@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.20.0")]
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.21.0")]
#![cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity, doc_markdown, match_same_arms,
redundant_field_names))]
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_test"
version = "1.0.30" # remember to update html_root_url
version = "1.0.33" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations"
+1 -1
View File
@@ -155,7 +155,7 @@
//! # }
//! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.30")]
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.33")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
+7
View File
@@ -528,6 +528,13 @@ fn test_gen() {
marker: PhantomData<T>,
}
assert::<TypeMacro<X>>();
#[derive(Serialize)]
struct BigArray {
#[serde(serialize_with = "<[_]>::serialize")]
array: [u8; 256],
}
assert_ser::<BigArray>();
}
//////////////////////////////////////////////////////////////////////////