Skip to content

Commit 66c5d2b

Browse files
authored
Merge pull request #2963 from dtolnay/diagnosticpath
Override diagnostic::on_unimplemented message for all serde_core traits
2 parents 723fcac + 4bddf1b commit 66c5d2b

7 files changed

Lines changed: 251 additions & 12 deletions

File tree

serde_core/src/de/mod.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ macro_rules! declare_error_trait {
158158
/// type appropriate for a basic JSON data format.
159159
///
160160
/// [example data format]: https://serde.rs/data-format.html
161+
#[cfg_attr(
162+
not(no_diagnostic_namespace),
163+
diagnostic::on_unimplemented(
164+
message = "the trait bound `{Self}: serde::de::Error` is not satisfied",
165+
)
166+
)]
161167
pub trait Error: Sized $(+ $($supertrait)::+)* {
162168
/// Raised when there is general error when deserializing a type.
163169
///
@@ -471,6 +477,12 @@ impl<'a> fmt::Display for Unexpected<'a> {
471477
/// ));
472478
/// # }
473479
/// ```
480+
#[cfg_attr(
481+
not(no_diagnostic_namespace),
482+
diagnostic::on_unimplemented(
483+
message = "the trait bound `{Self}: serde::de::Expected` is not satisfied",
484+
)
485+
)]
474486
pub trait Expected {
475487
/// Format an explanation of what data was being expected. Same signature as
476488
/// the `Display` and `Debug` traits.
@@ -534,6 +546,9 @@ impl Display for dyn Expected + '_ {
534546
#[cfg_attr(
535547
not(no_diagnostic_namespace),
536548
diagnostic::on_unimplemented(
549+
// Prevents `serde_core::de::Deserialize` appearing in the error message
550+
// in projects with no direct dependency on serde_core.
551+
message = "the trait bound `{Self}: serde::Deserialize<'de>` is not satisfied",
537552
note = "for local types consider adding `#[derive(serde::Deserialize)]` to your `{Self}` type",
538553
note = "for types from other crates check whether the crate offers a `serde` feature flag",
539554
)
@@ -610,6 +625,12 @@ pub trait Deserialize<'de>: Sized {
610625
/// lifetimes].
611626
///
612627
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
628+
#[cfg_attr(
629+
not(no_diagnostic_namespace),
630+
diagnostic::on_unimplemented(
631+
message = "the trait bound `{Self}: serde::de::DeserializeOwned` is not satisfied",
632+
)
633+
)]
613634
pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
614635
impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
615636

@@ -775,6 +796,12 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
775796
/// # Ok(())
776797
/// # }
777798
/// ```
799+
#[cfg_attr(
800+
not(no_diagnostic_namespace),
801+
diagnostic::on_unimplemented(
802+
message = "the trait bound `{Self}: serde::de::DeserializeSeed<'de>` is not satisfied",
803+
)
804+
)]
778805
pub trait DeserializeSeed<'de>: Sized {
779806
/// The type produced by using this seed.
780807
type Value;
@@ -911,6 +938,12 @@ where
911938
/// a basic JSON `Deserializer`.
912939
///
913940
/// [example data format]: https://serde.rs/data-format.html
941+
#[cfg_attr(
942+
not(no_diagnostic_namespace),
943+
diagnostic::on_unimplemented(
944+
message = "the trait bound `{Self}: serde::de::Deserializer<'de>` is not satisfied",
945+
)
946+
)]
914947
pub trait Deserializer<'de>: Sized {
915948
/// The error type that can be returned if some error occurs during
916949
/// deserialization.
@@ -1267,6 +1300,12 @@ pub trait Deserializer<'de>: Sized {
12671300
/// }
12681301
/// }
12691302
/// ```
1303+
#[cfg_attr(
1304+
not(no_diagnostic_namespace),
1305+
diagnostic::on_unimplemented(
1306+
message = "the trait bound `{Self}: serde::de::Visitor<'de>` is not satisfied",
1307+
)
1308+
)]
12701309
pub trait Visitor<'de>: Sized {
12711310
/// The value produced by this visitor.
12721311
type Value;
@@ -1693,6 +1732,12 @@ pub trait Visitor<'de>: Sized {
16931732
/// implementation of `SeqAccess` for a basic JSON data format.
16941733
///
16951734
/// [example data format]: https://serde.rs/data-format.html
1735+
#[cfg_attr(
1736+
not(no_diagnostic_namespace),
1737+
diagnostic::on_unimplemented(
1738+
message = "the trait bound `{Self}: serde::de::SeqAccess<'de>` is not satisfied",
1739+
)
1740+
)]
16961741
pub trait SeqAccess<'de> {
16971742
/// The error type that can be returned if some error occurs during
16981743
/// deserialization.
@@ -1775,6 +1820,12 @@ where
17751820
/// implementation of `MapAccess` for a basic JSON data format.
17761821
///
17771822
/// [example data format]: https://serde.rs/data-format.html
1823+
#[cfg_attr(
1824+
not(no_diagnostic_namespace),
1825+
diagnostic::on_unimplemented(
1826+
message = "the trait bound `{Self}: serde::de::MapAccess<'de>` is not satisfied",
1827+
)
1828+
)]
17781829
pub trait MapAccess<'de> {
17791830
/// The error type that can be returned if some error occurs during
17801831
/// deserialization.
@@ -1967,6 +2018,12 @@ where
19672018
/// implementation of `EnumAccess` for a basic JSON data format.
19682019
///
19692020
/// [example data format]: https://serde.rs/data-format.html
2021+
#[cfg_attr(
2022+
not(no_diagnostic_namespace),
2023+
diagnostic::on_unimplemented(
2024+
message = "the trait bound `{Self}: serde::de::EnumAccess<'de>` is not satisfied",
2025+
)
2026+
)]
19702027
pub trait EnumAccess<'de>: Sized {
19712028
/// The error type that can be returned if some error occurs during
19722029
/// deserialization.
@@ -2014,6 +2071,12 @@ pub trait EnumAccess<'de>: Sized {
20142071
/// implementation of `VariantAccess` for a basic JSON data format.
20152072
///
20162073
/// [example data format]: https://serde.rs/data-format.html
2074+
#[cfg_attr(
2075+
not(no_diagnostic_namespace),
2076+
diagnostic::on_unimplemented(
2077+
message = "the trait bound `{Self}: serde::de::VariantAccess<'de>` is not satisfied",
2078+
)
2079+
)]
20172080
pub trait VariantAccess<'de>: Sized {
20182081
/// The error type that can be returned if some error occurs during
20192082
/// deserialization. Must match the error type of our `EnumAccess`.

