Merge pull request #1140 from serde-rs/hygiene

Hygiene fixes
This commit is contained in:
David Tolnay 2018-01-09 22:39:23 -08:00 committed by GitHub
commit 5c41661bce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 76 additions and 29 deletions

View File

@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use syn::{self, Ident, Member};
use syn::{self, Ident, Index, Member};
use syn::punctuated::Punctuated;
use quote::{ToTokens, Tokens};
use proc_macro2::{Literal, Span, Term};
@ -32,9 +32,10 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis;
let fun = quote_spanned!(Span::call_site()=> deserialize);
quote! {
impl #de_impl_generics #ident #ty_generics #where_clause {
#vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
#vis fn #fun<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
where __D: _serde::Deserializer<#delife>
{
#body
@ -562,14 +563,16 @@ fn deserialize_seq(
}
});
// FIXME: parentheses around field values are because of
// https://github.com/rust-lang/rust/issues/47311
let mut result = if is_struct {
let names = fields.iter().map(|f| &f.ident);
quote! {
#type_path { #( #names: #vars ),* }
quote_spanned! {Span::call_site()=>
#type_path { #( #names: (#vars) ),* }
}
} else {
quote! {
#type_path ( #(#vars),* )
quote_spanned! {Span::call_site()=>
#type_path ( #((#vars)),* )
}
};
@ -624,12 +627,16 @@ fn deserialize_seq_in_place(
let field_name = field
.ident
.map(Member::Named)
.unwrap_or_else(|| Member::Unnamed(field_index.into()));
.unwrap_or_else(|| Member::Unnamed(Index {
index: field_index as u32,
span: Span::call_site(),
}));
let dot = quote_spanned!(Span::call_site()=> .);
if field.attrs.skip_deserializing() {
let default = Expr(expr_is_missing(field, cattrs));
quote! {
self.place.#field_name = #default;
self.place #dot #field_name = #default;
}
} else {
let return_invalid_length = quote! {
@ -639,7 +646,7 @@ fn deserialize_seq_in_place(
None => {
quote! {
if let _serde::export::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
_serde::private::de::InPlaceSeed(&mut self.place.#field_name)))
_serde::private::de::InPlaceSeed(&mut self.place #dot #field_name)))
{
#return_invalid_length
}
@ -652,7 +659,7 @@ fn deserialize_seq_in_place(
#wrapper
match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
_serde::export::Some(__wrap) => {
self.place.#field_name = __wrap.value;
self.place #dot #field_name = __wrap.value;
}
_serde::export::None => {
#return_invalid_length
@ -708,7 +715,9 @@ fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &F
}
};
let mut result = quote!(#type_path(#value));
// FIXME: parentheses around field values are because of
// https://github.com/rust-lang/rust/issues/47311
let mut result = quote_spanned!(Span::call_site()=> #type_path((#value)));
if params.has_getter {
let this = &params.this;
result = quote! {
@ -733,12 +742,13 @@ fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> To
let delife = params.borrowed.de_lifetime();
let elem = quote_spanned!(Span::call_site()=> .0);
quote! {
#[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
where __E: _serde::Deserializer<#delife>
{
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
_serde::Deserialize::deserialize_in_place(__e, &mut self.place #elem)
}
}
}
@ -2039,13 +2049,15 @@ fn deserialize_map(
}
});
// FIXME: parentheses around field values are because of
// https://github.com/rust-lang/rust/issues/47311
let result = fields_names.iter().map(|&(field, ref name)| {
let ident = field.ident.expect("struct contains unnamed fields");
if field.attrs.skip_deserializing() {
let value = Expr(expr_is_missing(field, cattrs));
quote!(#ident: #value)
quote_spanned!(Span::call_site()=> #ident: (#value))
} else {
quote!(#ident: #name)
quote_spanned!(Span::call_site()=> #ident: (#name))
}
});
@ -2063,7 +2075,7 @@ fn deserialize_map(
}
};
let mut result = quote!(#struct_path { #(#result),* });
let mut result = quote_spanned!(Span::call_site()=> #struct_path { #(#result),* });
if params.has_getter {
let this = &params.this;
result = quote! {
@ -2314,7 +2326,10 @@ fn wrap_deserialize_variant_with(
let (wrapper, wrapper_ty) =
wrap_deserialize_with(params, &quote!((#(#field_tys),*)), deserialize_with);
let field_access = (0..variant.fields.len()).map(|n| Member::Unnamed(n.into()));
let field_access = (0..variant.fields.len()).map(|n| Member::Unnamed(Index {
index: n as u32,
span: Span::call_site(),
}));
let unwrap_fn = match variant.style {
Style::Struct => {
let field_idents = variant

View File

@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use syn::{self, Ident, Member};
use syn::{self, Ident, Index, Member};
use quote::Tokens;
use proc_macro2::Span;
@ -31,9 +31,10 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis;
let fun = quote_spanned!(Span::call_site()=> serialize);
quote! {
impl #impl_generics #ident #ty_generics #where_clause {
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
#vis fn #fun<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer
{
#body
@ -202,7 +203,10 @@ fn serialize_newtype_struct(
) -> Fragment {
let type_name = cattrs.name().serialize_name();
let mut field_expr = get_member(params, field, &Member::Unnamed(0.into()));
let mut field_expr = get_member(params, field, &Member::Unnamed(Index {
index: 0,
span: Span::call_site(),
}));
if let Some(path) = field.attrs.serialize_with() {
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
}
@ -817,7 +821,10 @@ fn serialize_tuple_struct_visitor(
let id = Ident::new(&format!("__field{}", i), Span::def_site());
quote!(#id)
} else {
get_member(params, field, &Member::Unnamed(i.into()))
get_member(params, field, &Member::Unnamed(Index {
index: i as u32,
span: Span::call_site(),
}))
};
let skip = field
@ -940,7 +947,10 @@ fn wrap_serialize_with(
};
let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
let field_access = (0..field_exprs.len()).map(|n| Member::Unnamed(n.into()));
let field_access = (0..field_exprs.len()).map(|n| Member::Unnamed(Index {
index: n as u32,
span: Span::call_site(),
}));
quote!({
struct __SerializeWith #wrapper_impl_generics #where_clause {
@ -981,11 +991,12 @@ fn get_member(params: &Parameters, field: &Field, member: &Member) -> Tokens {
let self_var = &params.self_var;
match (params.is_remote, field.attrs.getter()) {
(false, None) => {
quote!(&#self_var.#member)
quote_spanned!(Span::call_site()=> &#self_var.#member)
}
(true, None) => {
let inner = quote_spanned!(Span::call_site()=> &#self_var.#member);
let ty = field.ty;
quote!(_serde::private::ser::constrain::<#ty>(&#self_var.#member))
quote!(_serde::private::ser::constrain::<#ty>(#inner))
}
(true, Some(getter)) => {
let ty = field.ty;

View File

@ -12,6 +12,7 @@ readme = "README.md"
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[dependencies]
proc-macro2 = "0.2"
syn = { version = "0.12", default-features = false, features = ["derive", "parsing", "clone-impls"] }
[badges]

View File

@ -8,12 +8,14 @@
use Ctxt;
use syn;
use syn::Ident;
use syn::Meta::{List, NameValue, Word};
use syn::NestedMeta::{Literal, Meta};
use syn::punctuated::Punctuated;
use syn::synom::Synom;
use std::collections::BTreeSet;
use std::str::FromStr;
use proc_macro2::Span;
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
// are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
@ -577,10 +579,10 @@ impl Variant {
Meta(NameValue(ref m)) if m.ident == "with" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
let mut ser_path = path.clone();
ser_path.segments.push("serialize".into());
ser_path.segments.push(Ident::new("serialize", Span::call_site()).into());
serialize_with.set(ser_path);
let mut de_path = path;
de_path.segments.push("deserialize".into());
de_path.segments.push(Ident::new("deserialize", Span::call_site()).into());
deserialize_with.set(de_path);
}
}
@ -819,10 +821,10 @@ impl Field {
Meta(NameValue(ref m)) if m.ident == "with" => {
if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
let mut ser_path = path.clone();
ser_path.segments.push("serialize".into());
ser_path.segments.push(Ident::new("serialize", Span::call_site()).into());
serialize_with.set(ser_path);
let mut de_path = path;
de_path.segments.push("deserialize".into());
de_path.segments.push(Ident::new("deserialize", Span::call_site()).into());
deserialize_with.set(de_path);
}
}
@ -911,10 +913,24 @@ impl Field {
// impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str>
// impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]>
if is_cow(&field.ty, is_str) {
let path = syn::parse_str("_serde::private::de::borrow_cow_str").unwrap();
let mut path = syn::Path {
leading_colon: None,
segments: Punctuated::new(),
};
path.segments.push(Ident::new("_serde", Span::def_site()).into());
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);
} else if is_cow(&field.ty, is_slice_u8) {
let path = syn::parse_str("_serde::private::de::borrow_cow_bytes").unwrap();
let mut path = syn::Path {
leading_colon: None,
segments: Punctuated::new(),
};
path.segments.push(Ident::new("_serde", Span::def_site()).into());
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);
}
} else if is_rptr(&field.ty, is_str) || is_rptr(&field.ty, is_slice_u8) {

View File

@ -12,6 +12,8 @@
#[macro_use]
extern crate syn;
extern crate proc_macro2;
pub mod ast;
pub mod attr;

View File

@ -9,6 +9,7 @@ unstable = ["serde/unstable", "compiletest_rs"]
[dev-dependencies]
fnv = "1.0"
proc-macro2 = "0.2"
rustc-serialize = "0.3.16"
serde = { path = "../serde", features = ["rc"] }
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }

View File

@ -55,6 +55,7 @@ else
channel build
cd "$DIR/test_suite"
channel test --features unstable
channel build --tests --features proc-macro2/nightly
if [ -z "${APPVEYOR}" ]; then
cd "$DIR/test_suite/no_std"
channel build