Compare commits

...

45 Commits

Author SHA1 Message Date
David Tolnay 85c73ef8de Release 1.0.206 2024-08-11 00:08:37 -07:00
David Tolnay 5ba1796a7e Resolve doc_markdown pedantic lint on regression test function
warning: you should put bare URLs between `<`/`>` or make a proper Markdown link
        --> test_suite/tests/test_annotations.rs:2383:25
         |
    2383 | /// Regression test for https://github.com/serde-rs/serde/issues/1904
         |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<https://github.com/serde-rs/serde/issues/1904>`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown
         = note: `-W clippy::doc-markdown` implied by `-W clippy::pedantic`
         = help: to override `-W clippy::pedantic` add `#[allow(clippy::doc_markdown)]`
2024-08-11 00:08:16 -07:00
David Tolnay e52b7b380f Touch up PR 2567 2024-08-11 00:05:56 -07:00
David Tolnay 84c7419652 Merge pull request #2794 from dtolnay/neverread
Temporarily ignore collection_is_never_read on FlattenSkipDeserializing
2024-08-11 00:05:31 -07:00
David Tolnay 536221b1f9 Temporarily ignore collection_is_never_read on FlattenSkipDeserializing
error: collection is never read
       --> test_suite/tests/test_gen.rs:723:25
        |
    723 |     #[derive(Serialize, Deserialize)]
        |                         ^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#collection_is_never_read
    note: the lint level is defined here
       --> test_suite/tests/test_gen.rs:23:9
        |
    23  | #![deny(clippy::collection_is_never_read)]
        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
2024-08-10 23:59:23 -07:00
David Tolnay fc55ac70d3 Merge pull request #2567 from Mingun/fix-2565
Correctly process flatten fields in enum variants
2024-08-10 23:28:22 -07:00
Mingun 2afe5b4ef9 Add regression test for issue #2792 2024-08-10 21:29:39 +05:00
Mingun b4ec2595c9 Correctly process flatten fields in enum variants
- Fix incorrect deserialization of variants that doesn't contain flatten field when other contains
- Fix a panic when deriving `Deserialize` for an enum with tuple and struct with flatten field

Fixes (2):
    regression::issue2565::simple_variant
    regression::issue1904 (compilation)
2024-08-09 19:59:23 +05:00
Mingun c3ac7b675a Add regression test for issue #1904
Currently panics in derive:

error: proc-macro derive panicked
    --> test_suite\tests\test_annotations.rs:2386:25
     |
2386 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
     |                         ^^^^^^^^^^^
     |
     = help: message: assertion failed: !cattrs.has_flatten()

error: proc-macro derive panicked
  --> test_suite\tests\regression\issue1904.rs:57:10
   |
57 | #[derive(Deserialize)]
   |          ^^^^^^^^^^^
   |
   = help: message: assertion failed: !cattrs.has_flatten()

error: proc-macro derive panicked
  --> test_suite\tests\regression\issue1904.rs:47:10
   |
47 | #[derive(Deserialize)]
   |          ^^^^^^^^^^^
   |
   = help: message: assertion failed: !cattrs.has_flatten()

error: proc-macro derive panicked
  --> test_suite\tests\regression\issue1904.rs:37:10
   |
37 | #[derive(Deserialize)]
   |          ^^^^^^^^^^^
   |
   = help: message: assertion failed: !cattrs.has_flatten()

error: proc-macro derive panicked
  --> test_suite\tests\regression\issue1904.rs:27:10
   |
27 | #[derive(Deserialize)]
   |          ^^^^^^^^^^^
   |
   = help: message: assertion failed: !cattrs.has_flatten()

error: proc-macro derive panicked
  --> test_suite\tests\regression\issue1904.rs:16:10
   |
16 | #[derive(Deserialize)]
   |          ^^^^^^^^^^^
   |
   = help: message: assertion failed: !cattrs.has_flatten()

error: proc-macro derive panicked
 --> test_suite\tests\regression\issue1904.rs:7:10
  |
7 | #[derive(Deserialize)]
  |          ^^^^^^^^^^^
  |
  = help: message: assertion failed: !cattrs.has_flatten()
2024-08-09 19:55:56 +05:00
Mingun 24614e44bf Add regression test for issue #2565
failures (1):
    regression::issue2565::simple_variant
2024-08-09 19:53:14 +05:00
David Tolnay 9b868ef831 Release 1.0.205 2024-08-07 18:53:21 -07:00
David Tolnay c3eaf76430 Merge pull request #2791 from dtolnay/flatten
Skip collecting unmatched fields in variants that do not use flatten
2024-08-07 18:52:21 -07:00
David Tolnay 32958dec3b Skip collecting unmatched fields in variants that do not use flatten 2024-08-07 18:43:47 -07:00
David Tolnay d64a97ba1e Ignore confusable_idents warning in test
error: found both `σ` and `o` as identifiers, which look alike
       --> test_suite/tests/test_gen.rs:734:13
        |
    292 |         σ: f64,
        |         - other identifier used here
    ...
    734 |             o: T,
        |             ^ this identifier can be confused with `σ`
        |
    note: the lint level is defined here
       --> test_suite/tests/test_gen.rs:5:9
        |
    5   | #![deny(warnings)]
        |         ^^^^^^^^
        = note: `#[deny(confusable_idents)]` implied by `#[deny(warnings)]`
2024-08-07 18:19:51 -07:00
David Tolnay c3df3372a1 Add test of flatten in enum
error: collection is never read
       --> test_suite/tests/test_gen.rs:728:25
        |
    728 |     #[derive(Serialize, Deserialize)]
        |                         ^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#collection_is_never_read
        = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
2024-08-07 18:19:17 -07:00
David Tolnay 8764353fe2 Enable collection_is_never_read nursury lint in test
error: collection is never read
       --> test_suite/tests/test_gen.rs:722:25
        |
    722 |     #[derive(Serialize, Deserialize)]
        |                         ^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#collection_is_never_read
    note: the lint level is defined here
       --> test_suite/tests/test_gen.rs:22:9
        |
    22  | #![deny(clippy::collection_is_never_read)]
        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
