From febacff1f553b68b21cbc8faf04c9209b5e1240f Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sat, 19 Oct 2024 19:11:35 +0000 Subject: [PATCH] Make compile error message point to field type instead of call site for not implemented Serialize trait --- serde_derive/src/ser.rs | 37 ++-- .../fn_param.rs} | 1 + .../fn_param.stderr} | 24 +-- .../tests/ui/on-unimplemented/struct_field.rs | 11 ++ .../ui/on-unimplemented/struct_field.stderr | 166 ++++++++++++++++++ .../ui/on-unimplemented/struct_variant.rs | 10 ++ .../ui/on-unimplemented/struct_variant.stderr | 108 ++++++++++++ .../tests/ui/on-unimplemented/tuple_field.rs | 8 + .../ui/on-unimplemented/tuple_field.stderr | 82 +++++++++ .../ui/on-unimplemented/tuple_variant.rs | 10 ++ .../ui/on-unimplemented/tuple_variant.stderr | 53 ++++++ 11 files changed, 486 insertions(+), 24 deletions(-) rename test_suite/tests/ui/{on_unimplemented.rs => on-unimplemented/fn_param.rs} (99%) rename test_suite/tests/ui/{on_unimplemented.stderr => on-unimplemented/fn_param.stderr} (79%) create mode 100644 test_suite/tests/ui/on-unimplemented/struct_field.rs create mode 100644 test_suite/tests/ui/on-unimplemented/struct_field.stderr create mode 100644 test_suite/tests/ui/on-unimplemented/struct_variant.rs create mode 100644 test_suite/tests/ui/on-unimplemented/struct_variant.stderr create mode 100644 test_suite/tests/ui/on-unimplemented/tuple_field.rs create mode 100644 test_suite/tests/ui/on-unimplemented/tuple_field.stderr create mode 100644 test_suite/tests/ui/on-unimplemented/tuple_variant.rs create mode 100644 test_suite/tests/ui/on-unimplemented/tuple_variant.stderr diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 35f8ca4bd..0e1a62488 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -311,7 +311,7 @@ fn serialize_struct_tag_field(cattrs: &attr::Container, struct_trait: &StructTra match cattrs.tag() { attr::TagType::Internal { tag } => { let type_name = cattrs.name().serialize_name(); - let func = struct_trait.serialize_field(Span::call_site()); + let func = struct_trait.serialize_field(None); quote! { #func(&mut __serde_state, #tag, #type_name)?; } @@ -1081,8 +1081,13 @@ fn serialize_tuple_struct_visitor( field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); } - let span = field.original.span(); - let func = tuple_trait.serialize_element(span); + let ty = if field.attrs.serialize_with().is_none() { + Some(field.ty) + } else { + None + }; + + let func = tuple_trait.serialize_element(ty); let ser = quote! { #func(&mut __serde_state, #field_expr)?; }; @@ -1131,7 +1136,13 @@ fn serialize_struct_visitor( #func(&#field_expr, _serde::__private::ser::FlatMapSerializer(&mut __serde_state))?; } } else { - let func = struct_trait.serialize_field(span); + let ty = if field.attrs.serialize_with().is_none() { + Some(field.ty) + } else { + None + }; + + let func = struct_trait.serialize_field(ty); quote! { #func(&mut __serde_state, #key_expr, #field_expr)?; } @@ -1300,16 +1311,17 @@ enum StructTrait { } impl StructTrait { - fn serialize_field(&self, span: Span) -> TokenStream { + fn serialize_field(&self, ty: Option<&syn::Type>) -> TokenStream { + let ty = ty.into_iter(); match *self { StructTrait::SerializeMap => { - quote_spanned!(span=> _serde::ser::SerializeMap::serialize_entry) + quote!(_serde::ser::SerializeMap::serialize_entry #( ::<_, #ty> )* ) } StructTrait::SerializeStruct => { - quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field) + quote!(_serde::ser::SerializeStruct::serialize_field #( ::<#ty> )* ) } StructTrait::SerializeStructVariant => { - quote_spanned!(span=> _serde::ser::SerializeStructVariant::serialize_field) + quote!(_serde::ser::SerializeStructVariant::serialize_field #( ::<#ty> )* ) } } } @@ -1334,16 +1346,17 @@ enum TupleTrait { } impl TupleTrait { - fn serialize_element(&self, span: Span) -> TokenStream { + fn serialize_element(&self, ty: Option<&syn::Type>) -> TokenStream { + let ty = ty.into_iter(); match *self { TupleTrait::SerializeTuple => { - quote_spanned!(span=> _serde::ser::SerializeTuple::serialize_element) + quote!(_serde::ser::SerializeTuple::serialize_element #( ::<#ty> )*) } TupleTrait::SerializeTupleStruct => { - quote_spanned!(span=> _serde::ser::SerializeTupleStruct::serialize_field) + quote!(_serde::ser::SerializeTupleStruct::serialize_field #( ::<#ty> )*) } TupleTrait::SerializeTupleVariant => { - quote_spanned!(span=> _serde::ser::SerializeTupleVariant::serialize_field) + quote!(_serde::ser::SerializeTupleVariant::serialize_field #( ::<#ty> )*) } } } diff --git a/test_suite/tests/ui/on_unimplemented.rs b/test_suite/tests/ui/on-unimplemented/fn_param.rs similarity index 99% rename from test_suite/tests/ui/on_unimplemented.rs rename to test_suite/tests/ui/on-unimplemented/fn_param.rs index fab56751b..a8f1ca9e5 100644 --- a/test_suite/tests/ui/on_unimplemented.rs +++ b/test_suite/tests/ui/on-unimplemented/fn_param.rs @@ -1,6 +1,7 @@ use serde::de::Deserialize; use serde::ser::Serialize; + fn to_string(_: &T) -> String where T: Serialize, diff --git a/test_suite/tests/ui/on_unimplemented.stderr b/test_suite/tests/ui/on-unimplemented/fn_param.stderr similarity index 79% rename from test_suite/tests/ui/on_unimplemented.stderr rename to test_suite/tests/ui/on-unimplemented/fn_param.stderr index 1b0318190..5d178829c 100644 --- a/test_suite/tests/ui/on_unimplemented.stderr +++ b/test_suite/tests/ui/on-unimplemented/fn_param.stderr @@ -1,7 +1,7 @@ error[E0277]: the trait bound `MyStruct: Serialize` is not satisfied - --> tests/ui/on_unimplemented.rs:21:15 + --> tests/ui/on-unimplemented/fn_param.rs:22:15 | -21 | to_string(&MyStruct); +22 | to_string(&MyStruct); | --------- ^^^^^^^^^ the trait `Serialize` is not implemented for `MyStruct` | | | required by a bound introduced by this call @@ -19,18 +19,18 @@ error[E0277]: the trait bound `MyStruct: Serialize` is not satisfied (T0, T1, T2, T3, T4) and $N others note: required by a bound in `to_string` - --> tests/ui/on_unimplemented.rs:6:8 + --> tests/ui/on-unimplemented/fn_param.rs:7:8 | -4 | fn to_string(_: &T) -> String +5 | fn to_string(_: &T) -> String | --------- required by a bound in this function -5 | where -6 | T: Serialize, +6 | where +7 | T: Serialize, | ^^^^^^^^^ required by this bound in `to_string` error[E0277]: the trait bound `MyStruct: Deserialize<'_>` is not satisfied - --> tests/ui/on_unimplemented.rs:22:23 + --> tests/ui/on-unimplemented/fn_param.rs:23:23 | -22 | let _: MyStruct = from_str(""); +23 | let _: MyStruct = from_str(""); | ^^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `MyStruct` | = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `MyStruct` type @@ -46,10 +46,10 @@ error[E0277]: the trait bound `MyStruct: Deserialize<'_>` is not satisfied (T0, T1, T2, T3) and $N others note: required by a bound in `from_str` - --> tests/ui/on_unimplemented.rs:13:8 + --> tests/ui/on-unimplemented/fn_param.rs:14:8 | -11 | fn from_str<'de, T>(_: &'de str) -> T +12 | fn from_str<'de, T>(_: &'de str) -> T | -------- required by a bound in this function -12 | where -13 | T: Deserialize<'de>, +13 | where +14 | T: Deserialize<'de>, | ^^^^^^^^^^^^^^^^ required by this bound in `from_str` diff --git a/test_suite/tests/ui/on-unimplemented/struct_field.rs b/test_suite/tests/ui/on-unimplemented/struct_field.rs new file mode 100644 index 000000000..a1c20513e --- /dev/null +++ b/test_suite/tests/ui/on-unimplemented/struct_field.rs @@ -0,0 +1,11 @@ +use serde_derive::{Deserialize, Serialize}; + +struct NoImpls; + +#[derive(Serialize, Deserialize)] +struct S { + x1: u32, + x2: NoImpls, +} + +fn main() {} diff --git a/test_suite/tests/ui/on-unimplemented/struct_field.stderr b/test_suite/tests/ui/on-unimplemented/struct_field.stderr new file mode 100644 index 000000000..c4dfe780f --- /dev/null +++ b/test_suite/tests/ui/on-unimplemented/struct_field.stderr @@ -0,0 +1,166 @@ +error[E0277]: the trait bound `NoImpls: Serialize` is not satisfied + --> tests/ui/on-unimplemented/struct_field.rs:8:9 + | +8 | x2: NoImpls, + | ^^^^^^^ the trait `Serialize` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Serialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Serialize`: + &'a T + &'a mut T + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + (T0, T1, T2, T3, T4) + and $N others +note: required by a bound in `_::_serde::ser::SerializeStruct::serialize_field` + --> $WORKSPACE/serde/src/ser/mod.rs + | + | fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + | --------------- required by a bound in this associated function + | where + | T: ?Sized + Serialize; + | ^^^^^^^^^ required by this bound in `SerializeStruct::serialize_field` + +error[E0277]: the trait bound `NoImpls: Deserialize<'_>` is not satisfied + --> tests/ui/on-unimplemented/struct_field.rs:8:9 + | +8 | x2: NoImpls, + | ^^^^^^^ the trait `Deserialize<'_>` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Deserialize<'de>`: + &'a Path + &'a [u8] + &'a str + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + and $N others +note: required by a bound in `next_element` + --> $WORKSPACE/serde/src/de/mod.rs + | + | fn next_element(&mut self) -> Result, Self::Error> + | ------------ required by a bound in this associated function + | where + | T: Deserialize<'de>, + | ^^^^^^^^^^^^^^^^ required by this bound in `SeqAccess::next_element` + +error[E0277]: the trait bound `NoImpls: Deserialize<'_>` is not satisfied + --> tests/ui/on-unimplemented/struct_field.rs:8:9 + | +8 | x2: NoImpls, + | ^^^^^^^ the trait `Deserialize<'_>` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Deserialize<'de>`: + &'a Path + &'a [u8] + &'a str + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + and $N others +note: required by a bound in `next_value` + --> $WORKSPACE/serde/src/de/mod.rs + | + | fn next_value(&mut self) -> Result + | ---------- required by a bound in this associated function + | where + | V: Deserialize<'de>, + | ^^^^^^^^^^^^^^^^ required by this bound in `MapAccess::next_value` + +error[E0277]: the trait bound `NoImpls: Deserialize<'_>` is not satisfied + --> tests/ui/on-unimplemented/struct_field.rs:5:21 + | +5 | #[derive(Serialize, Deserialize)] + | ^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Deserialize<'de>`: + &'a Path + &'a [u8] + &'a str + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + and $N others +note: required by a bound in `_::_serde::__private::de::missing_field` + --> $WORKSPACE/serde/src/private/de.rs + | + | pub fn missing_field<'de, V, E>(field: &'static str) -> Result + | ------------- required by a bound in this function + | where + | V: Deserialize<'de>, + | ^^^^^^^^^^^^^^^^ required by this bound in `missing_field` + = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `NoImpls: Deserialize<'_>` is not satisfied + --> tests/ui/on-unimplemented/struct_field.rs:5:21 + | +5 | #[derive(Serialize, Deserialize)] + | ^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `NoImpls`, which is required by `InPlaceSeed<'_, NoImpls>: DeserializeSeed<'_>` + | + = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Deserialize<'de>`: + &'a Path + &'a [u8] + &'a str + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + and $N others + = note: required for `InPlaceSeed<'_, NoImpls>` to implement `DeserializeSeed<'_>` +note: required by a bound in `next_element_seed` + --> $WORKSPACE/serde/src/de/mod.rs + | + | fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> + | ----------------- required by a bound in this associated function + | where + | T: DeserializeSeed<'de>; + | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `SeqAccess::next_element_seed` + = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `NoImpls: Deserialize<'_>` is not satisfied + --> tests/ui/on-unimplemented/struct_field.rs:5:21 + | +5 | #[derive(Serialize, Deserialize)] + | ^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `NoImpls`, which is required by `InPlaceSeed<'_, NoImpls>: DeserializeSeed<'_>` + | + = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Deserialize<'de>`: + &'a Path + &'a [u8] + &'a str + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + and $N others + = note: required for `InPlaceSeed<'_, NoImpls>` to implement `DeserializeSeed<'_>` +note: required by a bound in `next_value_seed` + --> $WORKSPACE/serde/src/de/mod.rs + | + | fn next_value_seed(&mut self, seed: V) -> Result + | --------------- required by a bound in this associated function + | where + | V: DeserializeSeed<'de>; + | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `MapAccess::next_value_seed` + = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/test_suite/tests/ui/on-unimplemented/struct_variant.rs b/test_suite/tests/ui/on-unimplemented/struct_variant.rs new file mode 100644 index 000000000..a4abfb60e --- /dev/null +++ b/test_suite/tests/ui/on-unimplemented/struct_variant.rs @@ -0,0 +1,10 @@ +use serde_derive::{Deserialize, Serialize}; + +struct NoImpls; + +#[derive(Serialize, Deserialize)] +enum E { + S { x1: u32, x2: NoImpls }, +} + +fn main() {} diff --git a/test_suite/tests/ui/on-unimplemented/struct_variant.stderr b/test_suite/tests/ui/on-unimplemented/struct_variant.stderr new file mode 100644 index 000000000..8a262b211 --- /dev/null +++ b/test_suite/tests/ui/on-unimplemented/struct_variant.stderr @@ -0,0 +1,108 @@ +error[E0277]: the trait bound `NoImpls: Serialize` is not satisfied + --> tests/ui/on-unimplemented/struct_variant.rs:7:22 + | +7 | S { x1: u32, x2: NoImpls }, + | ^^^^^^^ the trait `Serialize` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Serialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Serialize`: + &'a T + &'a mut T + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + (T0, T1, T2, T3, T4) + and $N others +note: required by a bound in `_::_serde::ser::SerializeStructVariant::serialize_field` + --> $WORKSPACE/serde/src/ser/mod.rs + | + | fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + | --------------- required by a bound in this associated function + | where + | T: ?Sized + Serialize; + | ^^^^^^^^^ required by this bound in `SerializeStructVariant::serialize_field` + +error[E0277]: the trait bound `NoImpls: Deserialize<'_>` is not satisfied + --> tests/ui/on-unimplemented/struct_variant.rs:7:22 + | +7 | S { x1: u32, x2: NoImpls }, + | ^^^^^^^ the trait `Deserialize<'_>` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Deserialize<'de>`: + &'a Path + &'a [u8] + &'a str + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + and $N others +note: required by a bound in `next_element` + --> $WORKSPACE/serde/src/de/mod.rs + | + | fn next_element(&mut self) -> Result, Self::Error> + | ------------ required by a bound in this associated function + | where + | T: Deserialize<'de>, + | ^^^^^^^^^^^^^^^^ required by this bound in `SeqAccess::next_element` + +error[E0277]: the trait bound `NoImpls: Deserialize<'_>` is not satisfied + --> tests/ui/on-unimplemented/struct_variant.rs:7:22 + | +7 | S { x1: u32, x2: NoImpls }, + | ^^^^^^^ the trait `Deserialize<'_>` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Deserialize<'de>`: + &'a Path + &'a [u8] + &'a str + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + and $N others +note: required by a bound in `next_value` + --> $WORKSPACE/serde/src/de/mod.rs + | + | fn next_value(&mut self) -> Result + | ---------- required by a bound in this associated function + | where + | V: Deserialize<'de>, + | ^^^^^^^^^^^^^^^^ required by this bound in `MapAccess::next_value` + +error[E0277]: the trait bound `NoImpls: Deserialize<'_>` is not satisfied + --> tests/ui/on-unimplemented/struct_variant.rs:5:21 + | +5 | #[derive(Serialize, Deserialize)] + | ^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Deserialize<'de>`: + &'a Path + &'a [u8] + &'a str + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + and $N others +note: required by a bound in `_::_serde::__private::de::missing_field` + --> $WORKSPACE/serde/src/private/de.rs + | + | pub fn missing_field<'de, V, E>(field: &'static str) -> Result + | ------------- required by a bound in this function + | where + | V: Deserialize<'de>, + | ^^^^^^^^^^^^^^^^ required by this bound in `missing_field` + = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/test_suite/tests/ui/on-unimplemented/tuple_field.rs b/test_suite/tests/ui/on-unimplemented/tuple_field.rs new file mode 100644 index 000000000..2786c1c94 --- /dev/null +++ b/test_suite/tests/ui/on-unimplemented/tuple_field.rs @@ -0,0 +1,8 @@ +use serde_derive::{Deserialize, Serialize}; + +struct NoImpls; + +#[derive(Serialize, Deserialize)] +struct S(u32, NoImpls); + +fn main() {} diff --git a/test_suite/tests/ui/on-unimplemented/tuple_field.stderr b/test_suite/tests/ui/on-unimplemented/tuple_field.stderr new file mode 100644 index 000000000..cce800c1c --- /dev/null +++ b/test_suite/tests/ui/on-unimplemented/tuple_field.stderr @@ -0,0 +1,82 @@ +error[E0277]: the trait bound `NoImpls: Serialize` is not satisfied + --> tests/ui/on-unimplemented/tuple_field.rs:6:15 + | +6 | struct S(u32, NoImpls); + | ^^^^^^^ the trait `Serialize` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Serialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Serialize`: + &'a T + &'a mut T + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + (T0, T1, T2, T3, T4) + and $N others +note: required by a bound in `_::_serde::ser::SerializeTupleStruct::serialize_field` + --> $WORKSPACE/serde/src/ser/mod.rs + | + | fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + | --------------- required by a bound in this associated function + | where + | T: ?Sized + Serialize; + | ^^^^^^^^^ required by this bound in `SerializeTupleStruct::serialize_field` + +error[E0277]: the trait bound `NoImpls: Deserialize<'_>` is not satisfied + --> tests/ui/on-unimplemented/tuple_field.rs:6:15 + | +6 | struct S(u32, NoImpls); + | ^^^^^^^ the trait `Deserialize<'_>` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Deserialize<'de>`: + &'a Path + &'a [u8] + &'a str + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + and $N others +note: required by a bound in `next_element` + --> $WORKSPACE/serde/src/de/mod.rs + | + | fn next_element(&mut self) -> Result, Self::Error> + | ------------ required by a bound in this associated function + | where + | T: Deserialize<'de>, + | ^^^^^^^^^^^^^^^^ required by this bound in `SeqAccess::next_element` + +error[E0277]: the trait bound `NoImpls: Deserialize<'_>` is not satisfied + --> tests/ui/on-unimplemented/tuple_field.rs:5:21 + | +5 | #[derive(Serialize, Deserialize)] + | ^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `NoImpls`, which is required by `InPlaceSeed<'_, NoImpls>: DeserializeSeed<'_>` + | + = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Deserialize<'de>`: + &'a Path + &'a [u8] + &'a str + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + and $N others + = note: required for `InPlaceSeed<'_, NoImpls>` to implement `DeserializeSeed<'_>` +note: required by a bound in `next_element_seed` + --> $WORKSPACE/serde/src/de/mod.rs + | + | fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> + | ----------------- required by a bound in this associated function + | where + | T: DeserializeSeed<'de>; + | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `SeqAccess::next_element_seed` + = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/test_suite/tests/ui/on-unimplemented/tuple_variant.rs b/test_suite/tests/ui/on-unimplemented/tuple_variant.rs new file mode 100644 index 000000000..71c43ca5d --- /dev/null +++ b/test_suite/tests/ui/on-unimplemented/tuple_variant.rs @@ -0,0 +1,10 @@ +use serde_derive::{Deserialize, Serialize}; + +struct NoImpls; + +#[derive(Serialize, Deserialize)] +enum E { + S(u32, NoImpls) +} + +fn main() {} diff --git a/test_suite/tests/ui/on-unimplemented/tuple_variant.stderr b/test_suite/tests/ui/on-unimplemented/tuple_variant.stderr new file mode 100644 index 000000000..92807aed8 --- /dev/null +++ b/test_suite/tests/ui/on-unimplemented/tuple_variant.stderr @@ -0,0 +1,53 @@ +error[E0277]: the trait bound `NoImpls: Serialize` is not satisfied + --> tests/ui/on-unimplemented/tuple_variant.rs:7:12 + | +7 | S(u32, NoImpls) + | ^^^^^^^ the trait `Serialize` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Serialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Serialize`: + &'a T + &'a mut T + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + (T0, T1, T2, T3, T4) + and $N others +note: required by a bound in `_::_serde::ser::SerializeTupleVariant::serialize_field` + --> $WORKSPACE/serde/src/ser/mod.rs + | + | fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + | --------------- required by a bound in this associated function + | where + | T: ?Sized + Serialize; + | ^^^^^^^^^ required by this bound in `SerializeTupleVariant::serialize_field` + +error[E0277]: the trait bound `NoImpls: Deserialize<'_>` is not satisfied + --> tests/ui/on-unimplemented/tuple_variant.rs:7:12 + | +7 | S(u32, NoImpls) + | ^^^^^^^ the trait `Deserialize<'_>` is not implemented for `NoImpls` + | + = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `NoImpls` type + = note: for types from other crates check whether the crate offers a `serde` feature flag + = help: the following other types implement trait `Deserialize<'de>`: + &'a Path + &'a [u8] + &'a str + () + (T,) + (T0, T1) + (T0, T1, T2) + (T0, T1, T2, T3) + and $N others +note: required by a bound in `next_element` + --> $WORKSPACE/serde/src/de/mod.rs + | + | fn next_element(&mut self) -> Result, Self::Error> + | ------------ required by a bound in this associated function + | where + | T: Deserialize<'de>, + | ^^^^^^^^^^^^^^^^ required by this bound in `SeqAccess::next_element`