diff --git a/serde_core/src/de/mod.rs b/serde_core/src/de/mod.rs index d540dcc8..c21480c9 100644 --- a/serde_core/src/de/mod.rs +++ b/serde_core/src/de/mod.rs @@ -158,6 +158,12 @@ macro_rules! declare_error_trait { /// type appropriate for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html + #[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::de::Error` is not satisfied", + ) + )] pub trait Error: Sized $(+ $($supertrait)::+)* { /// Raised when there is general error when deserializing a type. /// @@ -471,6 +477,12 @@ impl<'a> fmt::Display for Unexpected<'a> { /// )); /// # } /// ``` +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::de::Expected` is not satisfied", + ) +)] pub trait Expected { /// Format an explanation of what data was being expected. Same signature as /// the `Display` and `Debug` traits. @@ -534,6 +546,9 @@ impl Display for dyn Expected + '_ { #[cfg_attr( not(no_diagnostic_namespace), diagnostic::on_unimplemented( + // Prevents `serde_core::de::Deserialize` appearing in the error message + // in projects with no direct dependency on serde_core. + message = "the trait bound `{Self}: serde::Deserialize<'de>` is not satisfied", note = "for local types consider adding `#[derive(serde::Deserialize)]` to your `{Self}` type", note = "for types from other crates check whether the crate offers a `serde` feature flag", ) @@ -610,6 +625,12 @@ pub trait Deserialize<'de>: Sized { /// lifetimes]. /// /// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::de::DeserializeOwned` is not satisfied", + ) +)] pub trait DeserializeOwned: for<'de> Deserialize<'de> {} impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} @@ -775,6 +796,12 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// # Ok(()) /// # } /// ``` +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::de::DeserializeSeed<'de>` is not satisfied", + ) +)] pub trait DeserializeSeed<'de>: Sized { /// The type produced by using this seed. type Value; @@ -911,6 +938,12 @@ where /// a basic JSON `Deserializer`. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::de::Deserializer<'de>` is not satisfied", + ) +)] pub trait Deserializer<'de>: Sized { /// The error type that can be returned if some error occurs during /// deserialization. @@ -1267,6 +1300,12 @@ pub trait Deserializer<'de>: Sized { /// } /// } /// ``` +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::de::Visitor<'de>` is not satisfied", + ) +)] pub trait Visitor<'de>: Sized { /// The value produced by this visitor. type Value; @@ -1693,6 +1732,12 @@ pub trait Visitor<'de>: Sized { /// implementation of `SeqAccess` for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::de::SeqAccess<'de>` is not satisfied", + ) +)] pub trait SeqAccess<'de> { /// The error type that can be returned if some error occurs during /// deserialization. @@ -1775,6 +1820,12 @@ where /// implementation of `MapAccess` for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::de::MapAccess<'de>` is not satisfied", + ) +)] pub trait MapAccess<'de> { /// The error type that can be returned if some error occurs during /// deserialization. @@ -1967,6 +2018,12 @@ where /// implementation of `EnumAccess` for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::de::EnumAccess<'de>` is not satisfied", + ) +)] pub trait EnumAccess<'de>: Sized { /// The error type that can be returned if some error occurs during /// deserialization. @@ -2014,6 +2071,12 @@ pub trait EnumAccess<'de>: Sized { /// implementation of `VariantAccess` for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::de::VariantAccess<'de>` is not satisfied", + ) +)] pub trait VariantAccess<'de>: Sized { /// The error type that can be returned if some error occurs during /// deserialization. Must match the error type of our `EnumAccess`. diff --git a/serde_core/src/ser/mod.rs b/serde_core/src/ser/mod.rs index 23418f9f..698d33ed 100644 --- a/serde_core/src/ser/mod.rs +++ b/serde_core/src/ser/mod.rs @@ -139,6 +139,12 @@ macro_rules! declare_error_trait { /// type appropriate for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html + #[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::ser::Error` is not satisfied", + ) + )] pub trait Error: Sized $(+ $($supertrait)::+)* { /// Used when a [`Serialize`] implementation encounters any error /// while serializing a type. @@ -218,6 +224,9 @@ declare_error_trait!(Error: Sized + Debug + Display); #[cfg_attr( not(no_diagnostic_namespace), diagnostic::on_unimplemented( + // Prevents `serde_core::ser::Serialize` appearing in the error message + // in projects with no direct dependency on serde_core. + message = "the trait bound `{Self}: serde::Serialize` is not satisfied", note = "for local types consider adding `#[derive(serde::Serialize)]` to your `{Self}` type", note = "for types from other crates check whether the crate offers a `serde` feature flag", ) @@ -337,6 +346,12 @@ pub trait Serialize { /// a basic JSON `Serializer`. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::Serializer` is not satisfied", + ) +)] pub trait Serializer: Sized { /// The output type produced by this `Serializer` during successful /// serialization. Most serializers that produce text or binary output @@ -1494,6 +1509,12 @@ pub trait Serializer: Sized { /// implementation of `SerializeSeq` for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::ser::SerializeSeq` is not satisfied", + ) +)] pub trait SerializeSeq { /// Must match the `Ok` type of our `Serializer`. type Ok; @@ -1594,6 +1615,12 @@ pub trait SerializeSeq { /// implementation of `SerializeTuple` for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::ser::SerializeTuple` is not satisfied", + ) +)] pub trait SerializeTuple { /// Must match the `Ok` type of our `Serializer`. type Ok; @@ -1639,6 +1666,12 @@ pub trait SerializeTuple { /// implementation of `SerializeTupleStruct` for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::ser::SerializeTupleStruct` is not satisfied", + ) +)] pub trait SerializeTupleStruct { /// Must match the `Ok` type of our `Serializer`. type Ok; @@ -1697,6 +1730,12 @@ pub trait SerializeTupleStruct { /// implementation of `SerializeTupleVariant` for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::ser::SerializeTupleVariant` is not satisfied", + ) +)] pub trait SerializeTupleVariant { /// Must match the `Ok` type of our `Serializer`. type Ok; @@ -1763,6 +1802,12 @@ pub trait SerializeTupleVariant { /// implementation of `SerializeMap` for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::ser::SerializeMap` is not satisfied", + ) +)] pub trait SerializeMap { /// Must match the `Ok` type of our `Serializer`. type Ok; @@ -1853,6 +1898,12 @@ pub trait SerializeMap { /// implementation of `SerializeStruct` for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::ser::SerializeStruct` is not satisfied", + ) +)] pub trait SerializeStruct { /// Must match the `Ok` type of our `Serializer`. type Ok; @@ -1917,6 +1968,12 @@ pub trait SerializeStruct { /// implementation of `SerializeStructVariant` for a basic JSON data format. /// /// [example data format]: https://serde.rs/data-format.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + message = "the trait bound `{Self}: serde::ser::SerializeStructVariant` is not satisfied", + ) +)] pub trait SerializeStructVariant { /// Must match the `Ok` type of our `Serializer`. type Ok; diff --git a/test_suite/tests/ui/unimplemented/required_by_dependency.stderr b/test_suite/tests/ui/unimplemented/required_by_dependency.stderr index 7a35caee..2473a812 100644 --- a/test_suite/tests/ui/unimplemented/required_by_dependency.stderr +++ b/test_suite/tests/ui/unimplemented/required_by_dependency.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `MyStruct: serde_core::ser::Serialize` is not satisfied +error[E0277]: the trait bound `MyStruct: serde::Serialize` is not satisfied --> tests/ui/unimplemented/required_by_dependency.rs:4:35 | 4 | serde_test::assert_ser_tokens(&MyStruct, &[]); @@ -32,7 +32,7 @@ note: required by a bound in `assert_ser_tokens` | T: ?Sized + Serialize, | ^^^^^^^^^ required by this bound in `assert_ser_tokens` -error[E0277]: the trait bound `MyStruct: serde_core::de::Deserialize<'_>` is not satisfied +error[E0277]: the trait bound `MyStruct: serde::Deserialize<'de>` is not satisfied --> tests/ui/unimplemented/required_by_dependency.rs:5:34 | 5 | serde_test::assert_de_tokens(&MyStruct, &[]); diff --git a/test_suite/tests/ui/unimplemented/required_locally.stderr b/test_suite/tests/ui/unimplemented/required_locally.stderr index 5828800f..e64fd411 100644 --- a/test_suite/tests/ui/unimplemented/required_locally.stderr +++ b/test_suite/tests/ui/unimplemented/required_locally.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `MyStruct: Serialize` is not satisfied +error[E0277]: the trait bound `MyStruct: serde::Serialize` is not satisfied --> tests/ui/unimplemented/required_locally.rs:21:15 | 21 | to_string(&MyStruct); @@ -32,7 +32,7 @@ note: required by a bound in `to_string` 6 | T: Serialize, | ^^^^^^^^^ required by this bound in `to_string` -error[E0277]: the trait bound `MyStruct: Deserialize<'_>` is not satisfied +error[E0277]: the trait bound `MyStruct: serde::Deserialize<'de>` is not satisfied --> tests/ui/unimplemented/required_locally.rs:22:23 | 22 | let _: MyStruct = from_str(""); diff --git a/test_suite/tests/ui/with/incorrect_type.stderr b/test_suite/tests/ui/with/incorrect_type.stderr index 1e625b0e..e707b472 100644 --- a/test_suite/tests/ui/with/incorrect_type.stderr +++ b/test_suite/tests/ui/with/incorrect_type.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `&u8: Serializer` is not satisfied +error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied --> tests/ui/with/incorrect_type.rs:14:10 | 14 | #[derive(Serialize, Deserialize)] @@ -30,7 +30,7 @@ note: function defined here 9 | pub fn serialize(_: S) -> Result { | ^^^^^^^^^ -error[E0277]: the trait bound `&u8: Serializer` is not satisfied +error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied --> tests/ui/with/incorrect_type.rs:15:25 | 15 | struct W(#[serde(with = "w")] u8, u8); @@ -49,7 +49,7 @@ error[E0308]: `?` operator has incompatible types | = note: `?` operator cannot convert from `()` to `u8` -error[E0277]: the trait bound `&u8: Serializer` is not satisfied +error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied --> tests/ui/with/incorrect_type.rs:17:10 | 17 | #[derive(Serialize, Deserialize)] @@ -81,7 +81,7 @@ note: function defined here 9 | pub fn serialize(_: S) -> Result { | ^^^^^^^^^ -error[E0277]: the trait bound `&u8: Serializer` is not satisfied +error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied --> tests/ui/with/incorrect_type.rs:18:35 | 18 | struct S(#[serde(serialize_with = "w::serialize")] u8, u8);