2024-08-07 18:16:55 -07:00
David Tolnay e08c5de5dd Merge pull request #2785 from Mingun/serialize_entry-in-flatten-newtype-variant
Use serialize_entry instead of serialize_key + serialize_value when serialize flatten newtype enum variant
2024-08-05 00:17:58 -07:00
Mingun bc5af506bd Use serialize_entry instead of serialize_key + serialize_value when serialize flatten newtype enum variant
Serializers that reimplements serialize_entry will get benefits from that
2024-08-03 14:49:38 +05:00
David Tolnay 28a092261b Work around test suite dead code warnings in nightly-2024-07-07
warning: struct `Cows` is never constructed
       --> test_suite/tests/test_borrow.rs:165:12
        |
    165 |     struct Cows<'a, 'b> {
        |            ^^^^

    warning: struct `Wrap` is never constructed
       --> test_suite/tests/test_borrow.rs:181:12
        |
    181 |     struct Wrap<'a, 'b> {
        |            ^^^^

    warning: struct `StructSkipDefaultGeneric` is never constructed
      --> test_suite/tests/test_de.rs:96:8
       |
    96 | struct StructSkipDefaultGeneric<T> {
       |        ^^^^^^^^^^^^^^^^^^^^^^^^

    warning: struct `NonAsciiIdents` is never constructed
       --> test_suite/tests/test_gen.rs:290:12
        |
    290 |     struct NonAsciiIdents {
        |            ^^^^^^^^^^^^^^
        |
    note: the lint level is defined here
       --> test_suite/tests/test_gen.rs:5:9
        |
    5   | #![deny(warnings)]
        |         ^^^^^^^^
        = note: `#[warn(dead_code)]` implied by `#[warn(warnings)]`

    warning: struct `EmptyBraced` is never constructed
       --> test_suite/tests/test_gen.rs:295:12
        |
    295 |     struct EmptyBraced {}
        |            ^^^^^^^^^^^

    warning: struct `EmptyBracedDenyUnknown` is never constructed
       --> test_suite/tests/test_gen.rs:299:12
        |
    299 |     struct EmptyBracedDenyUnknown {}
        |            ^^^^^^^^^^^^^^^^^^^^^^

    warning: struct `BracedSkipAll` is never constructed
       --> test_suite/tests/test_gen.rs:302:12
        |
    302 |     struct BracedSkipAll {
        |            ^^^^^^^^^^^^^

    warning: struct `BracedSkipAllDenyUnknown` is never constructed
       --> test_suite/tests/test_gen.rs:309:12
        |
    309 |     struct BracedSkipAllDenyUnknown {
        |            ^^^^^^^^^^^^^^^^^^^^^^^^

    warning: struct `EmptyTuple` is never constructed
       --> test_suite/tests/test_gen.rs:315:12
        |
    315 |     struct EmptyTuple();
        |            ^^^^^^^^^^

    warning: struct `EmptyTupleDenyUnknown` is never constructed
       --> test_suite/tests/test_gen.rs:319:12
        |
    319 |     struct EmptyTupleDenyUnknown();
        |            ^^^^^^^^^^^^^^^^^^^^^

    warning: struct `TupleSkipAll` is never constructed
       --> test_suite/tests/test_gen.rs:322:12
        |
    322 |     struct TupleSkipAll(#[serde(skip_deserializing)] u8);
        |            ^^^^^^^^^^^^

    warning: struct `TupleSkipAllDenyUnknown` is never constructed
       --> test_suite/tests/test_gen.rs:326:12
        |
    326 |     struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);
        |            ^^^^^^^^^^^^^^^^^^^^^^^

    warning: enum `EmptyEnum` is never used
       --> test_suite/tests/test_gen.rs:329:10
        |
    329 |     enum EmptyEnum {}
        |          ^^^^^^^^^

    warning: enum `EmptyEnumDenyUnknown` is never used
       --> test_suite/tests/test_gen.rs:333:10
        |
    333 |     enum EmptyEnumDenyUnknown {}
        |          ^^^^^^^^^^^^^^^^^^^^

    warning: enum `EnumSkipAll` is never used
       --> test_suite/tests/test_gen.rs:336:10
        |
    336 |     enum EnumSkipAll {
        |          ^^^^^^^^^^^

    warning: enum `EmptyVariants` is never used
       --> test_suite/tests/test_gen.rs:343:10
        |
    343 |     enum EmptyVariants {
        |          ^^^^^^^^^^^^^

    warning: enum `EmptyVariantsDenyUnknown` is never used
       --> test_suite/tests/test_gen.rs:355:10
        |
    355 |     enum EmptyVariantsDenyUnknown {
        |          ^^^^^^^^^^^^^^^^^^^^^^^^

    warning: struct `UnitDenyUnknown` is never constructed
       --> test_suite/tests/test_gen.rs:367:12
        |
    367 |     struct UnitDenyUnknown;
        |            ^^^^^^^^^^^^^^^

    warning: struct `EmptyArray` is never constructed
       --> test_suite/tests/test_gen.rs:370:12
        |
    370 |     struct EmptyArray {
        |            ^^^^^^^^^^

    warning: enum `Or` is never used
       --> test_suite/tests/test_gen.rs:374:10
        |
    374 |     enum Or<A, B> {
        |          ^^

    warning: enum `OrDef` is never used
       --> test_suite/tests/test_gen.rs:381:10
        |
    381 |     enum OrDef<A, B> {
        |          ^^^^^

    warning: struct `Str` is never constructed
       --> test_suite/tests/test_gen.rs:386:12
        |
    386 |     struct Str<'a>(&'a str);
        |            ^^^

    warning: struct `StrDef` is never constructed
       --> test_suite/tests/test_gen.rs:390:12
        |
    390 |     struct StrDef<'a>(&'a str);
        |            ^^^^^^

    warning: struct `Remote` is never constructed
       --> test_suite/tests/test_gen.rs:393:12
        |
    393 |     struct Remote<'a> {
        |            ^^^^^^

    warning: enum `BorrowVariant` is never used
       --> test_suite/tests/test_gen.rs:401:10
        |
    401 |     enum BorrowVariant<'a> {
        |          ^^^^^^^^^^^^^

    warning: struct `RemoteVisibility` is never constructed
       --> test_suite/tests/test_gen.rs:418:12
        |
    418 |     struct RemoteVisibility {
        |            ^^^^^^^^^^^^^^^^

    warning: struct `FlattenDenyUnknown` is never constructed
       --> test_suite/tests/test_gen.rs:551:12
        |
    551 |     struct FlattenDenyUnknown<T> {
        |            ^^^^^^^^^^^^^^^^^^

    warning: struct `StaticStrStruct` is never constructed
       --> test_suite/tests/test_gen.rs:557:12
        |
    557 |     struct StaticStrStruct<'a> {
        |            ^^^^^^^^^^^^^^^

    warning: struct `StaticStrTupleStruct` is never constructed
       --> test_suite/tests/test_gen.rs:563:12
        |
    563 |     struct StaticStrTupleStruct<'a>(&'a str, &'static str);
        |            ^^^^^^^^^^^^^^^^^^^^

    warning: struct `StaticStrNewtypeStruct` is never constructed
       --> test_suite/tests/test_gen.rs:566:12
        |
    566 |     struct StaticStrNewtypeStruct(&'static str);
        |            ^^^^^^^^^^^^^^^^^^^^^^

    warning: enum `StaticStrEnum` is never used
       --> test_suite/tests/test_gen.rs:569:10
        |
    569 |     enum StaticStrEnum<'a> {
        |          ^^^^^^^^^^^^^

    warning: enum `AdjacentlyTaggedVoid` is never used
       --> test_suite/tests/test_gen.rs:652:10
        |
    652 |     enum AdjacentlyTaggedVoid {}
        |          ^^^^^^^^^^^^^^^^^^^^

    warning: struct `ImplicitlyBorrowedOption` is never constructed
       --> test_suite/tests/test_gen.rs:665:12
        |
    665 |     struct ImplicitlyBorrowedOption<'a> {
        |            ^^^^^^^^^^^^^^^^^^^^^^^^

    warning: enum `UntaggedNewtypeVariantWith` is never used
       --> test_suite/tests/test_gen.rs:672:10
        |
    672 |     enum UntaggedNewtypeVariantWith {
        |          ^^^^^^^^^^^^^^^^^^^^^^^^^^

    warning: struct `TransparentWith` is never constructed
       --> test_suite/tests/test_gen.rs:682:12
        |
    682 |     struct TransparentWith {
        |            ^^^^^^^^^^^^^^^

    warning: struct `FlattenSkipSerializing` is never constructed
       --> test_suite/tests/test_gen.rs:712:12
        |
    712 |     struct FlattenSkipSerializing<T> {
        |            ^^^^^^^^^^^^^^^^^^^^^^

    warning: struct `FlattenSkipSerializingIf` is never constructed
       --> test_suite/tests/test_gen.rs:719:12
        |
    719 |     struct FlattenSkipSerializingIf<T> {
        |            ^^^^^^^^^^^^^^^^^^^^^^^^

    warning: struct `FlattenSkipDeserializing` is never constructed
       --> test_suite/tests/test_gen.rs:725:12
        |
    725 |     struct FlattenSkipDeserializing<T> {
        |            ^^^^^^^^^^^^^^^^^^^^^^^^

    warning: enum `Message` is never used
       --> test_suite/tests/test_gen.rs:732:10
        |
    732 |     enum Message {
        |          ^^^^^^^

    warning: struct `MacroRules` is never constructed
       --> test_suite/tests/test_gen.rs:751:20
        |
    751 |             struct MacroRules<'a> {
        |                    ^^^^^^^^^^
    ...
    758 |     deriving!(&'a str);
        |     ------------------ in this macro invocation
        |
        = note: this warning originates in the macro `deriving` (in Nightly builds, run with -Z macro-backtrace for more info)

    warning: struct `BorrowLifetimeInsideMacro` is never constructed
       --> test_suite/tests/test_gen.rs:767:12
        |
    767 |     struct BorrowLifetimeInsideMacro<'a> {
        |            ^^^^^^^^^^^^^^^^^^^^^^^^^

    warning: struct `GenericUnitStruct` is never constructed
       --> test_suite/tests/test_gen.rs:782:12
        |
    782 |     struct GenericUnitStruct<const N: usize>;
        |            ^^^^^^^^^^^^^^^^^

    warning: enum `InternallyTagged` is never used
       --> test_suite/tests/test_gen.rs:869:6
        |
    869 | enum InternallyTagged {
        |      ^^^^^^^^^^^^^^^^

    warning: function `deserialize_generic` is never used
       --> test_suite/tests/test_gen.rs:880:4
        |
    880 | fn deserialize_generic<'de, T, D>(deserializer: D) -> StdResult<T, D::Error>
        |    ^^^^^^^^^^^^^^^^^^^

    warning: struct `Restricted` is never constructed
       --> test_suite/tests/test_gen.rs:643:20
        |
    643 |             struct Restricted {
        |                    ^^^^^^^^^^

    warning: struct `Test` is never constructed
      --> test_suite/tests/test_remote.rs:95:8
       |
    95 | struct Test {
       |        ^^^^

    warning: struct `UnitDef` is never constructed
       --> test_suite/tests/test_remote.rs:135:8
        |
    135 | struct UnitDef;
        |        ^^^^^^^

    warning: struct `PrimitivePubDef` is never constructed
       --> test_suite/tests/test_remote.rs:143:8
        |
    143 | struct PrimitivePubDef(u8);
        |        ^^^^^^^^^^^^^^^

    warning: struct `NewtypePubDef` is never constructed
       --> test_suite/tests/test_remote.rs:151:8
        |
    151 | struct NewtypePubDef(#[serde(with = "UnitDef")] remote::Unit);
        |        ^^^^^^^^^^^^^

    warning: struct `TuplePubDef` is never constructed
       --> test_suite/tests/test_remote.rs:162:8
        |
    162 | struct TuplePubDef(u8, #[serde(with = "UnitDef")] remote::Unit);
        |        ^^^^^^^^^^^

    warning: struct `StructPubDef` is never constructed
       --> test_suite/tests/test_remote.rs:177:8
        |
    177 | struct StructPubDef {
        |        ^^^^^^^^^^^^

    warning: struct `StructConcrete` is never constructed
       --> test_suite/tests/test_remote.rs:193:8
        |
    193 | struct StructConcrete {
        |        ^^^^^^^^^^^^^^

    warning: enum `EnumConcrete` is never used
       --> test_suite/tests/test_remote.rs:199:6
        |
    199 | enum EnumConcrete {
        |      ^^^^^^^^^^^^

    warning: enum `ErrorKind` is never used
       --> test_suite/tests/test_remote.rs:204:6
        |
    204 | enum ErrorKind {
        |      ^^^^^^^^^

    warning: enum `ErrorKindDef` is never used
       --> test_suite/tests/test_remote.rs:214:6
        |
    214 | enum ErrorKindDef {
        |      ^^^^^^^^^^^^

    warning: struct `PrimitivePub` is never constructed
      --> test_suite/tests/test_remote.rs:10:16
       |
    10 |     pub struct PrimitivePub(pub u8);
       |                ^^^^^^^^^^^^

    warning: struct `NewtypePub` is never constructed
      --> test_suite/tests/test_remote.rs:14:16
       |
    14 |     pub struct NewtypePub(pub Unit);
       |                ^^^^^^^^^^

    warning: struct `TuplePub` is never constructed
      --> test_suite/tests/test_remote.rs:18:16
       |
    18 |     pub struct TuplePub(pub u8, pub Unit);
       |                ^^^^^^^^

    warning: struct `StructPub` is never constructed
      --> test_suite/tests/test_remote.rs:25:16
       |
    25 |     pub struct StructPub {
       |                ^^^^^^^^^

    warning: enum `EnumGeneric` is never used
      --> test_suite/tests/test_remote.rs:89:14
       |
    89 |     pub enum EnumGeneric<T> {
       |              ^^^^^^^^^^^

    warning: struct `Tuple` is never constructed
      --> test_suite/tests/test_self.rs:44:12
       |
    44 |     struct Tuple(
       |            ^^^^^

    warning: associated items `ASSOC` and `assoc` are never used
      --> test_suite/tests/test_self.rs:52:15
       |
    51 |     impl Tuple {
       |     ---------- associated items in this implementation
    52 |         const ASSOC: usize = 1;
       |               ^^^^^
    53 |         const fn assoc() -> usize {
       |                  ^^^^^

    warning: enum `Enum` is never used
      --> test_suite/tests/test_self.rs:63:10
       |
    63 |     enum Enum {
       |          ^^^^

    warning: associated items `ASSOC` and `assoc` are never used
      --> test_suite/tests/test_self.rs:79:15
       |
    78 |     impl Enum {
       |     --------- associated items in this implementation
    79 |         const ASSOC: usize = 1;
       |               ^^^^^
    80 |         const fn assoc() -> usize {
       |                  ^^^^^

    warning: struct `Unit` is never constructed
      --> test_suite/no_std/src/main.rs:26:8
       |
    26 | struct Unit;
       |        ^^^^

    warning: struct `Newtype` is never constructed
      --> test_suite/no_std/src/main.rs:29:8
       |
    29 | struct Newtype(u8);
       |        ^^^^^^^

    warning: struct `Tuple` is never constructed
      --> test_suite/no_std/src/main.rs:32:8
       |
    32 | struct Tuple(u8, u8);
       |        ^^^^^

    warning: struct `Struct` is never constructed
      --> test_suite/no_std/src/main.rs:35:8
       |
    35 | struct Struct {
       |        ^^^^^^

    warning: enum `Enum` is never used
      --> test_suite/no_std/src/main.rs:40:6
       |
    40 | enum Enum {
       |      ^^^^
2024-07-06 19:26:29 -07:00
David Tolnay 18dcae0a77 Release 1.0.204 2024-07-06 13:38:01 -07:00
David Tolnay 58c307f9cc Alphabetize list of rustc-check-cfg 2024-07-06 13:37:24 -07:00
David Tolnay 8cc4809414 Merge pull request #2769 from dtolnay/onunimpl
Add ui test of unsatisfied serde trait bound
2024-07-06 13:33:50 -07:00
David Tolnay 1179158def Update ui test with diagnostic::on_unimplemented from PR 2767 2024-07-06 13:29:51 -07:00
David Tolnay 91aa40e749 Add ui test of unsatisfied serde trait bound 2024-07-06 13:29:50 -07:00
David Tolnay 595019e979 Cut test_suite from workspace members in old toolchain CI jobs
The test suite's dependencies cannot be resolved by an old toolchain.

    error: failed to select a version for the requirement `toml = "^0.8"`
    candidate versions found which didn't match: 0.5.11, 0.5.10, 0.5.9, ...
    location searched: crates.io index
    required by package `trybuild v1.0.97`
        ... which satisfies dependency `trybuild = "^1.0.97"` of package `serde_test_suite v0.0.0`
2024-07-06 13:25:55 -07:00
David Tolnay b0d7917f88 Pull in trybuild 'following types implement trait' fix 2024-07-06 13:13:32 -07:00
David Tolnay 8e6637a1e4 Merge pull request #2767 from weiznich/feature/diagnostic_on_unimplemented
Use the `#[diagnostic::on_unimplemented]` attribute when possible
2024-07-06 10:29:08 -07:00
Georg Semmler 694fe05953 Use the #[diagnostic::on_unimplemented] attribute when possible
This change enables the `#[diagnostic::on_unimplemented]` attribute for
the `Serialize` and `Deserialize` trait to point the user to the
relevant derives and point out that they might want to check crates
features for external types by adding the relevant hints an note.
2024-07-02 16:39:06 +02:00
David Tolnay f3dfd2a237 Suppress dead code warning in test of unit struct remote derive
error: struct `RemoteSelf` is never constructed
       --> test_suite/tests/test_gen.rs:425:12
        |
    425 |     struct RemoteSelf;
        |            ^^^^^^^^^^
        |
    note: the lint level is defined here
       --> test_suite/tests/test_gen.rs:5:9
        |
    5   | #![deny(warnings)]
        |         ^^^^^^^^
        = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]`
2024-06-26 19:41:25 -07:00
David Tolnay 9e6158e9e6 Nightly no longer requires error_in_core feature
warning: the feature `error_in_core` has been stable since 1.81.0-nightly and no longer requires an attribute to enable
       --> serde/src/lib.rs:108:43
        |
    108 | #![cfg_attr(feature = "unstable", feature(error_in_core, never_type))]
        |                                           ^^^^^^^^^^^^^
        |
        = note: `#[warn(stable_features)]` on by default
2024-06-10 09:47:24 -07:00
David Tolnay d577c4a2ce Merge pull request #2754 from bm-w/master
Fix missing close paren in crates-io.md
2024-06-06 21:32:01 -07:00
Bastiaan Marinus van de Weerd fee0b82a40 Fix missing close paren in crates-io.md 2024-06-06 23:19:04 -04:00
David Tolnay 7aafa26314 Fill in ignore reasons in all #[ignore] attributes 2024-06-01 22:13:43 -07:00
David Tolnay d5bc546ca5 Release 1.0.203 2024-05-25 10:43:27 -07:00
David Tolnay 45ae217728 Merge pull request #2747 from dtolnay/variadic
Document tuple impls as fake variadic
2024-05-25 10:15:58 -07:00
David Tolnay b7b97dda73 Unindent implementation inside tuple_impl_body macro 2024-05-25 10:11:45 -07:00
David Tolnay 5d3c563d46 Document tuple impls as fake variadic 2024-05-25 10:11:04 -07:00
David Tolnay 376185458b Merge pull request #2745 from dtolnay/docsrs
Rely on docs.rs to define --cfg=docsrs by default
2024-05-18 21:25:44 -07:00
David Tolnay a8f14840ab Rely on docs.rs to define --cfg=docsrs by default 2024-05-18 21:16:37 -07:00
David Tolnay 9e32a40b1c Release 1.0.202 2024-05-15 00:42:49 -07:00
David Tolnay 87f635e54d Release serde_derive_internals 0.29.1 2024-05-15 00:35:14 -07:00
David Tolnay d4b2dfbde2 Merge pull request #2743 from dtolnay/renameallrules
Provide public access to RenameAllRules in serde_derive_internals
2024-05-15 00:34:38 -07:00
David Tolnay f6ab0bc56f Provide public access to RenameAllRules in serde_derive_internals 2024-05-15 00:30:55 -07:00
David Tolnay 48cc2a6327 Replace use of a syn From impl
The From impls may be going away in the next version of syn.
2024-05-14 23:02:28 -07:00
David Tolnay 3202a6858a Skip rerunning build script on library code changes 2024-05-08 21:59:41 -07:00
34 changed files with 693 additions and 280 deletions
+3
View File
@@ -84,6 +84,7 @@ jobs:
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
- run: sed -i '/"test_suite"/d' Cargo.toml
- run: cd serde && cargo build --features rc
- run: cd serde && cargo build --no-default-features
- run: cd serde && cargo build
@@ -95,6 +96,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.56.0
- run: sed -i '/"test_suite"/d' Cargo.toml
- run: cd serde && cargo check --no-default-features
- run: cd serde && cargo check
- run: cd serde_derive && cargo check
@@ -106,6 +108,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.36.0
- run: sed -i '/"test_suite"/d' Cargo.toml
- run: cd serde && cargo build --no-default-features --features alloc
minimal:
+2 -2
View File
@@ -46,8 +46,8 @@ fn main() {
Serde is one of the most widely used Rust libraries so any place that Rustaceans
congregate will be able to help you out. For chat, consider trying the
[#rust-questions] or [#rust-beginners] channels of the unofficial community
Discord (invite: <https://discord.gg/rust-lang-community>, the [#rust-usage] or
[#beginners] channels of the official Rust Project Discord (invite:
Discord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage]
or [#beginners] channels of the official Rust Project Discord (invite:
<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.201"
version = "1.0.206"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs"
categories = ["encoding", "no-std", "no-std::no-alloc"]
@@ -29,7 +29,7 @@ features = ["derive", "rc"]
[package.metadata.docs.rs]
features = ["derive", "rc", "unstable"]
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = ["--cfg", "doc_cfg", "--generate-link-to-definition"]
rustdoc-args = ["--generate-link-to-definition"]
# This cfg cannot be enabled, but it still forces Cargo to keep serde_derive's
# version in lockstep with serde's, even if someone depends on the two crates
@@ -37,7 +37,7 @@ rustdoc-args = ["--cfg", "doc_cfg", "--generate-link-to-definition"]
# is compatible with exactly one serde release because the generated code
# involves nonpublic APIs which are not bound by semver.
[target.'cfg(any())'.dependencies]
serde_derive = { version = "=1.0.201", path = "../serde_derive" }
serde_derive = { version = "=1.0.206", path = "../serde_derive" }
### FEATURES #################################################################
+7 -1
View File
@@ -14,10 +14,10 @@ fn main() {
};
if minor >= 77 {
println!("cargo:rustc-check-cfg=cfg(doc_cfg)");
println!("cargo:rustc-check-cfg=cfg(no_core_cstr)");
println!("cargo:rustc-check-cfg=cfg(no_core_num_saturating)");
println!("cargo:rustc-check-cfg=cfg(no_core_try_from)");
println!("cargo:rustc-check-cfg=cfg(no_diagnostic_namespace)");
println!("cargo:rustc-check-cfg=cfg(no_float_copysign)");
println!("cargo:rustc-check-cfg=cfg(no_num_nonzero_signed)");
println!("cargo:rustc-check-cfg=cfg(no_relaxed_trait_bounds)");
@@ -85,6 +85,12 @@ fn main() {
if minor < 74 {
println!("cargo:rustc-cfg=no_core_num_saturating");
}
// Support for the `#[diagnostic]` tool attribute namespace
// https://blog.rust-lang.org/2024/05/02/Rust-1.78.0.html#diagnostic-attributes
if minor < 78 {
println!("cargo:rustc-cfg=no_diagnostic_namespace");
}
}
fn rustc_minor_version() -> Option<u32> {
+127 -106
View File
@@ -39,7 +39,7 @@ impl<'de> Deserialize<'de> for () {
}
#[cfg(feature = "unstable")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "unstable")))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<'de> Deserialize<'de> for ! {
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
where
@@ -695,7 +695,7 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
impl<'de> Deserialize<'de> for String {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -839,7 +839,7 @@ impl<'de> Visitor<'de> for CStringVisitor {
}
#[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
impl<'de> Deserialize<'de> for CString {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -868,7 +868,7 @@ macro_rules! forwarded_impl {
forwarded_impl! {
#[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
(), Box<CStr>, CString::into_boxed_c_str
}
@@ -1086,7 +1086,7 @@ fn nop_reserve<T>(_seq: T, _n: usize) {}
seq_impl!(
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
BinaryHeap<T: Ord>,
seq,
BinaryHeap::clear,
@@ -1097,7 +1097,7 @@ seq_impl!(
seq_impl!(
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
BTreeSet<T: Eq + Ord>,
seq,
BTreeSet::clear,
@@ -1108,7 +1108,7 @@ seq_impl!(
seq_impl!(
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
LinkedList<T>,
seq,
LinkedList::clear,
@@ -1119,7 +1119,7 @@ seq_impl!(
seq_impl!(
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
HashSet<T: Eq + Hash, S: BuildHasher + Default>,
seq,
HashSet::clear,
@@ -1130,7 +1130,7 @@ seq_impl!(
seq_impl!(
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
VecDeque<T>,
seq,
VecDeque::clear,
@@ -1142,7 +1142,7 @@ seq_impl!(
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
impl<'de, T> Deserialize<'de> for Vec<T>
where
T: Deserialize<'de>,
@@ -1393,82 +1393,103 @@ array_impls! {
macro_rules! tuple_impls {
($($len:tt => ($($n:tt $name:ident)+))+) => {
$(
impl<'de, $($name: Deserialize<'de>),+> Deserialize<'de> for ($($name,)+) {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct TupleVisitor<$($name,)+> {
marker: PhantomData<($($name,)+)>,
}
impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<$($name,)+> {
type Value = ($($name,)+);
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(concat!("a tuple of size ", $len))
}
#[inline]
#[allow(non_snake_case)]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
$(
let $name = match tri!(seq.next_element()) {
Some(value) => value,
None => return Err(Error::invalid_length($n, &self)),
};
)+
Ok(($($name,)+))
}
}
deserializer.deserialize_tuple($len, TupleVisitor { marker: PhantomData })
}
#[inline]
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
where
D: Deserializer<'de>,
{
struct TupleInPlaceVisitor<'a, $($name: 'a,)+>(&'a mut ($($name,)+));
impl<'a, 'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleInPlaceVisitor<'a, $($name,)+> {
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(concat!("a tuple of size ", $len))
}
#[inline]
#[allow(non_snake_case)]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
$(
if tri!(seq.next_element_seed(InPlaceSeed(&mut (self.0).$n))).is_none() {
return Err(Error::invalid_length($n, &self));
}
)+
Ok(())
}
}
deserializer.deserialize_tuple($len, TupleInPlaceVisitor(place))
}
#[cfg_attr(docsrs, doc(hidden))]
impl<'de, $($name),+> Deserialize<'de> for ($($name,)+)
where
$($name: Deserialize<'de>,)+
{
tuple_impl_body!($len => ($($n $name)+));
}
)+
}
};
}
macro_rules! tuple_impl_body {
($len:tt => ($($n:tt $name:ident)+)) => {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct TupleVisitor<$($name,)+> {
marker: PhantomData<($($name,)+)>,
}
impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<$($name,)+> {
type Value = ($($name,)+);
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(concat!("a tuple of size ", $len))
}
#[inline]
#[allow(non_snake_case)]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
$(
let $name = match tri!(seq.next_element()) {
Some(value) => value,
None => return Err(Error::invalid_length($n, &self)),
};
)+
Ok(($($name,)+))
}
}
deserializer.deserialize_tuple($len, TupleVisitor { marker: PhantomData })
}
#[inline]
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
where
D: Deserializer<'de>,
{
struct TupleInPlaceVisitor<'a, $($name: 'a,)+>(&'a mut ($($name,)+));
impl<'a, 'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleInPlaceVisitor<'a, $($name,)+> {
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(concat!("a tuple of size ", $len))
}
#[inline]
#[allow(non_snake_case)]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
$(
if tri!(seq.next_element_seed(InPlaceSeed(&mut (self.0).$n))).is_none() {
return Err(Error::invalid_length($n, &self));
}
)+
Ok(())
}
}
deserializer.deserialize_tuple($len, TupleInPlaceVisitor(place))
}
};
}
#[cfg_attr(docsrs, doc(fake_variadic))]
#[cfg_attr(
docsrs,
doc = "This trait is implemented for tuples up to 16 items long."
)]
impl<'de, T> Deserialize<'de> for (T,)
where
T: Deserialize<'de>,
{
tuple_impl_body!(1 => (0 T));
}
tuple_impls! {
1 => (0 T0)
2 => (0 T0 1 T1)
3 => (0 T0 1 T1 2 T2)
4 => (0 T0 1 T1 2 T2 3 T3)
@@ -1546,7 +1567,7 @@ macro_rules! map_impl {
map_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
BTreeMap<K: Ord, V>,
map,
BTreeMap::new(),
@@ -1554,7 +1575,7 @@ map_impl! {
map_impl! {
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
map,
HashMap::with_capacity_and_hasher(size_hint::cautious::<(K, V)>(map.size_hint()), S::default()),
@@ -1696,7 +1717,7 @@ macro_rules! deserialize_enum {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<'de> Deserialize<'de> for net::IpAddr {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1717,13 +1738,13 @@ impl<'de> Deserialize<'de> for net::IpAddr {
parse_ip_impl! {
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
net::Ipv4Addr, "IPv4 address", 4
}
parse_ip_impl! {
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
net::Ipv6Addr, "IPv6 address", 16
}
@@ -1750,7 +1771,7 @@ macro_rules! parse_socket_impl {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<'de> Deserialize<'de> for net::SocketAddr {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1771,14 +1792,14 @@ impl<'de> Deserialize<'de> for net::SocketAddr {
parse_socket_impl! {
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
net::SocketAddrV4, "IPv4 socket address",
|(ip, port)| net::SocketAddrV4::new(ip, port),
}
parse_socket_impl! {
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
net::SocketAddrV6, "IPv6 socket address",
|(ip, port)| net::SocketAddrV6::new(ip, port, 0, 0),
}
@@ -1814,7 +1835,7 @@ impl<'a> Visitor<'a> for PathVisitor {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<'de: 'a, 'a> Deserialize<'de> for &'a Path {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1869,7 +1890,7 @@ impl<'de> Visitor<'de> for PathBufVisitor {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<'de> Deserialize<'de> for PathBuf {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1881,7 +1902,7 @@ impl<'de> Deserialize<'de> for PathBuf {
forwarded_impl! {
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
(), Box<Path>, PathBuf::into_boxed_path
}
@@ -1943,7 +1964,7 @@ impl<'de> Visitor<'de> for OsStringVisitor {
}
#[cfg(all(feature = "std", any(unix, windows)))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))]
impl<'de> Deserialize<'de> for OsString {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1957,30 +1978,30 @@ impl<'de> Deserialize<'de> for OsString {
forwarded_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
(T), Box<T>, Box::new
}
forwarded_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
(T), Box<[T]>, Vec::into_boxed_slice
}
forwarded_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
(), Box<str>, String::into_boxed_str
}
forwarded_impl! {
#[cfg(all(feature = "std", any(unix, windows)))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))]
(), Box<OsStr>, OsString::into_boxed_os_str
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
impl<'de, 'a, T> Deserialize<'de> for Cow<'a, T>
where
T: ?Sized + ToOwned,
@@ -2003,7 +2024,7 @@ where
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg_attr(
doc_cfg,
docsrs,
doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc"))))
)]
impl<'de, T> Deserialize<'de> for RcWeak<T>
@@ -2025,7 +2046,7 @@ where
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg_attr(
doc_cfg,
docsrs,
doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc"))))
)]
impl<'de, T> Deserialize<'de> for ArcWeak<T>
@@ -2073,7 +2094,7 @@ box_forwarded_impl! {
///
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))]
Rc
}
@@ -2086,7 +2107,7 @@ box_forwarded_impl! {
///
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))]
Arc
}
@@ -2110,13 +2131,13 @@ forwarded_impl! {
forwarded_impl! {
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
(T), Mutex<T>, Mutex::new
}
forwarded_impl! {
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
(T), RwLock<T>, RwLock::new
}
@@ -2271,7 +2292,7 @@ impl<'de> Deserialize<'de> for Duration {
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<'de> Deserialize<'de> for SystemTime {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -3107,7 +3128,7 @@ macro_rules! atomic_impl {
($($ty:ident $size:expr)*) => {
$(
#[cfg(any(no_target_has_atomic, target_has_atomic = $size))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", target_has_atomic = $size))))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "std", target_has_atomic = $size))))]
impl<'de> Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
+9 -2
View File
@@ -532,6 +532,13 @@ impl<'a> Display for Expected + 'a {
/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
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",
)
)]
pub trait Deserialize<'de>: Sized {
/// Deserialize this value from the given Serde deserializer.
///
@@ -1525,7 +1532,7 @@ pub trait Visitor<'de>: Sized {
/// `String`.
#[inline]
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
@@ -1584,7 +1591,7 @@ pub trait Visitor<'de>: Sized {
/// The default implementation forwards to `visit_bytes` and then drops the
/// `Vec<u8>`.
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: Error,
+12 -12
View File
@@ -112,7 +112,7 @@ impl Debug for Error {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl error::Error for Error {
fn description(&self) -> &str {
&self.err
@@ -185,14 +185,14 @@ impl<E> Debug for UnitDeserializer<E> {
/// A deserializer that cannot be instantiated.
#[cfg(feature = "unstable")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "unstable")))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
pub struct NeverDeserializer<E> {
never: !,
marker: PhantomData<E>,
}
#[cfg(feature = "unstable")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "unstable")))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<'de, E> IntoDeserializer<'de, E> for !
where
E: de::Error,
@@ -565,7 +565,7 @@ impl<'de, E> Debug for BorrowedStrDeserializer<'de, E> {
/// A deserializer holding a `String`.
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
pub struct StringDeserializer<E> {
value: String,
marker: PhantomData<E>,
@@ -582,7 +582,7 @@ impl<E> Clone for StringDeserializer<E> {
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
impl<'de, E> IntoDeserializer<'de, E> for String
where
E: de::Error,
@@ -670,7 +670,7 @@ impl<E> Debug for StringDeserializer<E> {
/// A deserializer holding a `Cow<str>`.
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
pub struct CowStrDeserializer<'a, E> {
value: Cow<'a, str>,
marker: PhantomData<E>,
@@ -687,7 +687,7 @@ impl<'a, E> Clone for CowStrDeserializer<'a, E> {
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str>
where
E: de::Error,
@@ -1006,7 +1006,7 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
impl<'de, T, E> IntoDeserializer<'de, E> for Vec<T>
where
T: IntoDeserializer<'de, E>,
@@ -1020,7 +1020,7 @@ where
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
impl<'de, T, E> IntoDeserializer<'de, E> for BTreeSet<T>
where
T: IntoDeserializer<'de, E> + Eq + Ord,
@@ -1034,7 +1034,7 @@ where
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<'de, T, S, E> IntoDeserializer<'de, E> for HashSet<T, S>
where
T: IntoDeserializer<'de, E> + Eq + Hash,
@@ -1421,7 +1421,7 @@ impl Expected for ExpectedInMap {
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap<K, V>
where
K: IntoDeserializer<'de, E> + Eq + Ord,
@@ -1436,7 +1436,7 @@ where
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<'de, K, V, S, E> IntoDeserializer<'de, E> for HashMap<K, V, S>
where
K: IntoDeserializer<'de, E> + Eq + Hash,
+5 -4
View File
@@ -95,16 +95,17 @@
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.201")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.206")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Show which crate feature enables conditionally compiled APIs in documentation.
#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![cfg_attr(docsrs, feature(doc_cfg, rustdoc_internals))]
#![cfg_attr(docsrs, allow(internal_features))]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
// https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(error_in_core, never_type))]
#![cfg_attr(feature = "unstable", feature(never_type))]
#![allow(unknown_lints, bare_trait_objects, deprecated)]
// Ignored clippy and clippy_pedantic lints
#![allow(
@@ -330,7 +331,7 @@ extern crate serde_derive;
/// Derive macro available if serde is built with `features = ["derive"]`.
#[cfg(feature = "serde_derive")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
pub use serde_derive::{Deserialize, Serialize};
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
+1 -2
View File
@@ -1125,8 +1125,7 @@ where
where
T: ?Sized + Serialize,
{
tri!(self.0.serialize_key(variant));
self.0.serialize_value(value)
self.0.serialize_entry(variant, value)
}
fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+63 -45
View File
@@ -48,7 +48,7 @@ impl Serialize for str {
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
impl Serialize for String {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -71,7 +71,7 @@ impl<'a> Serialize for fmt::Arguments<'a> {
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", not(no_core_cstr)))]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl Serialize for CStr {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -83,7 +83,7 @@ impl Serialize for CStr {
}
#[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
impl Serialize for CString {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -232,37 +232,37 @@ macro_rules! seq_impl {
seq_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
BinaryHeap<T: Ord>
}
seq_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
BTreeSet<T: Ord>
}
seq_impl! {
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
HashSet<T: Eq + Hash, H: BuildHasher>
}
seq_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
LinkedList<T>
}
seq_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
Vec<T>
}
seq_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
VecDeque<T>
}
@@ -371,7 +371,7 @@ impl Serialize for () {
}
#[cfg(feature = "unstable")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "unstable")))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl Serialize for ! {
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
where
@@ -386,28 +386,46 @@ impl Serialize for ! {
macro_rules! tuple_impls {
($($len:expr => ($($n:tt $name:ident)+))+) => {
$(
#[cfg_attr(docsrs, doc(hidden))]
impl<$($name),+> Serialize for ($($name,)+)
where
$($name: Serialize,)+
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut tuple = tri!(serializer.serialize_tuple($len));
$(
tri!(tuple.serialize_element(&self.$n));
)+
tuple.end()
}
tuple_impl_body!($len => ($($n)+));
}
)+
}
};
}
macro_rules! tuple_impl_body {
($len:expr => ($($n:tt)+)) => {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut tuple = tri!(serializer.serialize_tuple($len));
$(
tri!(tuple.serialize_element(&self.$n));
)+
tuple.end()
}
};
}
#[cfg_attr(docsrs, doc(fake_variadic))]
#[cfg_attr(
docsrs,
doc = "This trait is implemented for tuples up to 16 items long."
)]
impl<T> Serialize for (T,)
where
T: Serialize,
{
tuple_impl_body!(1 => (0));
}
tuple_impls! {
1 => (0 T0)
2 => (0 T0 1 T1)
3 => (0 T0 1 T1 2 T2)
4 => (0 T0 1 T1 2 T2 3 T3)
@@ -476,13 +494,13 @@ macro_rules! map_impl {
map_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
BTreeMap<K: Ord, V>
}
map_impl! {
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
HashMap<K: Eq + Hash, V, H: BuildHasher>
}
@@ -516,7 +534,7 @@ deref_impl! {
deref_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
<T> Serialize for Box<T> where T: ?Sized + Serialize
}
@@ -530,7 +548,7 @@ deref_impl! {
///
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))]
<T> Serialize for Rc<T> where T: ?Sized + Serialize
}
@@ -544,13 +562,13 @@ deref_impl! {
///
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))]
<T> Serialize for Arc<T> where T: ?Sized + Serialize
}
deref_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "alloc"))))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
<'a, T> Serialize for Cow<'a, T> where T: ?Sized + Serialize + ToOwned
}
@@ -561,7 +579,7 @@ deref_impl! {
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg_attr(
doc_cfg,
docsrs,
doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc"))))
)]
impl<T> Serialize for RcWeak<T>
@@ -581,7 +599,7 @@ where
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg_attr(
doc_cfg,
docsrs,
doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc"))))
)]
impl<T> Serialize for ArcWeak<T>
@@ -660,7 +678,7 @@ where
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<T> Serialize for Mutex<T>
where
T: ?Sized + Serialize,
@@ -677,7 +695,7 @@ where
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<T> Serialize for RwLock<T>
where
T: ?Sized + Serialize,
@@ -731,7 +749,7 @@ impl Serialize for Duration {
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl Serialize for SystemTime {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -776,7 +794,7 @@ macro_rules! serialize_display_bounded_length {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl Serialize for net::IpAddr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -847,7 +865,7 @@ fn test_format_u8() {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl Serialize for net::Ipv4Addr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -872,7 +890,7 @@ impl Serialize for net::Ipv4Addr {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl Serialize for net::Ipv6Addr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -889,7 +907,7 @@ impl Serialize for net::Ipv6Addr {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl Serialize for net::SocketAddr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -914,7 +932,7 @@ impl Serialize for net::SocketAddr {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl Serialize for net::SocketAddrV4 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -931,7 +949,7 @@ impl Serialize for net::SocketAddrV4 {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl Serialize for net::SocketAddrV6 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -953,7 +971,7 @@ impl Serialize for net::SocketAddrV6 {
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl Serialize for Path {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -967,7 +985,7 @@ impl Serialize for Path {
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl Serialize for PathBuf {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -978,7 +996,7 @@ impl Serialize for PathBuf {
}
#[cfg(all(feature = "std", any(unix, windows)))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))]
impl Serialize for OsStr {
#[cfg(unix)]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -1001,7 +1019,7 @@ impl Serialize for OsStr {
}
#[cfg(all(feature = "std", any(unix, windows)))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", any(unix, windows)))))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))]
impl Serialize for OsString {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -1060,7 +1078,7 @@ macro_rules! atomic_impl {
($($ty:ident $size:expr)*) => {
$(
#[cfg(any(no_target_has_atomic, target_has_atomic = $size))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", target_has_atomic = $size))))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "std", target_has_atomic = $size))))]
impl Serialize for $ty {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
+7
View File
@@ -215,6 +215,13 @@ declare_error_trait!(Error: Sized + Debug + Display);
/// [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
/// [`serde_derive`]: https://crates.io/crates/serde_derive
/// [derive section of the manual]: https://serde.rs/derive.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
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",
)
)]
pub trait Serialize {
/// Serialize this value into the given Serde serializer.
///
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.201"
version = "1.0.206"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
categories = ["no-std", "no-std::no-alloc"]
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
+1
View File
@@ -1,6 +1,7 @@
fn main() {
// Warning: build.rs is not published to crates.io.
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rustc-cfg=check_cfg");
println!("cargo:rustc-check-cfg=cfg(check_cfg)");
println!("cargo:rustc-check-cfg=cfg(exhaustive)");
+62 -31
View File
@@ -281,11 +281,21 @@ fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment {
} else if let attr::Identifier::No = cont.attrs.identifier() {
match &cont.data {
Data::Enum(variants) => deserialize_enum(params, variants, &cont.attrs),
Data::Struct(Style::Struct, fields) => {
deserialize_struct(params, fields, &cont.attrs, StructForm::Struct)
}
Data::Struct(Style::Struct, fields) => deserialize_struct(
params,
fields,
&cont.attrs,
cont.attrs.has_flatten(),
StructForm::Struct,
),
Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => {
deserialize_tuple(params, fields, &cont.attrs, TupleForm::Tuple)
deserialize_tuple(
params,
fields,
&cont.attrs,
cont.attrs.has_flatten(),
TupleForm::Tuple,
)
}
Data::Struct(Style::Unit, _) => deserialize_unit_struct(params, &cont.attrs),
}
@@ -459,9 +469,13 @@ fn deserialize_tuple(
params: &Parameters,
fields: &[Field],
cattrs: &attr::Container,
has_flatten: bool,
form: TupleForm,
) -> Fragment {
assert!(!cattrs.has_flatten());
assert!(
!has_flatten,
"tuples and tuple variants cannot have flatten fields"
);
let field_count = fields
.iter()
@@ -579,7 +593,10 @@ fn deserialize_tuple_in_place(
fields: &[Field],
cattrs: &attr::Container,
) -> Fragment {
assert!(!cattrs.has_flatten());
assert!(
!cattrs.has_flatten(),
"tuples and tuple variants cannot have flatten fields"
);
let field_count = fields
.iter()
@@ -910,6 +927,7 @@ fn deserialize_struct(
params: &Parameters,
fields: &[Field],
cattrs: &attr::Container,
has_flatten: bool,
form: StructForm,
) -> Fragment {
let this_type = &params.this_type;
@@ -958,13 +976,13 @@ fn deserialize_struct(
)
})
.collect();
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs);
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs, has_flatten);
// untagged struct variants do not get a visit_seq method. The same applies to
// structs that only have a map representation.
let visit_seq = match form {
StructForm::Untagged(..) => None,
_ if cattrs.has_flatten() => None,
_ if has_flatten => None,
_ => {
let mut_seq = if field_names_idents.is_empty() {
quote!(_)
@@ -987,10 +1005,16 @@ fn deserialize_struct(
})
}
};
let visit_map = Stmts(deserialize_map(&type_path, params, fields, cattrs));
let visit_map = Stmts(deserialize_map(
&type_path,
params,
fields,
cattrs,
has_flatten,
));
let visitor_seed = match form {
StructForm::ExternallyTagged(..) if cattrs.has_flatten() => Some(quote! {
StructForm::ExternallyTagged(..) if has_flatten => Some(quote! {
impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause {
type Value = #this_type #ty_generics;
@@ -1005,7 +1029,7 @@ fn deserialize_struct(
_ => None,
};
let fields_stmt = if cattrs.has_flatten() {
let fields_stmt = if has_flatten {
None
} else {
let field_names = field_names_idents
@@ -1025,7 +1049,7 @@ fn deserialize_struct(
}
};
let dispatch = match form {
StructForm::Struct if cattrs.has_flatten() => quote! {
StructForm::Struct if has_flatten => quote! {
_serde::Deserializer::deserialize_map(__deserializer, #visitor_expr)
},
StructForm::Struct => {
@@ -1034,7 +1058,7 @@ fn deserialize_struct(
_serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
}
}
StructForm::ExternallyTagged(_) if cattrs.has_flatten() => quote! {
StructForm::ExternallyTagged(_) if has_flatten => quote! {
_serde::de::VariantAccess::newtype_variant_seed(__variant, #visitor_expr)
},
StructForm::ExternallyTagged(_) => quote! {
@@ -1116,7 +1140,7 @@ fn deserialize_struct_in_place(
})
.collect();
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs);
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs, false);
let mut_seq = if field_names_idents.is_empty() {
quote!(_)
@@ -1210,10 +1234,7 @@ fn deserialize_homogeneous_enum(
}
}
fn prepare_enum_variant_enum(
variants: &[Variant],
cattrs: &attr::Container,
) -> (TokenStream, Stmts) {
fn prepare_enum_variant_enum(variants: &[Variant]) -> (TokenStream, Stmts) {
let mut deserialized_variants = variants
.iter()
.enumerate()
@@ -1247,7 +1268,7 @@ fn prepare_enum_variant_enum(
let variant_visitor = Stmts(deserialize_generated_identifier(
&variant_names_idents,
cattrs,
false, // variant identifiers do not depend on the presence of flatten fields
true,
None,
fallthrough,
@@ -1270,7 +1291,7 @@ fn deserialize_externally_tagged_enum(
let expecting = format!("enum {}", params.type_name());
let expecting = cattrs.expecting().unwrap_or(&expecting);
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants);
// Match arms to extract a variant from a string
let variant_arms = variants
@@ -1355,7 +1376,7 @@ fn deserialize_internally_tagged_enum(
cattrs: &attr::Container,
tag: &str,
) -> Fragment {
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants);
// Match arms to extract a variant from a string
let variant_arms = variants
@@ -1409,7 +1430,7 @@ fn deserialize_adjacently_tagged_enum(
split_with_de_lifetime(params);
let delife = params.borrowed.de_lifetime();
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants);
let variant_arms: &Vec<_> = &variants
.iter()
@@ -1810,12 +1831,14 @@ fn deserialize_externally_tagged_variant(
params,
&variant.fields,
cattrs,
variant.attrs.has_flatten(),
TupleForm::ExternallyTagged(variant_ident),
),
Style::Struct => deserialize_struct(
params,
&variant.fields,
cattrs,
variant.attrs.has_flatten(),
StructForm::ExternallyTagged(variant_ident),
),
}
@@ -1859,6 +1882,7 @@ fn deserialize_internally_tagged_variant(
params,
&variant.fields,
cattrs,
variant.attrs.has_flatten(),
StructForm::InternallyTagged(variant_ident, deserializer),
),
Style::Tuple => unreachable!("checked in serde_derive_internals"),
@@ -1909,12 +1933,14 @@ fn deserialize_untagged_variant(
params,
&variant.fields,
cattrs,
variant.attrs.has_flatten(),
TupleForm::Untagged(variant_ident, deserializer),
),
Style::Struct => deserialize_struct(
params,
&variant.fields,
cattrs,
variant.attrs.has_flatten(),
StructForm::Untagged(variant_ident, deserializer),
),
}
@@ -1985,7 +2011,7 @@ fn deserialize_untagged_newtype_variant(
fn deserialize_generated_identifier(
fields: &[(&str, Ident, &BTreeSet<String>)],
cattrs: &attr::Container,
has_flatten: bool,
is_variant: bool,
ignore_variant: Option<TokenStream>,
fallthrough: Option<TokenStream>,
@@ -1999,11 +2025,11 @@ fn deserialize_generated_identifier(
is_variant,
fallthrough,
None,
!is_variant && cattrs.has_flatten(),
!is_variant && has_flatten,
None,
));
let lifetime = if !is_variant && cattrs.has_flatten() {
let lifetime = if !is_variant && has_flatten {
Some(quote!(<'de>))
} else {
None
@@ -2043,8 +2069,9 @@ fn deserialize_generated_identifier(
fn deserialize_field_identifier(
fields: &[(&str, Ident, &BTreeSet<String>)],
cattrs: &attr::Container,
has_flatten: bool,
) -> Stmts {
let (ignore_variant, fallthrough) = if cattrs.has_flatten() {
let (ignore_variant, fallthrough) = if has_flatten {
let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),);
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
(Some(ignore_variant), Some(fallthrough))
@@ -2058,7 +2085,7 @@ fn deserialize_field_identifier(
Stmts(deserialize_generated_identifier(
fields,
cattrs,
has_flatten,
false,
ignore_variant,
fallthrough,
@@ -2460,6 +2487,7 @@ fn deserialize_map(
params: &Parameters,
fields: &[Field],
cattrs: &attr::Container,
has_flatten: bool,
) -> Fragment {
// Create the field names for the fields.
let fields_names: Vec<_> = fields
@@ -2480,7 +2508,7 @@ fn deserialize_map(
});
// Collect contents for flatten fields into a buffer
let let_collect = if cattrs.has_flatten() {
let let_collect = if has_flatten {
Some(quote! {
let mut __collect = _serde::__private::Vec::<_serde::__private::Option<(
_serde::__private::de::Content,
@@ -2532,7 +2560,7 @@ fn deserialize_map(
});
// Visit ignored values to consume them
let ignored_arm = if cattrs.has_flatten() {
let ignored_arm = if has_flatten {
Some(quote! {
__Field::__other(__name) => {
__collect.push(_serde::__private::Some((
@@ -2602,7 +2630,7 @@ fn deserialize_map(
}
});
let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() {
let collected_deny_unknown_fields = if has_flatten && cattrs.deny_unknown_fields() {
Some(quote! {
if let _serde::__private::Some(_serde::__private::Some((__key, _))) =
__collect.into_iter().filter(_serde::__private::Option::is_some).next()
@@ -2678,7 +2706,10 @@ fn deserialize_map_in_place(
fields: &[Field],
cattrs: &attr::Container,
) -> Fragment {
assert!(!cattrs.has_flatten());
assert!(
!cattrs.has_flatten(),
"inplace deserialization of maps does not support flatten fields"
);
// Create the field names for the fields.
let fields_names: Vec<_> = fields
+1
View File
@@ -85,6 +85,7 @@ impl<'a> Container<'a> {
for field in &mut variant.fields {
if field.attrs.flatten() {
has_flatten = true;
variant.attrs.mark_has_flatten();
}
field.attrs.rename_by_rules(
variant
+39 -2
View File
@@ -185,8 +185,8 @@ impl Name {
#[derive(Copy, Clone)]
pub struct RenameAllRules {
serialize: RenameRule,
deserialize: RenameRule,
pub serialize: RenameRule,
pub deserialize: RenameRule,
}
impl RenameAllRules {
@@ -216,6 +216,22 @@ pub struct Container {
type_into: Option<syn::Type>,
remote: Option<syn::Path>,
identifier: Identifier,
/// True if container is a struct and has a field with `#[serde(flatten)]`,
/// or is an enum with a struct variant which has a field with
/// `#[serde(flatten)]`.
///
/// ```ignore
/// struct Container {
/// #[serde(flatten)]
/// some_field: (),
/// }
/// enum Container {
/// Variant {
/// #[serde(flatten)]
/// some_field: (),
/// },
/// }
/// ```
has_flatten: bool,
serde_path: Option<syn::Path>,
is_packed: bool,
@@ -794,6 +810,18 @@ pub struct Variant {
rename_all_rules: RenameAllRules,
ser_bound: Option<Vec<syn::WherePredicate>>,
de_bound: Option<Vec<syn::WherePredicate>>,
/// True if variant is a struct variant which contains a field with
/// `#[serde(flatten)]`.
///
/// ```ignore
/// enum Enum {
/// Variant {
/// #[serde(flatten)]
/// some_field: (),
/// },
/// }
/// ```
has_flatten: bool,
skip_deserializing: bool,
skip_serializing: bool,
other: bool,
@@ -963,6 +991,7 @@ impl Variant {
},
ser_bound: ser_bound.get(),
de_bound: de_bound.get(),
has_flatten: false,
skip_deserializing: skip_deserializing.get(),
skip_serializing: skip_serializing.get(),
other: other.get(),
@@ -1005,6 +1034,14 @@ impl Variant {
self.de_bound.as_ref().map(|vec| &vec[..])
}
pub fn has_flatten(&self) -> bool {
self.has_flatten
}
pub fn mark_has_flatten(&mut self) {
self.has_flatten = true;
}
pub fn skip_deserializing(&self) -> bool {
self.skip_deserializing
}
+1 -1
View File
@@ -84,7 +84,7 @@ impl ReplaceReceiver<'_> {
self.visit_type_mut_impl(ty);
return;
};
*ty = self.self_ty(span).into();
*ty = Type::Path(self.self_ty(span));
}
// `Self::Assoc` -> `<Receiver>::Assoc`
+1 -1
View File
@@ -13,7 +13,7 @@
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.201")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.206")]
#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
// Ignored clippy lints
#![allow(
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive_internals"
version = "0.29.0"
version = "0.29.1"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
description = "AST representation used by Serde derive macros. Unstable."
documentation = "https://docs.rs/serde_derive_internals"
+1 -1
View File
@@ -1,4 +1,4 @@
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.29.0")]
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.29.1")]
#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
// Ignored clippy lints
#![allow(
+1 -1
View File
@@ -18,4 +18,4 @@ rustversion = "1.0"
serde = { path = "../serde", features = ["rc"] }
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
serde_test = "1.0.176"
trybuild = { version = "1.0.66", features = ["diff"] }
trybuild = { version = "1.0.97", features = ["diff"] }
+5 -5
View File
@@ -23,21 +23,21 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Unit;
pub struct Unit;
#[derive(Serialize, Deserialize)]
struct Newtype(u8);
pub struct Newtype(u8);
#[derive(Serialize, Deserialize)]
struct Tuple(u8, u8);
pub struct Tuple(u8, u8);
#[derive(Serialize, Deserialize)]
struct Struct {
pub struct Struct {
f: u8,
}
#[derive(Serialize, Deserialize)]
enum Enum {
pub enum Enum {
Unit,
Newtype(u8),
Tuple(u8, u8),
+3 -3
View File
@@ -1,6 +1,6 @@
#[cfg_attr(target_os = "emscripten", ignore)]
#[rustversion::attr(not(nightly), ignore)]
#[cfg_attr(miri, ignore)]
#[cfg_attr(target_os = "emscripten", ignore = "disabled on Emscripten")]
#[rustversion::attr(not(nightly), ignore = "requires nightly")]
#[cfg_attr(miri, ignore = "incompatible with miri")]
#[allow(unused_attributes)]
#[test]
fn ui() {
+66
View File
@@ -0,0 +1,66 @@
#![allow(dead_code)] // we do not read enum fields
use serde_derive::Deserialize;
#[derive(Deserialize)]
pub struct Nested;
#[derive(Deserialize)]
pub enum ExternallyTagged1 {
Tuple(f64, String),
Flatten {
#[serde(flatten)]
nested: Nested,
},
}
#[derive(Deserialize)]
pub enum ExternallyTagged2 {
Flatten {
#[serde(flatten)]
nested: Nested,
},
Tuple(f64, String),
}
// Internally tagged enums cannot contain tuple variants so not tested here
#[derive(Deserialize)]
#[serde(tag = "tag", content = "content")]
pub enum AdjacentlyTagged1 {
Tuple(f64, String),
Flatten {
#[serde(flatten)]
nested: Nested,
},
}
#[derive(Deserialize)]
#[serde(tag = "tag", content = "content")]
pub enum AdjacentlyTagged2 {
Flatten {
#[serde(flatten)]
nested: Nested,
},
Tuple(f64, String),
}
#[derive(Deserialize)]
#[serde(untagged)]
pub enum Untagged1 {
Tuple(f64, String),
Flatten {
#[serde(flatten)]
nested: Nested,
},
}
#[derive(Deserialize)]
#[serde(untagged)]
pub enum Untagged2 {
Flatten {
#[serde(flatten)]
nested: Nested,
},
Tuple(f64, String),
}
+41
View File
@@ -0,0 +1,41 @@
use serde_derive::{Serialize, Deserialize};
use serde_test::{assert_tokens, Token};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
enum Enum {
Simple {
a: i32,
},
Flatten {
#[serde(flatten)]
flatten: (),
a: i32,
},
}
#[test]
fn simple_variant() {
assert_tokens(
&Enum::Simple { a: 42 },
&[
Token::StructVariant { name: "Enum", variant: "Simple", len: 1 },
Token::Str("a"),
Token::I32(42),
Token::StructVariantEnd,
]
);
}
#[test]
fn flatten_variant() {
assert_tokens(
&Enum::Flatten { flatten: (), a: 42 },
&[
Token::NewtypeVariant { name: "Enum", variant: "Flatten" },
Token::Map { len: None },
Token::Str("a"),
Token::I32(42),
Token::MapEnd,
]
);
}
+18
View File
@@ -0,0 +1,18 @@
#![allow(dead_code)] // we do not read enum fields
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
pub enum A {
B {
c: String,
},
D {
#[serde(flatten)]
e: E,
},
}
#[derive(Deserialize)]
pub struct E {}
+50
View File
@@ -2380,6 +2380,56 @@ fn test_partially_untagged_enum_desugared() {
);
}
// Regression test for https://github.com/serde-rs/serde/issues/1904
#[test]
fn test_enum_tuple_and_struct_with_flatten() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum Outer {
Tuple(f64, i32),
Flatten {
#[serde(flatten)]
nested: Nested,
},
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Nested {
a: i32,
b: i32,
}
assert_tokens(
&Outer::Tuple(1.2, 3),
&[
Token::TupleVariant {
name: "Outer",
variant: "Tuple",
len: 2,
},
Token::F64(1.2),
Token::I32(3),
Token::TupleVariantEnd,
],
);
assert_tokens(
&Outer::Flatten {
nested: Nested { a: 1, b: 2 },
},
&[
Token::NewtypeVariant {
name: "Outer",
variant: "Flatten",
},
Token::Map { len: None },
Token::Str("a"),
Token::I32(1),
Token::Str("b"),
Token::I32(2),
Token::MapEnd,
],
);
}
#[test]
fn test_partially_untagged_internally_tagged_enum() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
+2 -2
View File
@@ -162,7 +162,7 @@ fn test_cow() {
#[test]
fn test_lifetimes() {
#[derive(Deserialize)]
struct Cows<'a, 'b> {
pub struct Cows<'a, 'b> {
_copied: Cow<'a, str>,
#[serde(borrow)]
@@ -178,7 +178,7 @@ fn test_lifetimes() {
}
#[derive(Deserialize)]
struct Wrap<'a, 'b> {
pub struct Wrap<'a, 'b> {
#[serde(borrow = "'b")]
_cows: Cows<'a, 'b>,
}
+1 -1
View File
@@ -93,7 +93,7 @@ struct StructSkipDefault {
#[derive(PartialEq, Debug, Deserialize)]
#[serde(default)]
struct StructSkipDefaultGeneric<T> {
pub struct StructSkipDefaultGeneric<T> {
#[serde(skip_deserializing)]
t: T,
}
+64 -51
View File
@@ -4,6 +4,7 @@
#![deny(warnings)]
#![allow(
confusable_idents,
unknown_lints,
mixed_script_confusables,
clippy::derive_partial_eq_without_eq,
@@ -19,6 +20,7 @@
clippy::trivially_copy_pass_by_ref,
clippy::type_repetition_in_bounds
)]
#![deny(clippy::collection_is_never_read)]
use serde::de::{Deserialize, DeserializeOwned, Deserializer};
use serde::ser::{Serialize, Serializer};
@@ -287,60 +289,60 @@ fn test_gen() {
assert::<EmptyEnumVariant>();
#[derive(Serialize, Deserialize)]
struct NonAsciiIdents {
pub struct NonAsciiIdents {
σ: f64,
}
#[derive(Serialize, Deserialize)]
struct EmptyBraced {}
pub struct EmptyBraced {}
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct EmptyBracedDenyUnknown {}
pub struct EmptyBracedDenyUnknown {}
#[derive(Serialize, Deserialize)]
struct BracedSkipAll {
pub struct BracedSkipAll {
#[serde(skip_deserializing)]
f: u8,
}
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct BracedSkipAllDenyUnknown {
pub struct BracedSkipAllDenyUnknown {
#[serde(skip_deserializing)]
f: u8,
}
#[derive(Serialize, Deserialize)]
struct EmptyTuple();
pub struct EmptyTuple();
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct EmptyTupleDenyUnknown();
pub struct EmptyTupleDenyUnknown();
#[derive(Serialize, Deserialize)]
struct TupleSkipAll(#[serde(skip_deserializing)] u8);
pub struct TupleSkipAll(#[serde(skip_deserializing)] u8);
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);
pub struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);
#[derive(Serialize, Deserialize)]
enum EmptyEnum {}
pub enum EmptyEnum {}
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
enum EmptyEnumDenyUnknown {}
pub enum EmptyEnumDenyUnknown {}
#[derive(Serialize, Deserialize)]
enum EnumSkipAll {
pub enum EnumSkipAll {
#[serde(skip_deserializing)]
#[allow(dead_code)]
Variant,
}
#[derive(Serialize, Deserialize)]
enum EmptyVariants {
pub enum EmptyVariants {
Braced {},
Tuple(),
BracedSkip {
@@ -352,7 +354,7 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
enum EmptyVariantsDenyUnknown {
pub enum EmptyVariantsDenyUnknown {
Braced {},
Tuple(),
BracedSkip {
@@ -364,21 +366,21 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct UnitDenyUnknown;
pub struct UnitDenyUnknown;
#[derive(Serialize, Deserialize)]
struct EmptyArray {
pub struct EmptyArray {
empty: [X; 0],
}
enum Or<A, B> {
pub enum Or<A, B> {
A(A),
B(B),
}
#[derive(Serialize, Deserialize)]
#[serde(untagged, remote = "Or")]
enum OrDef<A, B> {
pub enum OrDef<A, B> {
A(A),
B(B),
}
@@ -390,7 +392,7 @@ fn test_gen() {
struct StrDef<'a>(&'a str);
#[derive(Serialize, Deserialize)]
struct Remote<'a> {
pub struct Remote<'a> {
#[serde(with = "OrDef")]
or: Or<u8, bool>,
#[serde(borrow, with = "StrDef")]
@@ -398,7 +400,7 @@ fn test_gen() {
}
#[derive(Serialize, Deserialize)]
enum BorrowVariant<'a> {
pub enum BorrowVariant<'a> {
#[serde(borrow, with = "StrDef")]
S(Str<'a>),
}
@@ -415,14 +417,14 @@ fn test_gen() {
// This would not work if SDef::serialize / deserialize are private.
#[derive(Serialize, Deserialize)]
struct RemoteVisibility {
pub struct RemoteVisibility {
#[serde(with = "vis::SDef")]
s: vis::S,
}
#[derive(Serialize, Deserialize)]
#[serde(remote = "Self")]
struct RemoteSelf;
pub struct RemoteSelf;
#[derive(Serialize, Deserialize)]
enum ExternallyTaggedVariantWith {
@@ -547,25 +549,25 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct FlattenDenyUnknown<T> {
pub struct FlattenDenyUnknown<T> {
#[serde(flatten)]
t: T,
}
#[derive(Serialize, Deserialize)]
struct StaticStrStruct<'a> {
pub struct StaticStrStruct<'a> {
a: &'a str,
b: &'static str,
}
#[derive(Serialize, Deserialize)]
struct StaticStrTupleStruct<'a>(&'a str, &'static str);
pub struct StaticStrTupleStruct<'a>(&'a str, &'static str);
#[derive(Serialize, Deserialize)]
struct StaticStrNewtypeStruct(&'static str);
pub struct StaticStrNewtypeStruct(&'static str);
#[derive(Serialize, Deserialize)]
enum StaticStrEnum<'a> {
pub enum StaticStrEnum<'a> {
Struct { a: &'a str, b: &'static str },
Tuple(&'a str, &'static str),
Newtype(&'static str),
@@ -639,6 +641,7 @@ fn test_gen() {
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
#[allow(dead_code)]
struct Restricted {
pub(super) a: usize,
pub(in super::inner) b: usize,
@@ -648,7 +651,7 @@ fn test_gen() {
#[derive(Deserialize)]
#[serde(tag = "t", content = "c")]
enum AdjacentlyTaggedVoid {}
pub enum AdjacentlyTaggedVoid {}
#[derive(Serialize, Deserialize)]
enum SkippedVariant<T> {
@@ -661,14 +664,13 @@ fn test_gen() {
assert::<SkippedVariant<X>>();
#[derive(Deserialize)]
struct ImplicitlyBorrowedOption<'a> {
#[allow(dead_code)]
pub struct ImplicitlyBorrowedOption<'a> {
option: std::option::Option<&'a str>,
}
#[derive(Serialize, Deserialize)]
#[serde(untagged)]
enum UntaggedNewtypeVariantWith {
pub enum UntaggedNewtypeVariantWith {
Newtype(
#[serde(serialize_with = "ser_x")]
#[serde(deserialize_with = "de_x")]
@@ -678,7 +680,7 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
struct TransparentWith {
pub struct TransparentWith {
#[serde(serialize_with = "ser_x")]
#[serde(deserialize_with = "de_x")]
x: X,
@@ -700,35 +702,49 @@ fn test_gen() {
}
#[derive(Deserialize)]
struct RelObject<'a> {
#[allow(dead_code)]
pub struct RelObject<'a> {
ty: &'a str,
#[allow(dead_code)]
id: String,
}
#[derive(Serialize, Deserialize)]
struct FlattenSkipSerializing<T> {
pub struct FlattenSkipSerializing<T> {
#[serde(flatten, skip_serializing)]
#[allow(dead_code)]
flat: T,
}
#[derive(Serialize, Deserialize)]
struct FlattenSkipSerializingIf<T> {
pub struct FlattenSkipSerializingIf<T> {
#[serde(flatten, skip_serializing_if = "StdOption::is_none")]
flat: StdOption<T>,
}
#[allow(clippy::collection_is_never_read)] // FIXME
const _: () = {
#[derive(Serialize, Deserialize)]
pub struct FlattenSkipDeserializing<T> {
#[serde(flatten, skip_deserializing)]
flat: T,
}
};
#[derive(Serialize, Deserialize)]
struct FlattenSkipDeserializing<T> {
#[serde(flatten, skip_deserializing)]
flat: T,
#[serde(untagged)]
pub enum Inner<T> {
Builder {
s: T,
#[serde(flatten)]
o: T,
},
Default {
s: T,
},
}
// https://github.com/serde-rs/serde/issues/1804
#[derive(Serialize, Deserialize)]
enum Message {
pub enum Message {
#[serde(skip)]
#[allow(dead_code)]
String(String),
@@ -747,8 +763,7 @@ fn test_gen() {
macro_rules! deriving {
($field:ty) => {
#[derive(Deserialize)]
struct MacroRules<'a> {
#[allow(dead_code)]
pub struct MacroRules<'a> {
field: $field,
}
};
@@ -763,22 +778,20 @@ fn test_gen() {
}
#[derive(Deserialize)]
struct BorrowLifetimeInsideMacro<'a> {
pub struct BorrowLifetimeInsideMacro<'a> {
#[serde(borrow = "'a")]
#[allow(dead_code)]
f: mac!(Cow<'a, str>),
pub f: mac!(Cow<'a, str>),
}
#[derive(Serialize)]
#[allow(dead_code)]
struct Struct {
pub struct Struct {
#[serde(serialize_with = "vec_first_element")]
vec: Vec<Self>,
pub vec: Vec<Self>,
}
#[derive(Deserialize)]
#[serde(bound(deserialize = "[&'de str; N]: Copy"))]
struct GenericUnitStruct<const N: usize>;
pub struct GenericUnitStruct<const N: usize>;
}
//////////////////////////////////////////////////////////////////////////
@@ -865,7 +878,7 @@ where
#[derive(Debug, PartialEq, Deserialize)]
#[serde(tag = "tag")]
enum InternallyTagged {
pub enum InternallyTagged {
#[serde(deserialize_with = "deserialize_generic")]
Unit,
+15
View File
@@ -7,14 +7,17 @@ mod remote {
pub struct PrimitivePriv(u8);
#[allow(dead_code)]
pub struct PrimitivePub(pub u8);
pub struct NewtypePriv(Unit);
#[allow(dead_code)]
pub struct NewtypePub(pub Unit);
pub struct TuplePriv(u8, Unit);
#[allow(dead_code)]
pub struct TuplePub(pub u8, pub Unit);
pub struct StructPriv {
@@ -22,6 +25,7 @@ mod remote {
b: Unit,
}
#[allow(dead_code)]
pub struct StructPub {
pub a: u8,
pub b: Unit,
@@ -86,12 +90,14 @@ mod remote {
}
}
#[allow(dead_code)]
pub enum EnumGeneric<T> {
Variant(T),
}
}
#[derive(Serialize, Deserialize)]
#[allow(dead_code)]
struct Test {
#[serde(with = "UnitDef")]
unit: remote::Unit,
@@ -132,6 +138,7 @@ struct Test {
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::Unit")]
#[allow(dead_code)]
struct UnitDef;
#[derive(Serialize, Deserialize)]
@@ -140,6 +147,7 @@ struct PrimitivePrivDef(#[serde(getter = "remote::PrimitivePriv::get")] u8);
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::PrimitivePub")]
#[allow(dead_code)]
struct PrimitivePubDef(u8);
#[derive(Serialize, Deserialize)]
@@ -148,6 +156,7 @@ struct NewtypePrivDef(#[serde(getter = "remote::NewtypePriv::get", with = "UnitD
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::NewtypePub")]
#[allow(dead_code)]
struct NewtypePubDef(#[serde(with = "UnitDef")] remote::Unit);
#[derive(Serialize, Deserialize)]
@@ -159,6 +168,7 @@ struct TuplePrivDef(
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::TuplePub")]
#[allow(dead_code)]
struct TuplePubDef(u8, #[serde(with = "UnitDef")] remote::Unit);
#[derive(Serialize, Deserialize)]
@@ -174,6 +184,7 @@ struct StructPrivDef {
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::StructPub")]
#[allow(dead_code)]
struct StructPubDef {
a: u8,
@@ -190,17 +201,20 @@ struct StructGenericWithGetterDef<T> {
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::StructGeneric<u8>")]
#[allow(dead_code)]
struct StructConcrete {
value: u8,
}
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::EnumGeneric<u8>")]
#[allow(dead_code)]
enum EnumConcrete {
Variant(u8),
}
#[derive(Debug)]
#[allow(dead_code)]
enum ErrorKind {
NotFound,
PermissionDenied,
@@ -211,6 +225,7 @@ enum ErrorKind {
#[derive(Serialize, Deserialize)]
#[serde(remote = "ErrorKind")]
#[non_exhaustive]
#[allow(dead_code)]
enum ErrorKindDef {
NotFound,
PermissionDenied,
+2 -2
View File
@@ -41,7 +41,7 @@ fn test_self() {
}
#[derive(Deserialize, Serialize)]
struct Tuple(
pub struct Tuple(
Box<Self>,
Box<<Self as Trait>::Assoc>,
[(); Self::ASSOC],
@@ -60,7 +60,7 @@ fn test_self() {
}
#[derive(Deserialize, Serialize)]
enum Enum {
pub enum Enum {
Struct {
_f1: Box<Self>,
_f2: Box<<Self as Trait>::Assoc>,
+23
View File
@@ -0,0 +1,23 @@
use serde::de::Deserialize;
use serde::ser::Serialize;
fn to_string<T>(_: &T) -> String
where
T: Serialize,
{
unimplemented!()
}
fn from_str<'de, T>(_: &'de str) -> T
where
T: Deserialize<'de>,
{
unimplemented!()
}
struct MyStruct;
fn main() {
to_string(&MyStruct);
let _: MyStruct = from_str("");
}
@@ -0,0 +1,55 @@
error[E0277]: the trait bound `MyStruct: Serialize` is not satisfied
--> tests/ui/on_unimplemented.rs:21:15
|
21 | to_string(&MyStruct);
| --------- ^^^^^^^^^ the trait `Serialize` is not implemented for `MyStruct`
| |
| required by a bound introduced by this call
|
= note: for local types consider adding `#[derive(serde::Serialize)]` to your `MyStruct` 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 `to_string`
--> tests/ui/on_unimplemented.rs:6:8
|
4 | fn to_string<T>(_: &T) -> String
| --------- required by a bound in this function
5 | where
6 | 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
|
22 | 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
= 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 `from_str`
--> tests/ui/on_unimplemented.rs:13:8
|
11 | fn from_str<'de, T>(_: &'de str) -> T
| -------- required by a bound in this function
12 | where
13 | T: Deserialize<'de>,
| ^^^^^^^^^^^^^^^^ required by this bound in `from_str`