Avoid generating ref patterns for fields of packed remote struct
This commit is contained in:
parent
14accf7518
commit
54102ee7d0
@ -36,7 +36,7 @@ pub fn expand_derive_deserialize(
|
|||||||
|
|
||||||
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);
|
let used = pretend::pretend_used(&cont, params.is_packed);
|
||||||
quote! {
|
quote! {
|
||||||
impl #de_impl_generics #ident #ty_generics #where_clause {
|
impl #de_impl_generics #ident #ty_generics #where_clause {
|
||||||
#vis fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result<#remote #ty_generics, __D::Error>
|
#vis fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result<#remote #ty_generics, __D::Error>
|
||||||
@ -125,6 +125,9 @@ struct Parameters {
|
|||||||
/// At least one field has a serde(getter) attribute, implying that the
|
/// At least one field has a serde(getter) attribute, implying that the
|
||||||
/// remote type has a private field.
|
/// remote type has a private field.
|
||||||
has_getter: bool,
|
has_getter: bool,
|
||||||
|
|
||||||
|
/// Type has a repr(packed) attribute.
|
||||||
|
is_packed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parameters {
|
impl Parameters {
|
||||||
@ -137,6 +140,7 @@ impl Parameters {
|
|||||||
let borrowed = borrowed_lifetimes(cont);
|
let borrowed = borrowed_lifetimes(cont);
|
||||||
let generics = build_generics(cont, &borrowed);
|
let generics = build_generics(cont, &borrowed);
|
||||||
let has_getter = cont.data.has_getter();
|
let has_getter = cont.data.has_getter();
|
||||||
|
let is_packed = cont.attrs.is_packed();
|
||||||
|
|
||||||
Parameters {
|
Parameters {
|
||||||
local,
|
local,
|
||||||
@ -144,6 +148,7 @@ impl Parameters {
|
|||||||
generics,
|
generics,
|
||||||
borrowed,
|
borrowed,
|
||||||
has_getter,
|
has_getter,
|
||||||
|
is_packed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ use internals::ast::{Container, Data, Field, Style};
|
|||||||
// 8 | enum EnumDef { V }
|
// 8 | enum EnumDef { V }
|
||||||
// | ^
|
// | ^
|
||||||
//
|
//
|
||||||
pub fn pretend_used(cont: &Container) -> TokenStream {
|
pub fn pretend_used(cont: &Container, is_packed: bool) -> TokenStream {
|
||||||
let pretend_fields = pretend_fields_used(cont);
|
let pretend_fields = pretend_fields_used(cont, is_packed);
|
||||||
let pretend_variants = pretend_variants_used(cont);
|
let pretend_variants = pretend_variants_used(cont);
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
@ -48,7 +48,7 @@ pub fn pretend_used(cont: &Container) -> TokenStream {
|
|||||||
// The `ref` is important in case the user has written a Drop impl on their
|
// The `ref` is important in case the user has written a Drop impl on their
|
||||||
// type. Rust does not allow destructuring a struct or enum that has a Drop
|
// type. Rust does not allow destructuring a struct or enum that has a Drop
|
||||||
// impl.
|
// impl.
|
||||||
fn pretend_fields_used(cont: &Container) -> TokenStream {
|
fn pretend_fields_used(cont: &Container, is_packed: bool) -> TokenStream {
|
||||||
let type_ident = &cont.ident;
|
let type_ident = &cont.ident;
|
||||||
let (_, ty_generics, _) = cont.generics.split_for_impl();
|
let (_, ty_generics, _) = cont.generics.split_for_impl();
|
||||||
|
|
||||||
@ -58,14 +58,14 @@ fn pretend_fields_used(cont: &Container) -> TokenStream {
|
|||||||
.filter_map(|variant| match variant.style {
|
.filter_map(|variant| match variant.style {
|
||||||
Style::Struct => {
|
Style::Struct => {
|
||||||
let variant_ident = &variant.ident;
|
let variant_ident = &variant.ident;
|
||||||
let pat = struct_pattern(&variant.fields);
|
let pat = struct_pattern(&variant.fields, is_packed);
|
||||||
Some(quote!(#type_ident::#variant_ident #pat))
|
Some(quote!(#type_ident::#variant_ident #pat))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
Data::Struct(Style::Struct, fields) => {
|
Data::Struct(Style::Struct, fields) => {
|
||||||
let pat = struct_pattern(fields);
|
let pat = struct_pattern(fields, is_packed);
|
||||||
vec![quote!(#type_ident #pat)]
|
vec![quote!(#type_ident #pat)]
|
||||||
}
|
}
|
||||||
Data::Struct(_, _) => {
|
Data::Struct(_, _) => {
|
||||||
@ -132,9 +132,14 @@ fn pretend_variants_used(cont: &Container) -> TokenStream {
|
|||||||
quote!(#(#cases)*)
|
quote!(#(#cases)*)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn struct_pattern(fields: &[Field]) -> TokenStream {
|
fn struct_pattern(fields: &[Field], is_packed: bool) -> TokenStream {
|
||||||
let members = fields.iter().map(|field| &field.member);
|
let members = fields.iter().map(|field| &field.member);
|
||||||
let placeholders =
|
let placeholders =
|
||||||
(0..fields.len()).map(|i| Ident::new(&format!("__v{}", i), Span::call_site()));
|
(0..fields.len()).map(|i| Ident::new(&format!("__v{}", i), Span::call_site()));
|
||||||
quote!({ #(#members: ref #placeholders),* })
|
let take_reference = if is_packed {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(quote!(ref))
|
||||||
|
};
|
||||||
|
quote!({ #(#members: #take_reference #placeholders),* })
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ pub fn expand_derive_serialize(
|
|||||||
|
|
||||||
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);
|
let used = pretend::pretend_used(&cont, params.is_packed);
|
||||||
quote! {
|
quote! {
|
||||||
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>
|
||||||
|
Loading…
Reference in New Issue
Block a user