mirror of
https://github.com/serde-rs/serde.git
synced 2025-09-30 06:21:26 +00:00
Override diagnostic::on_unimplemented message of all serde_core traits
This prevents diagnostics being rendered like `serde_core::ser::Serialize`
and `serde_core:🇩🇪:Deserialize` in projects that have no direct
dependency on serde_core.
The attributes make error messages arguably sometimes worse than
pre-serde_core by always rendering `serde::Serialize` and never
`Serialize` when `use serde::Serialize` is in scope, which rustc's
default message construction knows to recognize. But this is probably
negligible.
I explored the alternative of setting `[lib] name = "serde"` in
serde_core/Cargo.toml which also prevents `serde_core::ser::Serialize`
in messages, but has the unwanted effect of also inserting the following
noise into every such error:
note: there are multiple different versions of crate `serde` in the dependency graph
--> $WORKSPACE/serde_core/src/ser/mod.rs:225:1
|
225 | pub trait Serialize {
| ^^^^^^^^^^^^^^^^^^^ this is the required trait
|
::: src/main.rs:1:1
|
1 | struct MyStruct;
| --------------- this type doesn't implement the required trait
...
4 | let _ = serde_json::to_string(&MyStruct);
| ----------
| |
| one version of crate `serde` used here, as a dependency of crate `serde`
| one version of crate `serde` used here, as a dependency of crate `serde_json`
|
::: $WORKSPACE/serde/src/private/de.rs:2347:1
|
2347 | pub trait IdentifierDeserializer<'de, E: Error> {
| ----------------------------------------------- this is the found trait
= help: you can use `cargo tree` to explore your dependency tree
The "this is the found trait" pointing to `IdentifierDeserializer` seems
like a compiler bug...
This commit is contained in:
parent
908f32175a
commit
4bddf1b953
@ -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<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
|
||||
|
||||
@ -775,6 +796,12 @@ impl<T> 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`.
|
||||
|
@ -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;
|
||||
|
@ -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, &[]);
|
||||
|
@ -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("");
|
||||
|
@ -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<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
|
||||
| ^^^^^^^^^
|
||||
|
||||
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<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
|
||||
| ^^^^^^^^^
|
||||
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user