serde_core/src/ser/mod.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ macro_rules! declare_error_trait {
139139
/// type appropriate for a basic JSON data format.
140140
///
141141
/// [example data format]: https://serde.rs/data-format.html
142+
#[cfg_attr(
143+
not(no_diagnostic_namespace),
144+
diagnostic::on_unimplemented(
145+
message = "the trait bound `{Self}: serde::ser::Error` is not satisfied",
146+
)
147+
)]
142148
pub trait Error: Sized $(+ $($supertrait)::+)* {
143149
/// Used when a [`Serialize`] implementation encounters any error
144150
/// while serializing a type.
@@ -218,6 +224,9 @@ declare_error_trait!(Error: Sized + Debug + Display);
218224
#[cfg_attr(
219225
not(no_diagnostic_namespace),
220226
diagnostic::on_unimplemented(
227+
// Prevents `serde_core::ser::Serialize` appearing in the error message
228+
// in projects with no direct dependency on serde_core.
229+
message = "the trait bound `{Self}: serde::Serialize` is not satisfied",
221230
note = "for local types consider adding `#[derive(serde::Serialize)]` to your `{Self}` type",
222231
note = "for types from other crates check whether the crate offers a `serde` feature flag",
223232
)
@@ -337,6 +346,12 @@ pub trait Serialize {
337346
/// a basic JSON `Serializer`.
338347
///
339348
/// [example data format]: https://serde.rs/data-format.html
349+
#[cfg_attr(
350+
not(no_diagnostic_namespace),
351+
diagnostic::on_unimplemented(
352+
message = "the trait bound `{Self}: serde::Serializer` is not satisfied",
353+
)
354+
)]
340355
pub trait Serializer: Sized {
341356
/// The output type produced by this `Serializer` during successful
342357
/// serialization. Most serializers that produce text or binary output
@@ -1494,6 +1509,12 @@ pub trait Serializer: Sized {
14941509
/// implementation of `SerializeSeq` for a basic JSON data format.
14951510
///
14961511
/// [example data format]: https://serde.rs/data-format.html
1512+
#[cfg_attr(
1513+
not(no_diagnostic_namespace),
1514+
diagnostic::on_unimplemented(
1515+
message = "the trait bound `{Self}: serde::ser::SerializeSeq` is not satisfied",
1516+
)
1517+
)]
14971518
pub trait SerializeSeq {
14981519
/// Must match the `Ok` type of our `Serializer`.
14991520
type Ok;
@@ -1594,6 +1615,12 @@ pub trait SerializeSeq {
15941615
/// implementation of `SerializeTuple` for a basic JSON data format.
15951616
///
15961617
/// [example data format]: https://serde.rs/data-format.html
1618+
#[cfg_attr(
1619+
not(no_diagnostic_namespace),
1620+
diagnostic::on_unimplemented(
1621+
message = "the trait bound `{Self}: serde::ser::SerializeTuple` is not satisfied",
1622+
)
1623+
)]
15971624
pub trait SerializeTuple {
15981625
/// Must match the `Ok` type of our `Serializer`.
15991626
type Ok;
@@ -1639,6 +1666,12 @@ pub trait SerializeTuple {
16391666
/// implementation of `SerializeTupleStruct` for a basic JSON data format.
16401667
///
16411668
/// [example data format]: https://serde.rs/data-format.html
1669+
#[cfg_attr(
1670+
not(no_diagnostic_namespace),
1671+
diagnostic::on_unimplemented(
1672+
message = "the trait bound `{Self}: serde::ser::SerializeTupleStruct` is not satisfied",
1673+
)
1674+
)]
16421675
pub trait SerializeTupleStruct {
16431676
/// Must match the `Ok` type of our `Serializer`.
16441677
type Ok;
@@ -1697,6 +1730,12 @@ pub trait SerializeTupleStruct {
16971730
/// implementation of `SerializeTupleVariant` for a basic JSON data format.
16981731
///
16991732
/// [example data format]: https://serde.rs/data-format.html
1733+
#[cfg_attr(
1734+
not(no_diagnostic_namespace),
1735+
diagnostic::on_unimplemented(
1736+
message = "the trait bound `{Self}: serde::ser::SerializeTupleVariant` is not satisfied",
1737+
)
1738+
)]
17001739
pub trait SerializeTupleVariant {
17011740
/// Must match the `Ok` type of our `Serializer`.
17021741
type Ok;
@@ -1763,6 +1802,12 @@ pub trait SerializeTupleVariant {
17631802
/// implementation of `SerializeMap` for a basic JSON data format.
17641803
///
17651804
/// [example data format]: https://serde.rs/data-format.html
1805+
#[cfg_attr(
1806+
not(no_diagnostic_namespace),
1807+
diagnostic::on_unimplemented(
1808+
message = "the trait bound `{Self}: serde::ser::SerializeMap` is not satisfied",
1809+
)
1810+
)]
17661811
pub trait SerializeMap {
17671812
/// Must match the `Ok` type of our `Serializer`.
17681813
type Ok;
@@ -1853,6 +1898,12 @@ pub trait SerializeMap {
18531898
/// implementation of `SerializeStruct` for a basic JSON data format.
18541899
///
18551900
/// [example data format]: https://serde.rs/data-format.html
1901+
#[cfg_attr(
1902+
not(no_diagnostic_namespace),
1903+
diagnostic::on_unimplemented(
1904+
message = "the trait bound `{Self}: serde::ser::SerializeStruct` is not satisfied",
1905+
)
1906+
)]
18561907
pub trait SerializeStruct {
18571908
/// Must match the `Ok` type of our `Serializer`.
18581909
type Ok;
@@ -1917,6 +1968,12 @@ pub trait SerializeStruct {
19171968
/// implementation of `SerializeStructVariant` for a basic JSON data format.
19181969
///
19191970
/// [example data format]: https://serde.rs/data-format.html
1971+
#[cfg_attr(
1972+
not(no_diagnostic_namespace),
1973+
diagnostic::on_unimplemented(
1974+
message = "the trait bound `{Self}: serde::ser::SerializeStructVariant` is not satisfied",
1975+
)
1976+
)]
19201977
pub trait SerializeStructVariant {
19211978
/// Must match the `Ok` type of our `Serializer`.
19221979
type Ok;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
struct MyStruct;
2+
3+
fn main() {
4+
serde_test::assert_ser_tokens(&MyStruct, &[]);
5+
serde_test::assert_de_tokens(&MyStruct, &[]);
6+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
error[E0277]: the trait bound `MyStruct: serde::Serialize` is not satisfied
2+
--> tests/ui/unimplemented/required_by_dependency.rs:4:35
3+
|
4+
4 | serde_test::assert_ser_tokens(&MyStruct, &[]);
5+
| ----------------------------- ^^^^^^^^^ unsatisfied trait bound
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
help: the trait `serde_core::ser::Serialize` is not implemented for `MyStruct`
10+
--> tests/ui/unimplemented/required_by_dependency.rs:1:1
11+
|
12+
1 | struct MyStruct;
13+
| ^^^^^^^^^^^^^^^
14+
= note: for local types consider adding `#[derive(serde::Serialize)]` to your `MyStruct` type
15+
= note: for types from other crates check whether the crate offers a `serde` feature flag
16+
= help: the following other types implement trait `serde_core::ser::Serialize`:
17+
&'a T
18+
&'a mut T
19+
()
20+
(T,)
21+
(T0, T1)
22+
(T0, T1, T2)
23+
(T0, T1, T2, T3)
24+
(T0, T1, T2, T3, T4)
25+
and $N others
26+
note: required by a bound in `assert_ser_tokens`
27+
--> $CARGO/serde_test-$VERSION/src/assert.rs
28+
|
29+
| pub fn assert_ser_tokens<T>(value: &T, tokens: &[Token])
30+
| ----------------- required by a bound in this function
31+
| where
32+
| T: ?Sized + Serialize,
33+
| ^^^^^^^^^ required by this bound in `assert_ser_tokens`
34+
35+
error[E0277]: the trait bound `MyStruct: serde::Deserialize<'de>` is not satisfied
36+
--> tests/ui/unimplemented/required_by_dependency.rs:5:34
37+
|
38+
5 | serde_test::assert_de_tokens(&MyStruct, &[]);
39+
| ---------------------------- ^^^^^^^^^ unsatisfied trait bound
40+
| |
41+
| required by a bound introduced by this call
42+
|
43+
help: the trait `serde_core::de::Deserialize<'_>` is not implemented for `MyStruct`
44+
--> tests/ui/unimplemented/required_by_dependency.rs:1:1
45+
|
46+
1 | struct MyStruct;
47+
| ^^^^^^^^^^^^^^^
48+
= note: for local types consider adding `#[derive(serde::Deserialize)]` to your `MyStruct` type
49+
= note: for types from other crates check whether the crate offers a `serde` feature flag
50+
= help: the following other types implement trait `serde_core::de::Deserialize<'de>`:
51+
&'a Path
52+
&'a [u8]
53+
&'a str
54+
()
55+
(T,)
56+
(T0, T1)
57+
(T0, T1, T2)
58+
(T0, T1, T2, T3)
59+
and $N others
60+
note: required by a bound in `assert_de_tokens`
61+
--> $CARGO/serde_test-$VERSION/src/assert.rs
62+
|
63+
| pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
64+
| ---------------- required by a bound in this function
65+
| where
66+
| T: Deserialize<'de> + PartialEq + Debug,
67+
| ^^^^^^^^^^^^^^^^ required by this bound in `assert_de_tokens`
68+
69+
error[E0277]: can't compare `MyStruct` with `MyStruct`
70+
--> tests/ui/unimplemented/required_by_dependency.rs:5:34
71+
|
72+
5 | serde_test::assert_de_tokens(&MyStruct, &[]);
73+
| ---------------------------- ^^^^^^^^^ no implementation for `MyStruct == MyStruct`
74+
| |
75+
| required by a bound introduced by this call
76+
|
77+
= help: the trait `PartialEq` is not implemented for `MyStruct`
78+
note: required by a bound in `assert_de_tokens`
79+
--> $CARGO/serde_test-$VERSION/src/assert.rs
80+
|
81+
| pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
82+
| ---------------- required by a bound in this function
83+
| where
84+
| T: Deserialize<'de> + PartialEq + Debug,
85+
| ^^^^^^^^^ required by this bound in `assert_de_tokens`
86+
help: consider annotating `MyStruct` with `#[derive(PartialEq)]`
87+
|
88+
1 + #[derive(PartialEq)]
89+
2 | struct MyStruct;
90+
|
91+
92+
error[E0277]: `MyStruct` doesn't implement `Debug`
93+
--> tests/ui/unimplemented/required_by_dependency.rs:5:34
94+
|
95+
5 | serde_test::assert_de_tokens(&MyStruct, &[]);
96+
| ---------------------------- ^^^^^^^^^ the trait `Debug` is not implemented for `MyStruct`
97+
| |
98+
| required by a bound introduced by this call
99+
|
100+
= note: add `#[derive(Debug)]` to `MyStruct` or manually `impl Debug for MyStruct`
101+
note: required by a bound in `assert_de_tokens`
102+
--> $CARGO/serde_test-$VERSION/src/assert.rs
103+
|
104+
| pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
105+
| ---------------- required by a bound in this function
106+
| where
107+
| T: Deserialize<'de> + PartialEq + Debug,
108+
| ^^^^^ required by this bound in `assert_de_tokens`
109+
help: consider annotating `MyStruct` with `#[derive(Debug)]`
110+
|
111+
1 + #[derive(Debug)]
112+
2 | struct MyStruct;
113+
|
File renamed without changes.

0 commit comments

Comments
 (0)