Respect variant skip attribute in inferred bounds

This commit is contained in:
David Tolnay 2018-05-07 21:30:00 -07:00
parent 8c0efc3d77
commit c4181f46be
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
3 changed files with 26 additions and 10 deletions

View File

@ -191,13 +191,17 @@ fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generi
} }
} }
// Fields with a `skip_deserializing` or `deserialize_with` attribute are not // Fields with a `skip_deserializing` or `deserialize_with` attribute, or which
// deserialized by us so we do not generate a bound. Fields with a `bound` // belong to a variant with a `skip_deserializing` or `deserialize_with`
// attribute specify their own bound so we do not generate one. All other fields // attribute, are not deserialized by us so we do not generate a bound. Fields
// may need a `T: Deserialize` bound where T is the type of the field. // with a `bound` attribute specify their own bound so we do not generate one.
// All other fields may need a `T: Deserialize` bound where T is the type of the
// field.
fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool { fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
!field.skip_deserializing() && field.deserialize_with().is_none() && field.de_bound().is_none() !field.skip_deserializing() && field.deserialize_with().is_none() && field.de_bound().is_none()
&& variant.map_or(true, |variant| variant.deserialize_with().is_none()) && variant.map_or(true, |variant| {
!variant.skip_deserializing() && variant.deserialize_with().is_none()
})
} }
// Fields with a `default` attribute (not `default=...`), and fields with a // Fields with a `default` attribute (not `default=...`), and fields with a

View File

@ -150,13 +150,15 @@ fn build_generics(cont: &Container) -> syn::Generics {
} }
// Fields with a `skip_serializing` or `serialize_with` attribute, or which // Fields with a `skip_serializing` or `serialize_with` attribute, or which
// belong to a variant with a `serialize_with` attribute, are not serialized by // belong to a variant with a 'skip_serializing` or `serialize_with` attribute,
// us so we do not generate a bound. Fields with a `bound` attribute specify // are not serialized by us so we do not generate a bound. Fields with a `bound`
// their own bound so we do not generate one. All other fields may need a `T: // attribute specify their own bound so we do not generate one. All other fields
// Serialize` bound where T is the type of the field. // may need a `T: Serialize` bound where T is the type of the field.
fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool { fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
!field.skip_serializing() && field.serialize_with().is_none() && field.ser_bound().is_none() !field.skip_serializing() && field.serialize_with().is_none() && field.ser_bound().is_none()
&& variant.map_or(true, |variant| variant.serialize_with().is_none()) && variant.map_or(true, |variant| {
!variant.skip_serializing() && variant.serialize_with().is_none()
})
} }
fn serialize_body(cont: &Container, params: &Parameters) -> Fragment { fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {

View File

@ -592,6 +592,16 @@ fn test_gen() {
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(tag = "t", content = "c")] #[serde(tag = "t", content = "c")]
enum AdjacentlyTaggedVoid {} enum AdjacentlyTaggedVoid {}
#[derive(Serialize, Deserialize)]
enum SkippedVariant<T> {
#[serde(skip)]
#[allow(dead_code)]
T(T),
Unit,
}
assert::<SkippedVariant<X>>();
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////