Compare commits

...

72 Commits

Author SHA1 Message Date
David Tolnay 8932c852a5 Release 1.0.135 2022-01-22 16:04:17 -08:00
David Tolnay 9f3dd3c7c4 Merge pull request #2163 from serde-rs/discord
Add discord invite links
2022-01-22 11:23:32 -08:00
David Tolnay dd9b415ff9 Add discord invite links 2022-01-22 11:21:08 -08:00
David Tolnay 3bb4a5a4f6 Release 1.0.134 2022-01-20 22:22:30 -08:00
David Tolnay 6164627bea Merge pull request #2159 from serde-rs/nonzero
Write better Visitor for NonZero integers
2022-01-20 22:22:02 -08:00
David Tolnay 51aaf496d4 Write better Visitor for NonZero integers 2022-01-20 22:15:16 -08:00
David Tolnay bc66aeb0d3 Add tests of deserializing NonZero 2022-01-20 21:55:50 -08:00
David Tolnay 7e7044d457 Ignore clippy in number conversion tests 2022-01-20 21:38:31 -08:00
David Tolnay 5498dc0550 Add tests of num conversion errors 2022-01-20 21:37:16 -08:00
David Tolnay ff04e8be9b Improve coverage of num conversion in test suite 2022-01-20 21:16:50 -08:00
David Tolnay 69240c17c5 Eliminate macro from serialization tests 2022-01-20 20:37:08 -08:00
David Tolnay 237434f19c Accept ?Sized references in assert_ser_tokens 2022-01-20 20:21:04 -08:00
David Tolnay 1833914346 Eliminate macro from deserialization error tests 2022-01-20 19:58:45 -08:00
David Tolnay ab848060f2 Extract tests of deserialization errors to separate file 2022-01-20 19:58:01 -08:00
David Tolnay 7e39623f72 Implement test suite seq macro without tt muncher 2022-01-20 19:40:58 -08:00
David Tolnay 157dc44c51 Clean up test suite's macro formatting 2022-01-20 19:40:32 -08:00
David Tolnay 80d01a3a79 Tweak seq iterators in test suite 2022-01-20 19:40:13 -08:00
David Tolnay 343c060fc1 Adapt seq macro to not derail rustfmt 2022-01-20 19:38:51 -08:00
David Tolnay 21c1ab6c50 Format deserialization tests with rustfmt 2022-01-20 19:24:35 -08:00
David Tolnay 594ab7745d Reimplement deserialization tests without macro 2022-01-20 18:09:48 -08:00
David Tolnay 8cf0ba7fe2 Make serde_test build script buildable with older rustc 2022-01-20 17:59:21 -08:00
David Tolnay 34b52c0b83 Include build script in packaged serde_test crate 2022-01-20 17:52:25 -08:00
David Tolnay ec7ddc93cd Include 128-bit integers in test suite unconditionally 2022-01-20 15:45:07 -08:00
David Tolnay 55a7cedd73 Invert all build.rs cfgs
This allows non-Cargo builds to generally not get involved in cfgs. As
long as one is using a reasonably recent toolchain, no cfgs need to be
set and you'll get a fully-featured build.
2022-01-01 21:09:49 -08:00
David Tolnay 7af97c66b8 Release 1.0.133 2022-01-01 13:16:35 -08:00
David Tolnay 1f57084365 Merge pull request #2148 from serde-rs/deserializecontent
Optimize deserialization of recursive buffered types
2022-01-01 13:16:02 -08:00
David Tolnay 56bd369422 Optimize deserialization of recursive buffered types 2022-01-01 13:01:38 -08:00
David Tolnay ff259ec66b Detect warnings in CI 2022-01-01 11:52:55 -08:00
David Tolnay 6c54aafeb9 Document the atomic ordering in the Serialize impl 2021-12-23 11:44:31 -08:00
David Tolnay 5d41404e67 No need for the SeqCst load in test suite 2021-12-23 11:42:41 -08:00
David Tolnay 1eccb3c350 Resolve unnecessary_to_owned clippy lint in test suite
error: unnecessary use of `to_vec`
       --> test_suite/tests/test_de.rs:251:12
        |
    251 |     .chain(ignorable_tokens.to_vec().into_iter())
        |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `ignorable_tokens.iter().copied()`
        |
        = note: `-D clippy::unnecessary-to-owned` implied by `-D clippy::all`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned
2021-12-17 18:25:04 -08:00
David Tolnay 77ae1c3bf7 Release 1.0.132 2021-12-16 11:06:42 -08:00
David Tolnay b85e28166c Update path to rustc target spec files 2021-12-16 11:05:58 -08:00
David Tolnay 0508cb50fc Merge pull request #2141 from Avimitin/risc-v
Enable atomic64 on riscv64 arch
2021-12-16 11:05:14 -08:00
Avimitin 84fdc7df69 Enable atomic64 on riscv64 arch
Signed-off-by: Avimitin <avimitin@gmail.com>
2021-12-14 20:30:28 +08:00
David Tolnay ab1ca04b2e Release 1.0.131 2021-12-08 18:47:15 -08:00
David Tolnay fb2fe409c8 Touch up PR 2116 2021-12-08 18:44:41 -08:00
David Tolnay 549fac7235 Merge pull request #2116 from tyranron/fix-unused-results
Fix `unused_results` complaining rustc lint in codegen for adjacently tagged enum
2021-12-08 18:43:31 -08:00
David Tolnay c375d8b19b Merge pull request #2124 from dtolnay/cbor
Change cbor link to new repo
2021-11-26 14:48:40 -08:00
David Tolnay 6cf507f808 Change cbor link to new repo 2021-11-26 14:43:09 -08:00
David Tolnay c3c1641c06 Remove workaround for redundant_field_names Clippy bug 2021-11-04 20:23:25 -07:00
David Tolnay 1fcda0ebdb Enable pedantic lints on test suite in CI 2021-11-04 20:21:48 -07:00
David Tolnay 8f16ac0a94 Move deny(clippy) to command line arguments in the CI job 2021-11-04 20:09:35 -07:00
David Tolnay 737f78c315 Ignore enum_variant_names Clippy lint in test suite
error: all variants have the same prefix: `Serialize`
        --> test_suite/tests/test_macros.rs:1741:5
         |
    1741 | /     enum E {
    1742 | |         #[serde(rename_all = "camelCase")]
    1743 | |         Serialize {
    1744 | |             serialize: bool,
    ...    |
    1756 | |         },
    1757 | |     }
         | |_____^
         |
         = note: `-D clippy::enum-variant-names` implied by `-D clippy::all`
         = help: remove the prefixes and use full paths to the variants instead of glob imports
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names
2021-11-04 20:06:02 -07:00
David Tolnay 4a97386cb9 Clippy if_then_panic lint has been renamed to manual_assert 2021-11-04 19:57:14 -07:00
tyranron 5b32217877 Fix unused_results complaining rustc lint in codegen for adjacently tagged enum 2021-10-29 14:13:26 +03:00
David Tolnay 5b140361a3 Merge pull request #2102 from atouchet/url
Update URL
2021-10-14 16:33:22 -07:00
Alex Touchet 678351eac7 Update URL 2021-10-14 16:27:49 -07:00
David Tolnay 999c261d11 Ui test changes for trybuild 1.0.49 2021-10-08 02:46:15 -04:00
David Tolnay efbe574209 Update ui test files 2021-10-07 00:56:29 -04:00
David Tolnay 33b2677384 Suppress broken semicolon_if_nothing_returned lint
https://github.com/rust-lang/rust-clippy/issues/7768

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde/src/de/impls.rs:849:1
        |
    849 | / seq_impl!(
    850 | |     BinaryHeap<T: Ord>,
    851 | |     seq,
    852 | |     BinaryHeap::clear,
    ...   |
    855 | |     BinaryHeap::push
    856 | | );
        | |__^
        |
    note: the lint level is defined here
       --> serde/src/lib.rs:97:52
        |
    97  | #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
        |                                                    ^^^^^^^^^^^^^^^
        = note: `#[deny(clippy::semicolon_if_nothing_returned)]` implied by `#[deny(clippy::pedantic)]`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
        |
    849 + seq_impl!(
    850 +     BinaryHeap<T: Ord>,
    851 +     seq,
    852 +     BinaryHeap::clear,
    853 +     BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
    854 +     BinaryHeap::reserve,
      ...

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde/src/de/impls.rs:859:1
        |
    859 | / seq_impl!(
    860 | |     BTreeSet<T: Eq + Ord>,
    861 | |     seq,
    862 | |     BTreeSet::clear,
    ...   |
    865 | |     BTreeSet::insert
    866 | | );
        | |__^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
        |
    859 + seq_impl!(
    860 +     BTreeSet<T: Eq + Ord>,
    861 +     seq,
    862 +     BTreeSet::clear,
    863 +     BTreeSet::new(),
    864 +     nop_reserve,
      ...

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde/src/de/impls.rs:869:1
        |
    869 | / seq_impl!(
    870 | |     LinkedList<T>,
    871 | |     seq,
    872 | |     LinkedList::clear,
    ...   |
    875 | |     LinkedList::push_back
    876 | | );
        | |__^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
        |
    869 + seq_impl!(
    870 +     LinkedList<T>,
    871 +     seq,
    872 +     LinkedList::clear,
    873 +     LinkedList::new(),
    874 +     nop_reserve,
      ...

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde/src/de/impls.rs:879:1
        |
    879 | / seq_impl!(
    880 | |     HashSet<T: Eq + Hash, S: BuildHasher + Default>,
    881 | |     seq,
    882 | |     HashSet::clear,
    883 | |     HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
    884 | |     HashSet::reserve,
    885 | |     HashSet::insert);
        | |_____________________^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
        |
    879 + seq_impl!(
    880 +     HashSet<T: Eq + Hash, S: BuildHasher + Default>,
    881 +     seq,
    882 +     HashSet::clear,
    883 +     HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
    884 +     HashSet::reserve,
      ...

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde/src/de/impls.rs:888:1
        |
    888 | / seq_impl!(
    889 | |     VecDeque<T>,
    890 | |     seq,
    891 | |     VecDeque::clear,
    ...   |
    894 | |     VecDeque::push_back
    895 | | );
        | |__^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
        |
    888 + seq_impl!(
    889 +     VecDeque<T>,
    890 +     seq,
    891 +     VecDeque::clear,
    892 +     VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
    893 +     VecDeque::reserve,
      ...

    error: consider adding a `;` to the last statement for consistent formatting
        --> serde/src/de/impls.rs:1300:1
         |
    1300 | / map_impl!(
    1301 | |     BTreeMap<K: Ord, V>,
    1302 | |     map,
    1303 | |     BTreeMap::new());
         | |_____________________^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
         |
    1300 + map_impl!(
    1301 +     BTreeMap<K: Ord, V>,
    1302 +     map,
    1303 +     BTreeMap::new());;
         |

    error: consider adding a `;` to the last statement for consistent formatting
        --> serde/src/de/impls.rs:1306:1
         |
    1306 | / map_impl!(
    1307 | |     HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
    1308 | |     map,
    1309 | |     HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default()));
         | |___________________________________________________________________________________________^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
         |
    1306 + map_impl!(
    1307 +     HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
    1308 +     map,
    1309 +     HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default()));;
         |
2021-10-04 23:57:05 -04:00
David Tolnay 01ded9f405 Declare minimum Rust version in Cargo metadata 2021-10-02 02:43:22 -04:00
David Tolnay fc827ecec2 Resolve redundant_closure_for_method_calls clippy lints
error: redundant closure
      --> serde_derive/src/bound.rs:53:19
       |
    53 |         .flat_map(|predicates| predicates.to_vec());
       |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `[T]::to_vec`
       |
    note: the lint level is defined here
      --> serde_derive/src/lib.rs:18:22
       |
    18 | #![deny(clippy::all, clippy::pedantic)]
       |                      ^^^^^^^^^^^^^^^^
       = note: `#[deny(clippy::redundant_closure_for_method_calls)]` implied by `#[deny(clippy::pedantic)]`
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_for_method_calls

    error: redundant closure
      --> serde_derive/src/bound.rs:75:19
       |
    75 |         .flat_map(|predicates| predicates.to_vec());
       |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `[T]::to_vec`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_for_method_calls
2021-09-30 00:31:49 -04:00
David Tolnay 5c785eee58 Ignore if_then_panic clippy lint
error: only a `panic!` in `if`-then statement
      --> serde_derive/src/internals/ctxt.rs:58:9
       |
    58 | /         if !thread::panicking() && self.errors.borrow().is_some() {
    59 | |             panic!("forgot to check for errors");
    60 | |         }
       | |_________^ help: try: `assert!(!!thread::panicking() && self.errors.borrow().is_some(), "forgot to check for errors");`
       |
    note: the lint level is defined here
      --> serde_derive/src/lib.rs:18:9
       |
    18 | #![deny(clippy::all, clippy::pedantic)]
       |         ^^^^^^^^^^^
       = note: `#[deny(clippy::if_then_panic)]` implied by `#[deny(clippy::all)]`
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
       --> serde_test/src/assert.rs:73:5
        |
    73  | /     if ser.remaining() > 0 {
    74  | |         panic!("{} remaining tokens", ser.remaining());
    75  | |     }
        | |_____^ help: try: `assert!(!ser.remaining() > 0, "{} remaining tokens", ser.remaining());`
        |
    note: the lint level is defined here
       --> serde_test/src/lib.rs:149:44
        |
    149 | #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
        |                                            ^^^^^^
        = note: `#[deny(clippy::if_then_panic)]` implied by `#[deny(clippy::all)]`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
       --> serde_test/src/assert.rs:126:5
        |
    126 | /     if ser.remaining() > 0 {
    127 | |         panic!("{} remaining tokens", ser.remaining());
    128 | |     }
        | |_____^ help: try: `assert!(!ser.remaining() > 0, "{} remaining tokens", ser.remaining());`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
       --> serde_test/src/assert.rs:166:5
        |
    166 | /     if de.remaining() > 0 {
    167 | |         panic!("{} remaining tokens", de.remaining());
    168 | |     }
        | |_____^ help: try: `assert!(!de.remaining() > 0, "{} remaining tokens", de.remaining());`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
       --> serde_test/src/assert.rs:180:5
        |
    180 | /     if de.remaining() > 0 {
    181 | |         panic!("{} remaining tokens", de.remaining());
    182 | |     }
        | |_____^ help: try: `assert!(!de.remaining() > 0, "{} remaining tokens", de.remaining());`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
       --> serde_test/src/assert.rs:220:5
        |
    220 | /     if de.remaining() > 0 {
    221 | |         panic!("{} remaining tokens", de.remaining());
    222 | |     }
        | |_____^ help: try: `assert!(!de.remaining() > 0, "{} remaining tokens", de.remaining());`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
        --> test_suite/tests/test_de.rs:1349:9
         |
    1349 | /         if de.remaining() > 0 {
    1350 | |             panic!("{} remaining tokens", de.remaining());
    1351 | |         }
         | |_________^ help: try: `assert!(!de.remaining() > 0, "{} remaining tokens", de.remaining());`
         |
         = note: `-D clippy::if-then-panic` implied by `-D clippy::all`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic
2021-09-30 00:31:49 -04:00
David Tolnay 819db93a3d Format with rustfmt 2021-09-29 2021-09-30 00:31:49 -04:00
David Tolnay a6690ea2fe Update ui test suite to nightly-2021-09-14 2021-09-14 19:13:54 -07:00
David Tolnay 65e1a50749 Release 1.0.130 2021-08-28 11:31:38 -07:00
David Tolnay 87d41b59fd Merge pull request #2081 from dtolnay/accessunsized
Enable unsized Map/SeqAccess types to use the impl for &mut
2021-08-28 11:11:57 -07:00
David Tolnay 3f120fb355 Enable unsized Map/SeqAccess types to use the impl for &mut 2021-08-28 10:59:51 -07:00
David Tolnay 2b92c80cc1 Release 1.0.129 2021-08-23 15:01:24 -07:00
David Tolnay c1c0ede452 Merge pull request #2080 from dtolnay/packeddrop
Support packed remote struct without destructuring
2021-08-23 15:00:50 -07:00
David Tolnay 4a66c5f33d Support packed remote struct without destructuring 2021-08-23 14:38:33 -07:00
David Tolnay 714c8a5586 Add test of packed struct that cannot be destructured
Currently fails:

    error[E0509]: cannot move out of type `RemotePackedNonCopyDef`, which implements the `Drop` trait
       --> test_suite/tests/test_gen.rs:876:10
        |
    876 | #[derive(Deserialize)]
        |          ^^^^^^^^^^^
        |          |
        |          cannot move out of here
        |          data moved here
        |          move occurs because `__v1` has type `std::string::String`, which does not implement the `Copy` trait
        |
        = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
2021-08-23 14:38:33 -07:00
David Tolnay dc0c0dcba1 Merge pull request #2079 from dtolnay/packedremote
Fix unaligned reference warnings on packed remote def
2021-08-23 14:38:21 -07:00
David Tolnay 54102ee7d0 Avoid generating ref patterns for fields of packed remote struct 2021-08-23 10:18:28 -07:00
David Tolnay 14accf7518 Add test of remote with a packed struct
Currently fails to build:

    error: reference to packed field is unaligned
       --> test_suite/tests/test_gen.rs:858:10
        |
    858 | #[derive(Serialize, Deserialize)]
        |          ^^^^^^^^^
        |
    note: the lint level is defined here
       --> test_suite/tests/test_gen.rs:5:9
        |
    5   | #![deny(warnings)]
        |         ^^^^^^^^
        = note: `#[deny(unaligned_references)]` implied by `#[deny(warnings)]`
        = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
        = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
        = note: this error originates in the derive macro `Serialize` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: reference to packed field is unaligned
       --> test_suite/tests/test_gen.rs:858:21
        |
    858 | #[derive(Serialize, Deserialize)]
        |                     ^^^^^^^^^^^
        |
        = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
        = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
        = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
2021-08-23 10:18:05 -07:00
David Tolnay 55fdbea20b Merge pull request #2077 from dtolnay/tryfold
Use try_fold in default implementation of collect_seq, collect_map
2021-08-21 14:08:20 -07:00
David Tolnay 75d8902371 Use try_fold in default implementation of collect_seq, collect_map 2021-08-21 14:00:51 -07:00
David Tolnay 9451ea8df1 Format PR 1992 with rustfmt 2021-08-21 12:49:58 -07:00
David Tolnay c1ce03b3dd Merge pull request 1992 from Mingun/unnecessary-deserialize-with 2021-08-21 12:49:39 -07:00
Mingun e0fc46783d Add test with generic deserialize_with function 2021-06-12 18:47:08 +05:00
Mingun ca772a14f9 Get rid of useless DeserializeWith wrapper 2021-06-12 18:38:03 +05:00
135 changed files with 4739 additions and 2077 deletions
+9 -8
View File
@@ -5,6 +5,9 @@ on:
pull_request: pull_request:
schedule: [cron: "40 1 * * *"] schedule: [cron: "40 1 * * *"]
env:
RUSTFLAGS: -Dwarnings
jobs: jobs:
test: test:
name: Test suite name: Test suite
@@ -153,11 +156,9 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: dtolnay/rust-toolchain@clippy - uses: dtolnay/rust-toolchain@clippy
# The need for -Aredundant_field_names here is a Clippy bug. - run: cd serde && cargo clippy --features rc,unstable -- -Dclippy::all -Dclippy::pedantic
# https://github.com/rust-lang/rust-clippy/issues/5356 - run: cd serde_derive && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd serde && cargo clippy --features rc,unstable -- -D clippy::all -A clippy::redundant_field_names - run: cd serde_derive_internals && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_derive && cargo clippy -- -D clippy::all - run: cd serde_test && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_derive_internals && cargo clippy -- -D clippy::all - run: cd test_suite && cargo clippy --tests --features unstable -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_test && cargo clippy -- -D clippy::all -A clippy::redundant_field_names - run: cd test_suite/no_std && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd test_suite && cargo clippy --tests --features unstable -- -D clippy::all -A clippy::redundant_field_names
- run: cd test_suite/no_std && cargo clippy -- -D clippy::all -A clippy::redundant_field_names
+12 -9
View File
@@ -77,17 +77,20 @@ fn main() {
Serde is one of the most widely used Rust libraries so any place that Rustaceans 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 congregate will be able to help you out. For chat, consider trying the
[#general] or [#beginners] channels of the unofficial community Discord, the [#rust-questions] or [#rust-beginners] channels of the unofficial community
[#rust-usage] channel of the official Rust Project Discord, or the Discord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or
[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag [#beginners] channels of the official Rust Project Discord (invite:
on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned <https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
weekly easy questions post, or the Rust [Discourse forum][discourse]. It's asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
acceptable to file a support issue in this repo but they tend not to get as many [/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
eyes as any of the above and may get closed without a response after some time. [Discourse forum][discourse]. It's acceptable to file a support issue in this
repo but they tend not to get as many eyes as any of the above and may get
closed without a response after some time.
[#general]: https://discord.com/channels/273534239310479360/274215136414400513 [#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281 [#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 [#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
[stackoverflow]: https://stackoverflow.com/questions/tagged/rust [stackoverflow]: https://stackoverflow.com/questions/tagged/rust
[/r/rust]: https://www.reddit.com/r/rust [/r/rust]: https://www.reddit.com/r/rust
+12 -9
View File
@@ -45,17 +45,20 @@ fn main() {
Serde is one of the most widely used Rust libraries so any place that Rustaceans 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 congregate will be able to help you out. For chat, consider trying the
[#general] or [#beginners] channels of the unofficial community Discord, the [#rust-questions] or [#rust-beginners] channels of the unofficial community
[#rust-usage] channel of the official Rust Project Discord, or the Discord (invite: <https://discord.gg/rust-lang-community>, the [#rust-usage] or
[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag [#beginners] channels of the official Rust Project Discord (invite:
on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned <https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
weekly easy questions post, or the Rust [Discourse forum][discourse]. It's asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
acceptable to file a support issue in this repo but they tend not to get as many [/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
eyes as any of the above and may get closed without a response after some time. [Discourse forum][discourse]. It's acceptable to file a support issue in this
repo but they tend not to get as many eyes as any of the above and may get
closed without a response after some time.
[#general]: https://discord.com/channels/273534239310479360/274215136414400513 [#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281 [#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 [#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
[stackoverflow]: https://stackoverflow.com/questions/tagged/rust [stackoverflow]: https://stackoverflow.com/questions/tagged/rust
[/r/rust]: https://www.reddit.com/r/rust [/r/rust]: https://www.reddit.com/r/rust
+3 -2
View File
@@ -1,7 +1,8 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.128" # remember to update html_root_url and serde_derive dependency version = "1.0.135" # remember to update html_root_url and serde_derive dependency
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
rust-version = "1.15"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
homepage = "https://serde.rs" homepage = "https://serde.rs"
@@ -14,7 +15,7 @@ include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APAC
build = "build.rs" build = "build.rs"
[dependencies] [dependencies]
serde_derive = { version = "=1.0.128", optional = true, path = "../serde_derive" } serde_derive = { version = "=1.0.135", optional = true, path = "../serde_derive" }
[dev-dependencies] [dev-dependencies]
serde_derive = { version = "1.0", path = "../serde_derive" } serde_derive = { version = "1.0", path = "../serde_derive" }
+46 -41
View File
@@ -17,37 +17,38 @@ fn main() {
// std::collections::Bound was stabilized in Rust 1.17 // std::collections::Bound was stabilized in Rust 1.17
// but it was moved to core::ops later in Rust 1.26: // but it was moved to core::ops later in Rust 1.26:
// https://doc.rust-lang.org/core/ops/enum.Bound.html // https://doc.rust-lang.org/core/ops/enum.Bound.html
if minor >= 26 { if minor < 26 {
println!("cargo:rustc-cfg=ops_bound"); println!("cargo:rustc-cfg=no_ops_bound");
} else if minor >= 17 && cfg!(feature = "std") { if minor < 17 {
println!("cargo:rustc-cfg=collections_bound"); println!("cargo:rustc-cfg=no_collections_bound");
}
} }
// core::cmp::Reverse stabilized in Rust 1.19: // core::cmp::Reverse stabilized in Rust 1.19:
// https://doc.rust-lang.org/stable/core/cmp/struct.Reverse.html // https://doc.rust-lang.org/stable/core/cmp/struct.Reverse.html
if minor >= 19 { if minor < 19 {
println!("cargo:rustc-cfg=core_reverse"); println!("cargo:rustc-cfg=no_core_reverse");
} }
// CString::into_boxed_c_str and PathBuf::into_boxed_path stabilized in Rust 1.20: // CString::into_boxed_c_str and PathBuf::into_boxed_path stabilized in Rust 1.20:
// https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str // https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str
// https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.into_boxed_path // https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.into_boxed_path
if minor >= 20 { if minor < 20 {
println!("cargo:rustc-cfg=de_boxed_c_str"); println!("cargo:rustc-cfg=no_de_boxed_c_str");
println!("cargo:rustc-cfg=de_boxed_path"); println!("cargo:rustc-cfg=no_de_boxed_path");
} }
// From<Box<T>> for Rc<T> / Arc<T> stabilized in Rust 1.21: // From<Box<T>> for Rc<T> / Arc<T> stabilized in Rust 1.21:
// https://doc.rust-lang.org/std/rc/struct.Rc.html#impl-From<Box<T>> // https://doc.rust-lang.org/std/rc/struct.Rc.html#impl-From<Box<T>>
// https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-From<Box<T>> // https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-From<Box<T>>
if minor >= 21 { if minor < 21 {
println!("cargo:rustc-cfg=de_rc_dst"); println!("cargo:rustc-cfg=no_de_rc_dst");
} }
// Duration available in core since Rust 1.25: // Duration available in core since Rust 1.25:
// https://blog.rust-lang.org/2018/03/29/Rust-1.25.html#library-stabilizations // https://blog.rust-lang.org/2018/03/29/Rust-1.25.html#library-stabilizations
if minor >= 25 { if minor < 25 {
println!("cargo:rustc-cfg=core_duration"); println!("cargo:rustc-cfg=no_core_duration");
} }
// 128-bit integers stabilized in Rust 1.26: // 128-bit integers stabilized in Rust 1.26:
@@ -56,52 +57,56 @@ fn main() {
// Disabled on Emscripten targets before Rust 1.40 since // Disabled on Emscripten targets before Rust 1.40 since
// Emscripten did not support 128-bit integers until Rust 1.40 // Emscripten did not support 128-bit integers until Rust 1.40
// (https://github.com/rust-lang/rust/pull/65251) // (https://github.com/rust-lang/rust/pull/65251)
if minor >= 26 && (!emscripten || minor >= 40) { if minor < 26 || emscripten && minor < 40 {
println!("cargo:rustc-cfg=integer128"); println!("cargo:rustc-cfg=no_integer128");
} }
// Inclusive ranges methods stabilized in Rust 1.27: // Inclusive ranges methods stabilized in Rust 1.27:
// https://github.com/rust-lang/rust/pull/50758 // https://github.com/rust-lang/rust/pull/50758
if minor >= 27 { // Also Iterator::try_for_each:
println!("cargo:rustc-cfg=range_inclusive"); // https://blog.rust-lang.org/2018/06/21/Rust-1.27.html#library-stabilizations
if minor < 27 {
println!("cargo:rustc-cfg=no_range_inclusive");
println!("cargo:rustc-cfg=no_iterator_try_fold");
} }
// Non-zero integers stabilized in Rust 1.28: // Non-zero integers stabilized in Rust 1.28:
// https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#library-stabilizations // https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#library-stabilizations
if minor >= 28 { if minor < 28 {
println!("cargo:rustc-cfg=num_nonzero"); println!("cargo:rustc-cfg=no_num_nonzero");
} }
// Current minimum supported version of serde_derive crate is Rust 1.31. // Current minimum supported version of serde_derive crate is Rust 1.31.
if minor >= 31 { if minor < 31 {
println!("cargo:rustc-cfg=serde_derive"); println!("cargo:rustc-cfg=no_serde_derive");
} }
// TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add // TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add
// stabilized in Rust 1.34: // stabilized in Rust 1.34:
// https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto
// https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations
if minor >= 34 { if minor < 34 {
println!("cargo:rustc-cfg=core_try_from"); println!("cargo:rustc-cfg=no_core_try_from");
println!("cargo:rustc-cfg=num_nonzero_signed"); println!("cargo:rustc-cfg=no_num_nonzero_signed");
println!("cargo:rustc-cfg=systemtime_checked_add"); println!("cargo:rustc-cfg=no_systemtime_checked_add");
}
// Whitelist of archs that support std::sync::atomic module. Ideally we // Whitelist of archs that support std::sync::atomic module. Ideally we
// would use #[cfg(target_has_atomic = "...")] but it is not stable yet. // would use #[cfg(target_has_atomic = "...")] but it is not stable yet.
// Instead this is based on rustc's src/librustc_target/spec/*.rs. // Instead this is based on rustc's compiler/rustc_target/src/spec/*.rs.
let has_atomic64 = target.starts_with("x86_64") let has_atomic64 = target.starts_with("x86_64")
|| target.starts_with("i686") || target.starts_with("i686")
|| target.starts_with("aarch64") || target.starts_with("aarch64")
|| target.starts_with("powerpc64") || target.starts_with("powerpc64")
|| target.starts_with("sparc64") || target.starts_with("sparc64")
|| target.starts_with("mips64el"); || target.starts_with("mips64el")
let has_atomic32 = has_atomic64 || emscripten; || target.starts_with("riscv64");
if has_atomic64 { let has_atomic32 = has_atomic64 || emscripten;
println!("cargo:rustc-cfg=std_atomic64"); if minor < 34 || !has_atomic64 {
} println!("cargo:rustc-cfg=no_std_atomic64");
if has_atomic32 { }
println!("cargo:rustc-cfg=std_atomic"); if minor < 34 || !has_atomic32 {
} println!("cargo:rustc-cfg=no_std_atomic");
} }
} }
+227 -165
View File
@@ -4,7 +4,7 @@ use de::{
Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor, Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor,
}; };
#[cfg(any(core_duration, feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc", not(no_core_duration)))]
use de::MapAccess; use de::MapAccess;
use seed::InPlaceSeed; use seed::InPlaceSeed;
@@ -81,8 +81,34 @@ impl<'de> Deserialize<'de> for bool {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
macro_rules! impl_deserialize_num { macro_rules! impl_deserialize_num {
($ty:ident, $deserialize:ident $($methods:tt)*) => { ($primitive:ident, $nonzero:ident $(cfg($($cfg:tt)*))*, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
impl<'de> Deserialize<'de> for $ty { impl_deserialize_num!($primitive, $deserialize $($method!($($val : $visit)*);)*);
#[cfg(all(not(no_num_nonzero), $($($cfg)*)*))]
impl<'de> Deserialize<'de> for num::$nonzero {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct NonZeroVisitor;
impl<'de> Visitor<'de> for NonZeroVisitor {
type Value = num::$nonzero;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(concat!("a nonzero ", stringify!($primitive)))
}
$($($method!(nonzero $primitive $val : $visit);)*)*
}
deserializer.$deserialize(NonZeroVisitor)
}
}
};
($primitive:ident, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
impl<'de> Deserialize<'de> for $primitive {
#[inline] #[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@@ -91,13 +117,13 @@ macro_rules! impl_deserialize_num {
struct PrimitiveVisitor; struct PrimitiveVisitor;
impl<'de> Visitor<'de> for PrimitiveVisitor { impl<'de> Visitor<'de> for PrimitiveVisitor {
type Value = $ty; type Value = $primitive;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(stringify!($ty)) formatter.write_str(stringify!($primitive))
} }
$($methods)* $($($method!($val : $visit);)*)*
} }
deserializer.$deserialize(PrimitiveVisitor) deserializer.$deserialize(PrimitiveVisitor)
@@ -116,85 +142,149 @@ macro_rules! num_self {
Ok(v) Ok(v)
} }
}; };
(nonzero $primitive:ident $ty:ident : $visit:ident) => {
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
where
E: Error,
{
if let Some(nonzero) = Self::Value::new(v) {
Ok(nonzero)
} else {
Err(Error::invalid_value(Unexpected::Unsigned(0), &self))
}
}
};
} }
macro_rules! num_as_self { macro_rules! num_as_self {
($($ty:ident : $visit:ident)*) => { ($ty:ident : $visit:ident) => {
$( #[inline]
#[inline] fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> where
where E: Error,
E: Error, {
{ Ok(v as Self::Value)
Ok(v as Self::Value) }
};
(nonzero $primitive:ident $ty:ident : $visit:ident) => {
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
where
E: Error,
{
if let Some(nonzero) = Self::Value::new(v as $primitive) {
Ok(nonzero)
} else {
Err(Error::invalid_value(Unexpected::Unsigned(0), &self))
} }
)* }
}; };
} }
macro_rules! int_to_int { macro_rules! int_to_int {
($($ty:ident : $visit:ident)*) => { ($ty:ident : $visit:ident) => {
$( #[inline]
#[inline] fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> where
where E: Error,
E: Error, {
if Self::Value::min_value() as i64 <= v as i64
&& v as i64 <= Self::Value::max_value() as i64
{ {
if Self::Value::min_value() as i64 <= v as i64 && v as i64 <= Self::Value::max_value() as i64 { Ok(v as Self::Value)
Ok(v as Self::Value) } else {
} else { Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self)) }
}
};
(nonzero $primitive:ident $ty:ident : $visit:ident) => {
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
where
E: Error,
{
if $primitive::min_value() as i64 <= v as i64
&& v as i64 <= $primitive::max_value() as i64
{
if let Some(nonzero) = Self::Value::new(v as $primitive) {
return Ok(nonzero);
} }
} }
)* Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
}
}; };
} }
macro_rules! int_to_uint { macro_rules! int_to_uint {
($($ty:ident : $visit:ident)*) => { ($ty:ident : $visit:ident) => {
$( #[inline]
#[inline] fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> where
where E: Error,
E: Error, {
{ if 0 <= v && v as u64 <= Self::Value::max_value() as u64 {
if 0 <= v && v as u64 <= Self::Value::max_value() as u64 { Ok(v as Self::Value)
Ok(v as Self::Value) } else {
} else { Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self)) }
}
};
(nonzero $primitive:ident $ty:ident : $visit:ident) => {
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
where
E: Error,
{
if 0 < v && v as u64 <= $primitive::max_value() as u64 {
if let Some(nonzero) = Self::Value::new(v as $primitive) {
return Ok(nonzero);
} }
} }
)* Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
}
}; };
} }
macro_rules! uint_to_self { macro_rules! uint_to_self {
($($ty:ident : $visit:ident)*) => { ($ty:ident : $visit:ident) => {
$( #[inline]
#[inline] fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> where
where E: Error,
E: Error, {
{ if v as u64 <= Self::Value::max_value() as u64 {
if v as u64 <= Self::Value::max_value() as u64 { Ok(v as Self::Value)
Ok(v as Self::Value) } else {
} else { Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self)) }
}
};
(nonzero $primitive:ident $ty:ident : $visit:ident) => {
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
where
E: Error,
{
if v as u64 <= $primitive::max_value() as u64 {
if let Some(nonzero) = Self::Value::new(v as $primitive) {
return Ok(nonzero);
} }
} }
)* Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
}
}; };
} }
impl_deserialize_num! { impl_deserialize_num! {
i8, deserialize_i8 i8, NonZeroI8 cfg(not(no_num_nonzero_signed)), deserialize_i8
num_self!(i8:visit_i8); num_self!(i8:visit_i8);
int_to_int!(i16:visit_i16 i32:visit_i32 i64:visit_i64); int_to_int!(i16:visit_i16 i32:visit_i32 i64:visit_i64);
uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
} }
impl_deserialize_num! { impl_deserialize_num! {
i16, deserialize_i16 i16, NonZeroI16 cfg(not(no_num_nonzero_signed)), deserialize_i16
num_self!(i16:visit_i16); num_self!(i16:visit_i16);
num_as_self!(i8:visit_i8); num_as_self!(i8:visit_i8);
int_to_int!(i32:visit_i32 i64:visit_i64); int_to_int!(i32:visit_i32 i64:visit_i64);
@@ -202,7 +292,7 @@ impl_deserialize_num! {
} }
impl_deserialize_num! { impl_deserialize_num! {
i32, deserialize_i32 i32, NonZeroI32 cfg(not(no_num_nonzero_signed)), deserialize_i32
num_self!(i32:visit_i32); num_self!(i32:visit_i32);
num_as_self!(i8:visit_i8 i16:visit_i16); num_as_self!(i8:visit_i8 i16:visit_i16);
int_to_int!(i64:visit_i64); int_to_int!(i64:visit_i64);
@@ -210,28 +300,28 @@ impl_deserialize_num! {
} }
impl_deserialize_num! { impl_deserialize_num! {
i64, deserialize_i64 i64, NonZeroI64 cfg(not(no_num_nonzero_signed)), deserialize_i64
num_self!(i64:visit_i64); num_self!(i64:visit_i64);
num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32); num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32);
uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
} }
impl_deserialize_num! { impl_deserialize_num! {
isize, deserialize_i64 isize, NonZeroIsize cfg(not(no_num_nonzero_signed)), deserialize_i64
num_as_self!(i8:visit_i8 i16:visit_i16); num_as_self!(i8:visit_i8 i16:visit_i16);
int_to_int!(i32:visit_i32 i64:visit_i64); int_to_int!(i32:visit_i32 i64:visit_i64);
uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
} }
impl_deserialize_num! { impl_deserialize_num! {
u8, deserialize_u8 u8, NonZeroU8, deserialize_u8
num_self!(u8:visit_u8); num_self!(u8:visit_u8);
int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
uint_to_self!(u16:visit_u16 u32:visit_u32 u64:visit_u64); uint_to_self!(u16:visit_u16 u32:visit_u32 u64:visit_u64);
} }
impl_deserialize_num! { impl_deserialize_num! {
u16, deserialize_u16 u16, NonZeroU16, deserialize_u16
num_self!(u16:visit_u16); num_self!(u16:visit_u16);
num_as_self!(u8:visit_u8); num_as_self!(u8:visit_u8);
int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
@@ -239,7 +329,7 @@ impl_deserialize_num! {
} }
impl_deserialize_num! { impl_deserialize_num! {
u32, deserialize_u32 u32, NonZeroU32, deserialize_u32
num_self!(u32:visit_u32); num_self!(u32:visit_u32);
num_as_self!(u8:visit_u8 u16:visit_u16); num_as_self!(u8:visit_u8 u16:visit_u16);
int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
@@ -247,14 +337,14 @@ impl_deserialize_num! {
} }
impl_deserialize_num! { impl_deserialize_num! {
u64, deserialize_u64 u64, NonZeroU64, deserialize_u64
num_self!(u64:visit_u64); num_self!(u64:visit_u64);
num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32); num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32);
int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
} }
impl_deserialize_num! { impl_deserialize_num! {
usize, deserialize_u64 usize, NonZeroUsize, deserialize_u64
num_as_self!(u8:visit_u8 u16:visit_u16); num_as_self!(u8:visit_u8 u16:visit_u16);
int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
uint_to_self!(u32:visit_u32 u64:visit_u64); uint_to_self!(u32:visit_u32 u64:visit_u64);
@@ -277,42 +367,62 @@ impl_deserialize_num! {
} }
serde_if_integer128! { serde_if_integer128! {
impl_deserialize_num! { macro_rules! num_128 {
i128, deserialize_i128 ($ty:ident : $visit:ident) => {
num_self!(i128:visit_i128); fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); where
num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); E: Error,
{
#[inline] if v as i128 >= Self::Value::min_value() as i128
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E> && v as u128 <= Self::Value::max_value() as u128
where {
E: Error, Ok(v as Self::Value)
{ } else {
if v <= i128::max_value() as u128 { Err(Error::invalid_value(
Ok(v as i128) Unexpected::Other(stringify!($ty)),
} else { &self,
Err(Error::invalid_value(Unexpected::Other("u128"), &self)) ))
}
} }
} };
(nonzero $primitive:ident $ty:ident : $visit:ident) => {
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
where
E: Error,
{
if v as i128 >= $primitive::min_value() as i128
&& v as u128 <= $primitive::max_value() as u128
{
if let Some(nonzero) = Self::Value::new(v as $primitive) {
Ok(nonzero)
} else {
Err(Error::invalid_value(Unexpected::Unsigned(0), &self))
}
} else {
Err(Error::invalid_value(
Unexpected::Other(stringify!($ty)),
&self,
))
}
}
};
} }
impl_deserialize_num! { impl_deserialize_num! {
u128, deserialize_u128 i128, NonZeroI128 cfg(not(no_num_nonzero_signed)), deserialize_i128
num_self!(i128:visit_i128);
num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
num_128!(u128:visit_u128);
}
impl_deserialize_num! {
u128, NonZeroU128, deserialize_u128
num_self!(u128:visit_u128); num_self!(u128:visit_u128);
num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
num_128!(i128:visit_i128);
#[inline]
fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
where
E: Error,
{
if 0 <= v {
Ok(v as u128)
} else {
Err(Error::invalid_value(Unexpected::Other("i128"), &self))
}
}
} }
} }
@@ -637,10 +747,10 @@ macro_rules! forwarded_impl {
} }
} }
#[cfg(all(feature = "std", de_boxed_c_str))] #[cfg(all(feature = "std", not(no_de_boxed_c_str)))]
forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str); forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str);
#[cfg(core_reverse)] #[cfg(not(no_core_reverse))]
forwarded_impl!((T), Reverse<T>, Reverse); forwarded_impl!((T), Reverse<T>, Reverse);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -1604,7 +1714,7 @@ impl<'de> Deserialize<'de> for PathBuf {
} }
} }
#[cfg(all(feature = "std", de_boxed_path))] #[cfg(all(feature = "std", not(no_de_boxed_path)))]
forwarded_impl!((), Box<Path>, PathBuf::into_boxed_path); forwarded_impl!((), Box<Path>, PathBuf::into_boxed_path);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -1685,11 +1795,7 @@ forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice);
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
forwarded_impl!((), Box<str>, String::into_boxed_str); forwarded_impl!((), Box<str>, String::into_boxed_str);
#[cfg(all( #[cfg(all(no_de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
not(de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
forwarded_impl! { forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde. /// This impl requires the [`"rc"`] Cargo feature of Serde.
/// ///
@@ -1701,11 +1807,7 @@ forwarded_impl! {
(T), Arc<T>, Arc::new (T), Arc<T>, Arc::new
} }
#[cfg(all( #[cfg(all(no_de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
not(de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
forwarded_impl! { forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde. /// This impl requires the [`"rc"`] Cargo feature of Serde.
/// ///
@@ -1772,7 +1874,11 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))] #[cfg(all(
not(no_de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
macro_rules! box_forwarded_impl { macro_rules! box_forwarded_impl {
( (
$(#[doc = $doc:tt])* $(#[doc = $doc:tt])*
@@ -1793,7 +1899,11 @@ macro_rules! box_forwarded_impl {
}; };
} }
#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))] #[cfg(all(
not(no_de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
box_forwarded_impl! { box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde. /// This impl requires the [`"rc"`] Cargo feature of Serde.
/// ///
@@ -1805,7 +1915,11 @@ box_forwarded_impl! {
Rc Rc
} }
#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))] #[cfg(all(
not(no_de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
box_forwarded_impl! { box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde. /// This impl requires the [`"rc"`] Cargo feature of Serde.
/// ///
@@ -1849,7 +1963,7 @@ forwarded_impl!((T), RwLock<T>, RwLock::new);
// secs: u64, // secs: u64,
// nanos: u32, // nanos: u32,
// } // }
#[cfg(any(core_duration, feature = "std"))] #[cfg(any(feature = "std", not(no_core_duration)))]
impl<'de> Deserialize<'de> for Duration { impl<'de> Deserialize<'de> for Duration {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@@ -2127,11 +2241,11 @@ impl<'de> Deserialize<'de> for SystemTime {
const FIELDS: &'static [&'static str] = &["secs_since_epoch", "nanos_since_epoch"]; const FIELDS: &'static [&'static str] = &["secs_since_epoch", "nanos_since_epoch"];
let duration = try!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor)); let duration = try!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor));
#[cfg(systemtime_checked_add)] #[cfg(not(no_systemtime_checked_add))]
let ret = UNIX_EPOCH let ret = UNIX_EPOCH
.checked_add(duration) .checked_add(duration)
.ok_or_else(|| D::Error::custom("overflow deserializing SystemTime")); .ok_or_else(|| D::Error::custom("overflow deserializing SystemTime"));
#[cfg(not(systemtime_checked_add))] #[cfg(no_systemtime_checked_add)]
let ret = Ok(UNIX_EPOCH + duration); let ret = Ok(UNIX_EPOCH + duration);
ret ret
} }
@@ -2167,7 +2281,7 @@ where
} }
} }
#[cfg(range_inclusive)] #[cfg(not(no_range_inclusive))]
impl<'de, Idx> Deserialize<'de> for RangeInclusive<Idx> impl<'de, Idx> Deserialize<'de> for RangeInclusive<Idx>
where where
Idx: Deserialize<'de>, Idx: Deserialize<'de>,
@@ -2319,7 +2433,7 @@ mod range {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(ops_bound, collections_bound))] #[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
impl<'de, T> Deserialize<'de> for Bound<T> impl<'de, T> Deserialize<'de> for Bound<T>
where where
T: Deserialize<'de>, T: Deserialize<'de>,
@@ -2427,58 +2541,6 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
macro_rules! nonzero_integers {
( $( $T: ident, )+ ) => {
$(
#[cfg(num_nonzero)]
impl<'de> Deserialize<'de> for num::$T {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value = try!(Deserialize::deserialize(deserializer));
match <num::$T>::new(value) {
Some(nonzero) => Ok(nonzero),
None => Err(Error::custom("expected a non-zero value")),
}
}
}
)+
};
}
nonzero_integers! {
NonZeroU8,
NonZeroU16,
NonZeroU32,
NonZeroU64,
NonZeroUsize,
}
#[cfg(num_nonzero_signed)]
nonzero_integers! {
NonZeroI8,
NonZeroI16,
NonZeroI32,
NonZeroI64,
NonZeroIsize,
}
// Currently 128-bit integers do not work on Emscripten targets so we need an
// additional `#[cfg]`
serde_if_integer128! {
nonzero_integers! {
NonZeroU128,
}
#[cfg(num_nonzero_signed)]
nonzero_integers! {
NonZeroI128,
}
}
////////////////////////////////////////////////////////////////////////////////
impl<'de, T, E> Deserialize<'de> for Result<T, E> impl<'de, T, E> Deserialize<'de> for Result<T, E>
where where
T: Deserialize<'de>, T: Deserialize<'de>,
@@ -2599,7 +2661,7 @@ where
} }
} }
#[cfg(all(feature = "std", std_atomic))] #[cfg(all(feature = "std", not(no_std_atomic)))]
macro_rules! atomic_impl { macro_rules! atomic_impl {
($($ty:ident)*) => { ($($ty:ident)*) => {
$( $(
@@ -2615,14 +2677,14 @@ macro_rules! atomic_impl {
}; };
} }
#[cfg(all(feature = "std", std_atomic))] #[cfg(all(feature = "std", not(no_std_atomic)))]
atomic_impl! { atomic_impl! {
AtomicBool AtomicBool
AtomicI8 AtomicI16 AtomicI32 AtomicIsize AtomicI8 AtomicI16 AtomicI32 AtomicIsize
AtomicU8 AtomicU16 AtomicU32 AtomicUsize AtomicU8 AtomicU16 AtomicU32 AtomicUsize
} }
#[cfg(all(feature = "std", std_atomic64))] #[cfg(all(feature = "std", not(no_std_atomic64)))]
atomic_impl! { atomic_impl! {
AtomicI64 AtomicU64 AtomicI64 AtomicU64
} }
+16 -2
View File
@@ -1213,6 +1213,20 @@ pub trait Deserializer<'de>: Sized {
fn is_human_readable(&self) -> bool { fn is_human_readable(&self) -> bool {
true true
} }
// Not public API.
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
#[doc(hidden)]
fn __deserialize_content<V>(
self,
_: ::actually_private::T,
visitor: V,
) -> Result<::private::de::Content<'de>, Self::Error>
where
V: Visitor<'de, Value = ::private::de::Content<'de>>,
{
self.deserialize_any(visitor)
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -1714,7 +1728,7 @@ pub trait SeqAccess<'de> {
} }
} }
impl<'de, 'a, A> SeqAccess<'de> for &'a mut A impl<'de, 'a, A: ?Sized> SeqAccess<'de> for &'a mut A
where where
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
@@ -1867,7 +1881,7 @@ pub trait MapAccess<'de> {
} }
} }
impl<'de, 'a, A> MapAccess<'de> for &'a mut A impl<'de, 'a, A: ?Sized> MapAccess<'de> for &'a mut A
where where
A: MapAccess<'de>, A: MapAccess<'de>,
{ {
+2 -2
View File
@@ -66,7 +66,7 @@
/// ($($tt:tt)*) => {}; /// ($($tt:tt)*) => {};
/// } /// }
/// ``` /// ```
#[cfg(integer128)] #[cfg(not(no_integer128))]
#[macro_export] #[macro_export]
macro_rules! serde_if_integer128 { macro_rules! serde_if_integer128 {
($($tt:tt)*) => { ($($tt:tt)*) => {
@@ -74,7 +74,7 @@ macro_rules! serde_if_integer128 {
}; };
} }
#[cfg(not(integer128))] #[cfg(no_integer128)]
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! serde_if_integer128 { macro_rules! serde_if_integer128 {
+18 -12
View File
@@ -60,7 +60,7 @@
//! //!
//! [JSON]: https://github.com/serde-rs/json //! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/servo/bincode //! [Bincode]: https://github.com/servo/bincode
//! [CBOR]: https://github.com/pyfisch/cbor //! [CBOR]: https://github.com/enarx/ciborium
//! [YAML]: https://github.com/dtolnay/serde-yaml //! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust //! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs //! [TOML]: https://github.com/alexcrichton/toml-rs
@@ -73,7 +73,7 @@
//! [URL]: https://docs.rs/serde_qs //! [URL]: https://docs.rs/serde_qs
//! [Envy]: https://github.com/softprops/envy //! [Envy]: https://github.com/softprops/envy
//! [Envy Store]: https://github.com/softprops/envy-store //! [Envy Store]: https://github.com/softprops/envy-store
//! [Cargo]: http://doc.crates.io/manifest.html //! [Cargo]: https://doc.rust-lang.org/cargo/reference/manifest.html
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html //! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html
//! [S-expressions]: https://github.com/rotty/lexpr-rs //! [S-expressions]: https://github.com/rotty/lexpr-rs
//! [D-Bus]: https://docs.rs/zvariant //! [D-Bus]: https://docs.rs/zvariant
@@ -84,7 +84,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here. // Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.128")] #![doc(html_root_url = "https://docs.rs/serde/1.0.135")]
// Support using Serde without the standard library! // Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and // Unstable functionality only if the user asks for it. For tracking and
@@ -94,13 +94,14 @@
#![cfg_attr(feature = "unstable", feature(never_type))] #![cfg_attr(feature = "unstable", feature(never_type))]
#![allow(unknown_lints, bare_trait_objects, deprecated)] #![allow(unknown_lints, bare_trait_objects, deprecated)]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy and clippy_pedantic lints // Ignored clippy and clippy_pedantic lints
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
allow( allow(
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704 // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
unnested_or_patterns, unnested_or_patterns,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/7768
semicolon_if_nothing_returned,
// not available in our oldest supported compiler // not available in our oldest supported compiler
checked_conversions, checked_conversions,
empty_enum, empty_enum,
@@ -157,7 +158,7 @@ mod lib {
pub use std::*; pub use std::*;
} }
pub use self::core::{cmp, iter, mem, num, slice, str}; pub use self::core::{cmp, iter, mem, num, ptr, slice, str};
pub use self::core::{f32, f64}; pub use self::core::{f32, f64};
pub use self::core::{i16, i32, i64, i8, isize}; pub use self::core::{i16, i32, i64, i8, isize};
pub use self::core::{u16, u32, u64, u8, usize}; pub use self::core::{u16, u32, u64, u8, usize};
@@ -226,27 +227,27 @@ mod lib {
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::time::{SystemTime, UNIX_EPOCH}; pub use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(all(feature = "std", collections_bound))] #[cfg(all(feature = "std", not(no_collections_bound), no_ops_bound))]
pub use std::collections::Bound; pub use std::collections::Bound;
#[cfg(core_reverse)] #[cfg(not(no_core_reverse))]
pub use self::core::cmp::Reverse; pub use self::core::cmp::Reverse;
#[cfg(ops_bound)] #[cfg(not(no_ops_bound))]
pub use self::core::ops::Bound; pub use self::core::ops::Bound;
#[cfg(range_inclusive)] #[cfg(not(no_range_inclusive))]
pub use self::core::ops::RangeInclusive; pub use self::core::ops::RangeInclusive;
#[cfg(all(feature = "std", std_atomic))] #[cfg(all(feature = "std", not(no_std_atomic)))]
pub use std::sync::atomic::{ pub use std::sync::atomic::{
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8, AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
AtomicUsize, Ordering, AtomicUsize, Ordering,
}; };
#[cfg(all(feature = "std", std_atomic64))] #[cfg(all(feature = "std", not(no_std_atomic64)))]
pub use std::sync::atomic::{AtomicI64, AtomicU64}; pub use std::sync::atomic::{AtomicI64, AtomicU64};
#[cfg(any(core_duration, feature = "std"))] #[cfg(any(feature = "std", not(no_core_duration)))]
pub use self::core::time::Duration; pub use self::core::time::Duration;
} }
@@ -294,3 +295,8 @@ extern crate serde_derive;
#[cfg(feature = "serde_derive")] #[cfg(feature = "serde_derive")]
#[doc(hidden)] #[doc(hidden)]
pub use serde_derive::*; pub use serde_derive::*;
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
mod actually_private {
pub struct T;
}
+27 -2
View File
@@ -206,6 +206,7 @@ mod content {
use lib::*; use lib::*;
use __private::size_hint; use __private::size_hint;
use actually_private;
use de::{ use de::{
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny, self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
MapAccess, SeqAccess, Unexpected, Visitor, MapAccess, SeqAccess, Unexpected, Visitor,
@@ -215,7 +216,7 @@ mod content {
/// deserializing untagged enums and internally tagged enums. /// deserializing untagged enums and internally tagged enums.
/// ///
/// Not public API. Use serde-value instead. /// Not public API. Use serde-value instead.
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum Content<'de> { pub enum Content<'de> {
Bool(bool), Bool(bool),
@@ -294,7 +295,7 @@ mod content {
// Untagged and internally tagged enums are only supported in // Untagged and internally tagged enums are only supported in
// self-describing formats. // self-describing formats.
let visitor = ContentVisitor { value: PhantomData }; let visitor = ContentVisitor { value: PhantomData };
deserializer.deserialize_any(visitor) deserializer.__deserialize_content(actually_private::T, visitor)
} }
} }
@@ -1427,6 +1428,18 @@ mod content {
drop(self); drop(self);
visitor.visit_unit() visitor.visit_unit()
} }
fn __deserialize_content<V>(
self,
_: actually_private::T,
visitor: V,
) -> Result<Content<'de>, Self::Error>
where
V: Visitor<'de, Value = Content<'de>>,
{
let _ = visitor;
Ok(self.content)
}
} }
impl<'de, E> ContentDeserializer<'de, E> { impl<'de, E> ContentDeserializer<'de, E> {
@@ -2138,6 +2151,18 @@ mod content {
{ {
visitor.visit_unit() visitor.visit_unit()
} }
fn __deserialize_content<V>(
self,
_: actually_private::T,
visitor: V,
) -> Result<Content<'de>, Self::Error>
where
V: Visitor<'de, Value = Content<'de>>,
{
let _ = visitor;
Ok(self.content.clone())
}
} }
impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> { impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> {
+4 -3
View File
@@ -1,6 +1,6 @@
#[cfg(serde_derive)] #[cfg(not(no_serde_derive))]
pub mod de; pub mod de;
#[cfg(serde_derive)] #[cfg(not(no_serde_derive))]
pub mod ser; pub mod ser;
pub mod size_hint; pub mod size_hint;
@@ -14,6 +14,7 @@ pub use lib::default::Default;
pub use lib::fmt::{self, Formatter}; pub use lib::fmt::{self, Formatter};
pub use lib::marker::PhantomData; pub use lib::marker::PhantomData;
pub use lib::option::Option::{self, None, Some}; pub use lib::option::Option::{self, None, Some};
pub use lib::ptr;
pub use lib::result::Result::{self, Err, Ok}; pub use lib::result::Result::{self, Err, Ok};
pub use self::string::from_utf8_lossy; pub use self::string::from_utf8_lossy;
@@ -21,7 +22,7 @@ pub use self::string::from_utf8_lossy;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
pub use lib::{ToString, Vec}; pub use lib::{ToString, Vec};
#[cfg(core_try_from)] #[cfg(not(no_core_try_from))]
pub use lib::convert::TryFrom; pub use lib::convert::TryFrom;
mod string { mod string {
+11 -10
View File
@@ -239,7 +239,7 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(range_inclusive)] #[cfg(not(no_range_inclusive))]
impl<Idx> Serialize for RangeInclusive<Idx> impl<Idx> Serialize for RangeInclusive<Idx>
where where
Idx: Serialize, Idx: Serialize,
@@ -258,7 +258,7 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(ops_bound, collections_bound))] #[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
impl<T> Serialize for Bound<T> impl<T> Serialize for Bound<T>
where where
T: Serialize, T: Serialize,
@@ -467,7 +467,7 @@ where
macro_rules! nonzero_integers { macro_rules! nonzero_integers {
( $( $T: ident, )+ ) => { ( $( $T: ident, )+ ) => {
$( $(
#[cfg(num_nonzero)] #[cfg(not(no_num_nonzero))]
impl Serialize for num::$T { impl Serialize for num::$T {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@@ -488,7 +488,7 @@ nonzero_integers! {
NonZeroUsize, NonZeroUsize,
} }
#[cfg(num_nonzero_signed)] #[cfg(not(no_num_nonzero_signed))]
nonzero_integers! { nonzero_integers! {
NonZeroI8, NonZeroI8,
NonZeroI16, NonZeroI16,
@@ -504,7 +504,7 @@ serde_if_integer128! {
NonZeroU128, NonZeroU128,
} }
#[cfg(num_nonzero_signed)] #[cfg(not(no_num_nonzero_signed))]
nonzero_integers! { nonzero_integers! {
NonZeroI128, NonZeroI128,
} }
@@ -591,7 +591,7 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(core_duration, feature = "std"))] #[cfg(any(feature = "std", not(no_core_duration)))]
impl Serialize for Duration { impl Serialize for Duration {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@@ -890,7 +890,7 @@ where
} }
} }
#[cfg(core_reverse)] #[cfg(not(no_core_reverse))]
impl<T> Serialize for Reverse<T> impl<T> Serialize for Reverse<T>
where where
T: Serialize, T: Serialize,
@@ -906,7 +906,7 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(all(feature = "std", std_atomic))] #[cfg(all(feature = "std", not(no_std_atomic)))]
macro_rules! atomic_impl { macro_rules! atomic_impl {
($($ty:ident)*) => { ($($ty:ident)*) => {
$( $(
@@ -915,6 +915,7 @@ macro_rules! atomic_impl {
where where
S: Serializer, S: Serializer,
{ {
// Matches the atomic ordering used in libcore for the Debug impl
self.load(Ordering::SeqCst).serialize(serializer) self.load(Ordering::SeqCst).serialize(serializer)
} }
} }
@@ -922,14 +923,14 @@ macro_rules! atomic_impl {
} }
} }
#[cfg(all(feature = "std", std_atomic))] #[cfg(all(feature = "std", not(no_std_atomic)))]
atomic_impl! { atomic_impl! {
AtomicBool AtomicBool
AtomicI8 AtomicI16 AtomicI32 AtomicIsize AtomicI8 AtomicI16 AtomicI32 AtomicIsize
AtomicU8 AtomicU16 AtomicU32 AtomicUsize AtomicU8 AtomicU16 AtomicU32 AtomicUsize
} }
#[cfg(all(feature = "std", std_atomic64))] #[cfg(all(feature = "std", not(no_std_atomic64)))]
atomic_impl! { atomic_impl! {
AtomicI64 AtomicU64 AtomicI64 AtomicU64
} }
+26 -4
View File
@@ -1279,9 +1279,20 @@ pub trait Serializer: Sized {
{ {
let iter = iter.into_iter(); let iter = iter.into_iter();
let mut serializer = try!(self.serialize_seq(iterator_len_hint(&iter))); let mut serializer = try!(self.serialize_seq(iterator_len_hint(&iter)));
for item in iter {
try!(serializer.serialize_element(&item)); #[cfg(not(no_iterator_try_fold))]
{
let mut iter = iter;
try!(iter.try_for_each(|item| serializer.serialize_element(&item)));
} }
#[cfg(no_iterator_try_fold)]
{
for item in iter {
try!(serializer.serialize_element(&item));
}
}
serializer.end() serializer.end()
} }
@@ -1319,9 +1330,20 @@ pub trait Serializer: Sized {
{ {
let iter = iter.into_iter(); let iter = iter.into_iter();
let mut serializer = try!(self.serialize_map(iterator_len_hint(&iter))); let mut serializer = try!(self.serialize_map(iterator_len_hint(&iter)));
for (key, value) in iter {
try!(serializer.serialize_entry(&key, &value)); #[cfg(not(no_iterator_try_fold))]
{
let mut iter = iter;
try!(iter.try_for_each(|(key, value)| serializer.serialize_entry(&key, &value)));
} }
#[cfg(no_iterator_try_fold)]
{
for (key, value) in iter {
try!(serializer.serialize_entry(&key, &value));
}
}
serializer.end() serializer.end()
} }
+2 -1
View File
@@ -1,7 +1,8 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.128" # remember to update html_root_url version = "1.0.135" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
rust-version = "1.31"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
homepage = "https://serde.rs" homepage = "https://serde.rs"
+6
View File
@@ -16,6 +16,12 @@ fn main() {
if minor >= 37 { if minor >= 37 {
println!("cargo:rustc-cfg=underscore_consts"); println!("cargo:rustc-cfg=underscore_consts");
} }
// The ptr::addr_of! macro stabilized in Rust 1.51:
// https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html#stabilized-apis
if minor >= 51 {
println!("cargo:rustc-cfg=ptr_addr_of");
}
} }
fn rustc_minor_version() -> Option<u32> { fn rustc_minor_version() -> Option<u32> {
+2 -2
View File
@@ -50,7 +50,7 @@ pub fn with_where_predicates_from_fields(
.data .data
.all_fields() .all_fields()
.filter_map(|field| from_field(&field.attrs)) .filter_map(|field| from_field(&field.attrs))
.flat_map(|predicates| predicates.to_vec()); .flat_map(<[syn::WherePredicate]>::to_vec);
let mut generics = generics.clone(); let mut generics = generics.clone();
generics.make_where_clause().predicates.extend(predicates); generics.make_where_clause().predicates.extend(predicates);
@@ -72,7 +72,7 @@ pub fn with_where_predicates_from_variants(
let predicates = variants let predicates = variants
.iter() .iter()
.filter_map(|variant| from_variant(&variant.attrs)) .filter_map(|variant| from_variant(&variant.attrs))
.flat_map(|predicates| predicates.to_vec()); .flat_map(<[syn::WherePredicate]>::to_vec);
let mut generics = generics.clone(); let mut generics = generics.clone();
generics.make_where_clause().predicates.extend(predicates); generics.make_where_clause().predicates.extend(predicates);
+40 -18
View File
@@ -36,7 +36,7 @@ pub fn expand_derive_deserialize(
let impl_block = if let Some(remote) = cont.attrs.remote() { let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis; let vis = &input.vis;
let used = pretend::pretend_used(&cont); let used = pretend::pretend_used(&cont, params.is_packed);
quote! { quote! {
impl #de_impl_generics #ident #ty_generics #where_clause { impl #de_impl_generics #ident #ty_generics #where_clause {
#vis fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result<#remote #ty_generics, __D::Error> #vis fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result<#remote #ty_generics, __D::Error>
@@ -125,6 +125,9 @@ struct Parameters {
/// At least one field has a serde(getter) attribute, implying that the /// At least one field has a serde(getter) attribute, implying that the
/// remote type has a private field. /// remote type has a private field.
has_getter: bool, has_getter: bool,
/// Type has a repr(packed) attribute.
is_packed: bool,
} }
impl Parameters { impl Parameters {
@@ -137,6 +140,7 @@ impl Parameters {
let borrowed = borrowed_lifetimes(cont); let borrowed = borrowed_lifetimes(cont);
let generics = build_generics(cont, &borrowed); let generics = build_generics(cont, &borrowed);
let has_getter = cont.data.has_getter(); let has_getter = cont.data.has_getter();
let is_packed = cont.attrs.is_packed();
Parameters { Parameters {
local, local,
@@ -144,6 +148,7 @@ impl Parameters {
generics, generics,
borrowed, borrowed,
has_getter, has_getter,
is_packed,
} }
} }
@@ -1453,7 +1458,7 @@ fn deserialize_adjacently_tagged_enum(
while let _serde::__private::Some(__k) = #next_key { while let _serde::__private::Some(__k) = #next_key {
match __k { match __k {
_serde::__private::de::TagContentOtherField::Other => { _serde::__private::de::TagContentOtherField::Other => {
try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map));
continue; continue;
}, },
_serde::__private::de::TagContentOtherField::Tag => { _serde::__private::de::TagContentOtherField::Tag => {
@@ -1728,6 +1733,8 @@ fn deserialize_externally_tagged_variant(
} }
} }
// Generates significant part of the visit_seq and visit_map bodies of visitors
// for the variants of internally tagged enum.
fn deserialize_internally_tagged_variant( fn deserialize_internally_tagged_variant(
params: &Parameters, params: &Parameters,
variant: &Variant, variant: &Variant,
@@ -1779,11 +1786,9 @@ fn deserialize_untagged_variant(
deserializer: TokenStream, deserializer: TokenStream,
) -> Fragment { ) -> Fragment {
if let Some(path) = variant.attrs.deserialize_with() { if let Some(path) = variant.attrs.deserialize_with() {
let (wrapper, wrapper_ty, unwrap_fn) = wrap_deserialize_variant_with(params, variant, path); let unwrap_fn = unwrap_to_variant_closure(params, variant, false);
return quote_block! { return quote_block! {
#wrapper _serde::__private::Result::map(#path(#deserializer), #unwrap_fn)
_serde::__private::Result::map(
<#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer), #unwrap_fn)
}; };
} }
@@ -2883,44 +2888,61 @@ fn wrap_deserialize_variant_with(
variant: &Variant, variant: &Variant,
deserialize_with: &syn::ExprPath, deserialize_with: &syn::ExprPath,
) -> (TokenStream, TokenStream, TokenStream) { ) -> (TokenStream, TokenStream, TokenStream) {
let this = &params.this;
let variant_ident = &variant.ident;
let field_tys = variant.fields.iter().map(|field| field.ty); let field_tys = variant.fields.iter().map(|field| field.ty);
let (wrapper, wrapper_ty) = let (wrapper, wrapper_ty) =
wrap_deserialize_with(params, &quote!((#(#field_tys),*)), deserialize_with); wrap_deserialize_with(params, &quote!((#(#field_tys),*)), deserialize_with);
let unwrap_fn = unwrap_to_variant_closure(params, variant, true);
(wrapper, wrapper_ty, unwrap_fn)
}
// Generates closure that converts single input parameter to the final value.
fn unwrap_to_variant_closure(
params: &Parameters,
variant: &Variant,
with_wrapper: bool,
) -> TokenStream {
let this = &params.this;
let variant_ident = &variant.ident;
let (arg, wrapper) = if with_wrapper {
(quote! { __wrap }, quote! { __wrap.value })
} else {
let field_tys = variant.fields.iter().map(|field| field.ty);
(quote! { __wrap: (#(#field_tys),*) }, quote! { __wrap })
};
let field_access = (0..variant.fields.len()).map(|n| { let field_access = (0..variant.fields.len()).map(|n| {
Member::Unnamed(Index { Member::Unnamed(Index {
index: n as u32, index: n as u32,
span: Span::call_site(), span: Span::call_site(),
}) })
}); });
let unwrap_fn = match variant.style {
match variant.style {
Style::Struct if variant.fields.len() == 1 => { Style::Struct if variant.fields.len() == 1 => {
let member = &variant.fields[0].member; let member = &variant.fields[0].member;
quote! { quote! {
|__wrap| #this::#variant_ident { #member: __wrap.value } |#arg| #this::#variant_ident { #member: #wrapper }
} }
} }
Style::Struct => { Style::Struct => {
let members = variant.fields.iter().map(|field| &field.member); let members = variant.fields.iter().map(|field| &field.member);
quote! { quote! {
|__wrap| #this::#variant_ident { #(#members: __wrap.value.#field_access),* } |#arg| #this::#variant_ident { #(#members: #wrapper.#field_access),* }
} }
} }
Style::Tuple => quote! { Style::Tuple => quote! {
|__wrap| #this::#variant_ident(#(__wrap.value.#field_access),*) |#arg| #this::#variant_ident(#(#wrapper.#field_access),*)
}, },
Style::Newtype => quote! { Style::Newtype => quote! {
|__wrap| #this::#variant_ident(__wrap.value) |#arg| #this::#variant_ident(#wrapper)
}, },
Style::Unit => quote! { Style::Unit => quote! {
|__wrap| #this::#variant_ident |#arg| #this::#variant_ident
}, },
}; }
(wrapper, wrapper_ty, unwrap_fn)
} }
fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment { fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
+2 -2
View File
@@ -13,9 +13,8 @@
//! //!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.128")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.135")]
#![allow(unknown_lints, bare_trait_objects)] #![allow(unknown_lints, bare_trait_objects)]
#![deny(clippy::all, clippy::pedantic)]
// Ignored clippy lints // Ignored clippy lints
#![allow( #![allow(
// clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054 // clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054
@@ -44,6 +43,7 @@
clippy::indexing_slicing, clippy::indexing_slicing,
clippy::items_after_statements, clippy::items_after_statements,
clippy::let_underscore_drop, clippy::let_underscore_drop,
clippy::manual_assert,
clippy::map_err_ignore, clippy::map_err_ignore,
clippy::match_same_arms, clippy::match_same_arms,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984 // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
+103 -42
View File
@@ -1,7 +1,7 @@
use proc_macro2::{Span, TokenStream}; use proc_macro2::TokenStream;
use syn::Ident; use quote::format_ident;
use internals::ast::{Container, Data, Field, Style}; use internals::ast::{Container, Data, Field, Style, Variant};
// Suppress dead_code warnings that would otherwise appear when using a remote // Suppress dead_code warnings that would otherwise appear when using a remote
// derive. Other than this pretend code, a struct annotated with remote derive // derive. Other than this pretend code, a struct annotated with remote derive
@@ -20,8 +20,8 @@ use internals::ast::{Container, Data, Field, Style};
// 8 | enum EnumDef { V } // 8 | enum EnumDef { V }
// | ^ // | ^
// //
pub fn pretend_used(cont: &Container) -> TokenStream { pub fn pretend_used(cont: &Container, is_packed: bool) -> TokenStream {
let pretend_fields = pretend_fields_used(cont); let pretend_fields = pretend_fields_used(cont, is_packed);
let pretend_variants = pretend_variants_used(cont); let pretend_variants = pretend_variants_used(cont);
quote! { quote! {
@@ -32,49 +32,117 @@ pub fn pretend_used(cont: &Container) -> TokenStream {
// For structs with named fields, expands to: // For structs with named fields, expands to:
// //
// match None::<&T> {
// Some(T { a: __v0, b: __v1 }) => {}
// _ => {}
// }
//
// For packed structs on sufficiently new rustc, expands to:
//
// match None::<&T> {
// Some(__v @ T { a: _, b: _ }) => {
// let _ = addr_of!(__v.a);
// let _ = addr_of!(__v.b);
// }
// _ => {}
// }
//
// For packed structs on older rustc, we assume Sized and !Drop, and expand to:
//
// match None::<T> { // match None::<T> {
// Some(T { a: ref __v0, b: ref __v1 }) => {} // Some(T { a: __v0, b: __v1 }) => {}
// _ => {} // _ => {}
// } // }
// //
// For enums, expands to the following but only including struct variants: // For enums, expands to the following but only including struct variants:
// //
// match None::<T> { // match None::<&T> {
// Some(T::A { a: ref __v0 }) => {} // Some(T::A { a: __v0 }) => {}
// Some(T::B { b: ref __v0 }) => {} // Some(T::B { b: __v0 }) => {}
// _ => {} // _ => {}
// } // }
// //
// The `ref` is important in case the user has written a Drop impl on their fn pretend_fields_used(cont: &Container, is_packed: bool) -> TokenStream {
// type. Rust does not allow destructuring a struct or enum that has a Drop match &cont.data {
// impl. Data::Enum(variants) => pretend_fields_used_enum(cont, variants),
fn pretend_fields_used(cont: &Container) -> TokenStream { Data::Struct(Style::Struct, fields) => {
if is_packed {
pretend_fields_used_struct_packed(cont, fields)
} else {
pretend_fields_used_struct(cont, fields)
}
}
Data::Struct(_, _) => quote!(),
}
}
fn pretend_fields_used_struct(cont: &Container, fields: &[Field]) -> TokenStream {
let type_ident = &cont.ident; let type_ident = &cont.ident;
let (_, ty_generics, _) = cont.generics.split_for_impl(); let (_, ty_generics, _) = cont.generics.split_for_impl();
let patterns = match &cont.data { let members = fields.iter().map(|field| &field.member);
Data::Enum(variants) => variants let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
.iter()
.filter_map(|variant| match variant.style {
Style::Struct => {
let variant_ident = &variant.ident;
let pat = struct_pattern(&variant.fields);
Some(quote!(#type_ident::#variant_ident #pat))
}
_ => None,
})
.collect::<Vec<_>>(),
Data::Struct(Style::Struct, fields) => {
let pat = struct_pattern(fields);
vec![quote!(#type_ident #pat)]
}
Data::Struct(_, _) => {
return quote!();
}
};
quote! { quote! {
match _serde::__private::None::<#type_ident #ty_generics> { match _serde::__private::None::<&#type_ident #ty_generics> {
_serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {}
_ => {}
}
}
}
fn pretend_fields_used_struct_packed(cont: &Container, fields: &[Field]) -> TokenStream {
let type_ident = &cont.ident;
let (_, ty_generics, _) = cont.generics.split_for_impl();
let members = fields.iter().map(|field| &field.member).collect::<Vec<_>>();
#[cfg(ptr_addr_of)]
{
quote! {
match _serde::__private::None::<&#type_ident #ty_generics> {
_serde::__private::Some(__v @ #type_ident { #(#members: _),* }) => {
#(
let _ = _serde::__private::ptr::addr_of!(__v.#members);
)*
}
_ => {}
}
}
}
#[cfg(not(ptr_addr_of))]
{
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
quote! {
match _serde::__private::None::<#type_ident #ty_generics> {
_serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {}
_ => {}
}
}
}
}
fn pretend_fields_used_enum(cont: &Container, variants: &[Variant]) -> TokenStream {
let type_ident = &cont.ident;
let (_, ty_generics, _) = cont.generics.split_for_impl();
let patterns = variants
.iter()
.filter_map(|variant| match variant.style {
Style::Struct => {
let variant_ident = &variant.ident;
let members = variant.fields.iter().map(|field| &field.member);
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
Some(quote!(#type_ident::#variant_ident { #(#members: #placeholders),* }))
}
_ => None,
})
.collect::<Vec<_>>();
quote! {
match _serde::__private::None::<&#type_ident #ty_generics> {
#( #(
_serde::__private::Some(#patterns) => {} _serde::__private::Some(#patterns) => {}
)* )*
@@ -107,7 +175,7 @@ fn pretend_variants_used(cont: &Container) -> TokenStream {
let cases = variants.iter().map(|variant| { let cases = variants.iter().map(|variant| {
let variant_ident = &variant.ident; let variant_ident = &variant.ident;
let placeholders = &(0..variant.fields.len()) let placeholders = &(0..variant.fields.len())
.map(|i| Ident::new(&format!("__v{}", i), Span::call_site())) .map(|i| format_ident!("__v{}", i))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let pat = match variant.style { let pat = match variant.style {
@@ -131,10 +199,3 @@ fn pretend_variants_used(cont: &Container) -> TokenStream {
quote!(#(#cases)*) quote!(#(#cases)*)
} }
fn struct_pattern(fields: &[Field]) -> TokenStream {
let members = fields.iter().map(|field| &field.member);
let placeholders =
(0..fields.len()).map(|i| Ident::new(&format!("__v{}", i), Span::call_site()));
quote!({ #(#members: ref #placeholders),* })
}
+1 -1
View File
@@ -30,7 +30,7 @@ pub fn expand_derive_serialize(
let impl_block = if let Some(remote) = cont.attrs.remote() { let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis; let vis = &input.vis;
let used = pretend::pretend_used(&cont); let used = pretend::pretend_used(&cont, params.is_packed);
quote! { quote! {
impl #impl_generics #ident #ty_generics #where_clause { impl #impl_generics #ident #ty_generics #where_clause {
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error> #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error>
+1
View File
@@ -2,6 +2,7 @@
name = "serde_derive_internals" name = "serde_derive_internals"
version = "0.26.0" # remember to update html_root_url version = "0.26.0" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
rust-version = "1.31"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "AST representation used by Serde derive macros. Unstable." description = "AST representation used by Serde derive macros. Unstable."
homepage = "https://serde.rs" homepage = "https://serde.rs"
+1 -1
View File
@@ -1,6 +1,5 @@
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.26.0")] #![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.26.0")]
#![allow(unknown_lints, bare_trait_objects)] #![allow(unknown_lints, bare_trait_objects)]
#![deny(clippy::all, clippy::pedantic)]
// Ignored clippy lints // Ignored clippy lints
#![allow( #![allow(
clippy::cognitive_complexity, clippy::cognitive_complexity,
@@ -23,6 +22,7 @@
clippy::enum_glob_use, clippy::enum_glob_use,
clippy::items_after_statements, clippy::items_after_statements,
clippy::let_underscore_drop, clippy::let_underscore_drop,
clippy::manual_assert,
clippy::match_same_arms, clippy::match_same_arms,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984 // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
clippy::match_wildcard_for_single_variants, clippy::match_wildcard_for_single_variants,
+4 -2
View File
@@ -1,7 +1,8 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "1.0.128" # remember to update html_root_url version = "1.0.135" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
rust-version = "1.15"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations" description = "Token De/Serializer for testing De/Serialize implementations"
homepage = "https://serde.rs" homepage = "https://serde.rs"
@@ -9,7 +10,8 @@ repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde_test/" documentation = "https://docs.serde.rs/serde_test/"
keywords = ["serde", "serialization"] keywords = ["serde", "serialization"]
readme = "crates-io.md" readme = "crates-io.md"
include = ["src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
build = "build.rs"
[dependencies] [dependencies]
serde = { version = "1.0.60", path = "../serde" } serde = { version = "1.0.60", path = "../serde" }
+23 -5
View File
@@ -1,6 +1,6 @@
use std::env; use std::env;
use std::process::Command; use std::process::Command;
use std::str; use std::str::{self, FromStr};
// The rustc-cfg strings below are *not* public API. Please let us know by // The rustc-cfg strings below are *not* public API. Please let us know by
// opening a GitHub issue if your build environment requires some way to enable // opening a GitHub issue if your build environment requires some way to enable
@@ -19,12 +19,30 @@ fn main() {
} }
fn rustc_minor_version() -> Option<u32> { fn rustc_minor_version() -> Option<u32> {
let rustc = env::var_os("RUSTC")?; let rustc = match env::var_os("RUSTC") {
let output = Command::new(rustc).arg("--version").output().ok()?; Some(rustc) => rustc,
let version = str::from_utf8(&output.stdout).ok()?; None => return None,
};
let output = match Command::new(rustc).arg("--version").output() {
Ok(output) => output,
Err(_) => return None,
};
let version = match str::from_utf8(&output.stdout) {
Ok(version) => version,
Err(_) => return None,
};
let mut pieces = version.split('.'); let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") { if pieces.next() != Some("rustc 1") {
return None; return None;
} }
pieces.next()?.parse().ok()
let next = match pieces.next() {
Some(next) => next,
None => return None,
};
u32::from_str(next).ok()
} }
+2 -2
View File
@@ -60,7 +60,7 @@ where
/// ]); /// ]);
/// ``` /// ```
#[cfg_attr(track_caller, track_caller)] #[cfg_attr(track_caller, track_caller)]
pub fn assert_ser_tokens<T>(value: &T, tokens: &[Token]) pub fn assert_ser_tokens<T: ?Sized>(value: &T, tokens: &[Token])
where where
T: Serialize, T: Serialize,
{ {
@@ -113,7 +113,7 @@ where
/// } /// }
/// ``` /// ```
#[cfg_attr(track_caller, track_caller)] #[cfg_attr(track_caller, track_caller)]
pub fn assert_ser_tokens_error<T>(value: &T, tokens: &[Token], error: &str) pub fn assert_ser_tokens_error<T: ?Sized>(value: &T, tokens: &[Token], error: &str)
where where
T: Serialize, T: Serialize,
{ {
+2 -2
View File
@@ -144,9 +144,8 @@
//! # } //! # }
//! ``` //! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.128")] #![doc(html_root_url = "https://docs.rs/serde_test/1.0.135")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy lints // Ignored clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))] #![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))]
// Ignored clippy_pedantic lints // Ignored clippy_pedantic lints
@@ -155,6 +154,7 @@
allow( allow(
cloned_instead_of_copied, cloned_instead_of_copied,
empty_line_after_outer_attr, empty_line_after_outer_attr,
manual_assert,
missing_docs_in_private_items, missing_docs_in_private_items,
missing_panics_doc, missing_panics_doc,
module_name_repetitions, module_name_repetitions,
+1 -1
View File
@@ -23,4 +23,4 @@ rustversion = "1.0"
serde = { path = "../serde", features = ["rc", "derive"] } serde = { path = "../serde", features = ["rc", "derive"] }
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] } serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
serde_test = { path = "../serde_test" } serde_test = { path = "../serde_test" }
trybuild = { version = "1.0.19", features = ["diff"] } trybuild = { version = "1.0.49", features = ["diff"] }
+50 -66
View File
@@ -1,93 +1,77 @@
use serde_test::Token;
use std::iter;
macro_rules! btreeset { macro_rules! btreeset {
() => { () => {
BTreeSet::new() BTreeSet::new()
}; };
($($value:expr),+) => { ($($value:expr),+) => {{
{ let mut set = BTreeSet::new();
let mut set = BTreeSet::new(); $(set.insert($value);)+
$(set.insert($value);)+ set
set }};
}
}
} }
macro_rules! btreemap { macro_rules! btreemap {
() => { () => {
BTreeMap::new() BTreeMap::new()
}; };
($($key:expr => $value:expr),+) => { ($($key:expr => $value:expr),+) => {{
{ let mut map = BTreeMap::new();
let mut map = BTreeMap::new(); $(map.insert($key, $value);)+
$(map.insert($key, $value);)+ map
map }};
}
}
} }
macro_rules! hashset { macro_rules! hashset {
() => { () => {
HashSet::new() HashSet::new()
}; };
($($value:expr),+) => { ($($value:expr),+) => {{
{ let mut set = HashSet::new();
let mut set = HashSet::new(); $(set.insert($value);)+
$(set.insert($value);)+ set
set }};
} ($hasher:ident @ $($value:expr),+) => {{
}; use std::hash::BuildHasherDefault;
($hasher:ident @ $($value:expr),+) => { let mut set = HashSet::with_hasher(BuildHasherDefault::<$hasher>::default());
{ $(set.insert($value);)+
use std::hash::BuildHasherDefault; set
let mut set = HashSet::with_hasher(BuildHasherDefault::<$hasher>::default()); }};
$(set.insert($value);)+
set
}
}
} }
macro_rules! hashmap { macro_rules! hashmap {
() => { () => {
HashMap::new() HashMap::new()
}; };
($($key:expr => $value:expr),+) => { ($($key:expr => $value:expr),+) => {{
{ let mut map = HashMap::new();
let mut map = HashMap::new(); $(map.insert($key, $value);)+
$(map.insert($key, $value);)+ map
map }};
} ($hasher:ident @ $($key:expr => $value:expr),+) => {{
}; use std::hash::BuildHasherDefault;
($hasher:ident @ $($key:expr => $value:expr),+) => { let mut map = HashMap::with_hasher(BuildHasherDefault::<$hasher>::default());
{ $(map.insert($key, $value);)+
use std::hash::BuildHasherDefault; map
let mut map = HashMap::with_hasher(BuildHasherDefault::<$hasher>::default()); }};
$(map.insert($key, $value);)+ }
map
} pub trait SingleTokenIntoIterator {
fn into_iter(self) -> iter::Once<Token>;
}
impl SingleTokenIntoIterator for Token {
fn into_iter(self) -> iter::Once<Token> {
iter::once(self)
} }
} }
macro_rules! seq_impl {
(seq $first:expr,) => {
seq_impl!(seq $first)
};
($first:expr,) => {
seq_impl!($first)
};
(seq $first:expr) => {
$first.into_iter()
};
($first:expr) => {
Some($first).into_iter()
};
(seq $first:expr , $( $elem: tt)*) => {
$first.into_iter().chain(seq!( $($elem)* ))
};
($first:expr , $($elem: tt)*) => {
Some($first).into_iter().chain(seq!( $($elem)* ))
}
}
macro_rules! seq { macro_rules! seq {
($($tt: tt)*) => { ($($elem:expr),* $(,)?) => {{
seq_impl!($($tt)*).collect::<Vec<_>>() use crate::macros::SingleTokenIntoIterator;
}; let mut vec = Vec::new();
$(<Vec<Token> as Extend<Token>>::extend(&mut vec, $elem.into_iter());)*
vec
}};
} }
+1
View File
@@ -3,6 +3,7 @@
clippy::from_over_into, clippy::from_over_into,
// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422 // Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
clippy::nonstandard_macro_braces, clippy::nonstandard_macro_braces,
clippy::too_many_lines,
clippy::trivially_copy_pass_by_ref clippy::trivially_copy_pass_by_ref
)] )]
+2
View File
@@ -1,3 +1,5 @@
#![allow(clippy::items_after_statements, clippy::used_underscore_binding)]
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use serde_test::{assert_de_tokens, assert_de_tokens_error, Token}; use serde_test::{assert_de_tokens, assert_de_tokens_error, Token};
+1748 -1119
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+66
View File
@@ -6,9 +6,14 @@
#![allow( #![allow(
unknown_lints, unknown_lints,
mixed_script_confusables, mixed_script_confusables,
clippy::items_after_statements,
clippy::missing_errors_doc,
clippy::missing_panics_doc,
clippy::must_use_candidate,
// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422 // Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
clippy::nonstandard_macro_braces, clippy::nonstandard_macro_braces,
clippy::ptr_arg, clippy::ptr_arg,
clippy::too_many_lines,
clippy::trivially_copy_pass_by_ref clippy::trivially_copy_pass_by_ref
)] )]
@@ -823,3 +828,64 @@ where
{ {
vec.first().serialize(serializer) vec.first().serialize(serializer)
} }
//////////////////////////////////////////////////////////////////////////
#[derive(Debug, PartialEq, Deserialize)]
#[serde(tag = "tag")]
enum InternallyTagged {
#[serde(deserialize_with = "deserialize_generic")]
Unit,
#[serde(deserialize_with = "deserialize_generic")]
Newtype(i32),
#[serde(deserialize_with = "deserialize_generic")]
Struct { f1: String, f2: u8 },
}
fn deserialize_generic<'de, T, D>(deserializer: D) -> StdResult<T, D::Error>
where
T: Deserialize<'de>,
D: Deserializer<'de>,
{
T::deserialize(deserializer)
}
//////////////////////////////////////////////////////////////////////////
#[repr(packed)]
pub struct RemotePacked {
pub a: u16,
pub b: u32,
}
#[derive(Serialize)]
#[repr(packed)]
#[serde(remote = "RemotePacked")]
pub struct RemotePackedDef {
a: u16,
b: u32,
}
impl Drop for RemotePackedDef {
fn drop(&mut self) {}
}
#[repr(packed)]
pub struct RemotePackedNonCopy {
pub a: u16,
pub b: String,
}
#[derive(Deserialize)]
#[repr(packed)]
#[serde(remote = "RemotePackedNonCopy")]
pub struct RemotePackedNonCopyDef {
a: u16,
b: String,
}
impl Drop for RemotePackedNonCopyDef {
fn drop(&mut self) {}
}
+5 -1
View File
@@ -1,5 +1,9 @@
#![deny(trivial_numeric_casts)] #![deny(trivial_numeric_casts)]
#![allow(clippy::redundant_field_names)] #![allow(
clippy::enum_variant_names,
clippy::redundant_field_names,
clippy::too_many_lines
)]
mod bytes; mod bytes;
+10 -8
View File
@@ -11,10 +11,12 @@ fn ip_addr_roundtrip() {
assert_tokens( assert_tokens(
&net::IpAddr::from(*b"1234").compact(), &net::IpAddr::from(*b"1234").compact(),
&seq![ &seq![
Token::NewtypeVariant { name: "IpAddr", variant: "V4" }, Token::NewtypeVariant {
name: "IpAddr",
variant: "V4"
},
Token::Tuple { len: 4 }, Token::Tuple { len: 4 },
seq b"1234".iter().map(|&b| Token::U8(b)), b"1234".iter().copied().map(Token::U8),
Token::TupleEnd, Token::TupleEnd,
], ],
); );
@@ -25,14 +27,14 @@ fn socket_addr_roundtrip() {
assert_tokens( assert_tokens(
&net::SocketAddr::from((*b"1234567890123456", 1234)).compact(), &net::SocketAddr::from((*b"1234567890123456", 1234)).compact(),
&seq![ &seq![
Token::NewtypeVariant { name: "SocketAddr", variant: "V6" }, Token::NewtypeVariant {
name: "SocketAddr",
variant: "V6"
},
Token::Tuple { len: 2 }, Token::Tuple { len: 2 },
Token::Tuple { len: 16 }, Token::Tuple { len: 16 },
seq b"1234567890123456".iter().map(|&b| Token::U8(b)), b"1234567890123456".iter().copied().map(Token::U8),
Token::TupleEnd, Token::TupleEnd,
Token::U16(1234), Token::U16(1234),
Token::TupleEnd, Token::TupleEnd,
], ],
+2
View File
@@ -1,3 +1,5 @@
#![allow(clippy::used_underscore_binding)]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[test] #[test]
File diff suppressed because it is too large Load Diff
+2
View File
@@ -1,3 +1,5 @@
#![allow(clippy::type_repetition_in_bounds)]
#[test] #[test]
fn test_gen_custom_serde() { fn test_gen_custom_serde() {
#[derive(serde::Serialize, serde::Deserialize)] #[derive(serde::Serialize, serde::Deserialize)]
+2 -1
View File
@@ -1,3 +1,5 @@
#![allow(clippy::similar_names)]
use serde::de::value::{self, MapAccessDeserializer}; use serde::de::value::{self, MapAccessDeserializer};
use serde::de::{IntoDeserializer, MapAccess, Visitor}; use serde::de::{IntoDeserializer, MapAccess, Visitor};
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
@@ -17,7 +19,6 @@ fn test_u32_to_enum() {
assert_eq!(E::B, e); assert_eq!(E::B, e);
} }
#[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))]
#[test] #[test]
fn test_integer128() { fn test_integer128() {
let de_u128 = IntoDeserializer::<value::Error>::into_deserializer(1u128); let de_u128 = IntoDeserializer::<value::Error>::into_deserializer(1u128);
@@ -1,5 +1,5 @@
error: failed to parse borrowed lifetimes: "zzz" error: failed to parse borrowed lifetimes: "zzz"
--> $DIR/bad_lifetimes.rs:5:22 --> tests/ui/borrow/bad_lifetimes.rs:5:22
| |
5 | #[serde(borrow = "zzz")] 5 | #[serde(borrow = "zzz")]
| ^^^^^ | ^^^^^
@@ -1,5 +1,5 @@
error: duplicate borrowed lifetime `'a` error: duplicate borrowed lifetime `'a`
--> $DIR/duplicate_lifetime.rs:5:22 --> tests/ui/borrow/duplicate_lifetime.rs:5:22
| |
5 | #[serde(borrow = "'a + 'a")] 5 | #[serde(borrow = "'a + 'a")]
| ^^^^^^^^^ | ^^^^^^^^^
@@ -1,5 +1,5 @@
error: duplicate serde attribute `borrow` error: duplicate serde attribute `borrow`
--> $DIR/duplicate_variant.rs:8:13 --> tests/ui/borrow/duplicate_variant.rs:8:13
| |
8 | #[serde(borrow)] 8 | #[serde(borrow)]
| ^^^^^^ | ^^^^^^
@@ -1,5 +1,5 @@
error: at least one lifetime must be borrowed error: at least one lifetime must be borrowed
--> $DIR/empty_lifetimes.rs:5:22 --> tests/ui/borrow/empty_lifetimes.rs:5:22
| |
5 | #[serde(borrow = "")] 5 | #[serde(borrow = "")]
| ^^ | ^^
@@ -1,5 +1,5 @@
error: field `s` has no lifetimes to borrow error: field `s` has no lifetimes to borrow
--> $DIR/no_lifetimes.rs:5:5 --> tests/ui/borrow/no_lifetimes.rs:5:5
| |
5 | / #[serde(borrow)] 5 | / #[serde(borrow)]
6 | | s: String, 6 | | s: String,
@@ -1,5 +1,5 @@
error: #[serde(borrow)] may only be used on newtype variants error: #[serde(borrow)] may only be used on newtype variants
--> $DIR/struct_variant.rs:8:5 --> tests/ui/borrow/struct_variant.rs:8:5
| |
8 | / #[serde(borrow)] 8 | / #[serde(borrow)]
9 | | S { s: Str<'a> }, 9 | | S { s: Str<'a> },
@@ -1,5 +1,5 @@
error: field `s` does not have lifetime 'b error: field `s` does not have lifetime 'b
--> $DIR/wrong_lifetime.rs:5:5 --> tests/ui/borrow/wrong_lifetime.rs:5:5
| |
5 | / #[serde(borrow = "'b")] 5 | / #[serde(borrow = "'b")]
6 | | s: &'a str, 6 | | s: &'a str,
@@ -1,5 +1,5 @@
error: enum tags `conflict` for type and content conflict with each other error: enum tags `conflict` for type and content conflict with each other
--> $DIR/adjacent-tag.rs:4:1 --> tests/ui/conflict/adjacent-tag.rs:4:1
| |
4 | / #[serde(tag = "conflict", content = "conflict")] 4 | / #[serde(tag = "conflict", content = "conflict")]
5 | | enum E { 5 | | enum E {
@@ -1,5 +1,5 @@
error: #[serde(flatten)] cannot be used on newtype structs error: #[serde(flatten)] cannot be used on newtype structs
--> $DIR/flatten-newtype-struct.rs:6:12 --> tests/ui/conflict/flatten-newtype-struct.rs:6:12
| |
6 | struct Foo(#[serde(flatten)] HashMap<String, String>); 6 | struct Foo(#[serde(flatten)] HashMap<String, String>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1,5 +1,5 @@
error: #[serde(flatten)] cannot be used on tuple structs error: #[serde(flatten)] cannot be used on tuple structs
--> $DIR/flatten-tuple-struct.rs:6:17 --> tests/ui/conflict/flatten-tuple-struct.rs:6:17
| |
6 | struct Foo(u32, #[serde(flatten)] HashMap<String, String>); 6 | struct Foo(u32, #[serde(flatten)] HashMap<String, String>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1,5 +1,5 @@
error: #[serde(from = "...")] and #[serde(try_from = "...")] conflict with each other error: #[serde(from = "...")] and #[serde(try_from = "...")] conflict with each other
--> $DIR/from-try-from.rs:4:1 --> tests/ui/conflict/from-try-from.rs:4:1
| |
4 | / #[serde(from = "u64", try_from = "u64")] 4 | / #[serde(from = "u64", try_from = "u64")]
5 | | struct S { 5 | | struct S {
@@ -1,5 +1,5 @@
error: variant field name `conflict` conflicts with internal tag error: variant field name `conflict` conflicts with internal tag
--> $DIR/internal-tag-alias.rs:4:1 --> tests/ui/conflict/internal-tag-alias.rs:4:1
| |
4 | / #[serde(tag = "conflict")] 4 | / #[serde(tag = "conflict")]
5 | | enum E { 5 | | enum E {
@@ -1,5 +1,5 @@
error: variant field name `conflict` conflicts with internal tag error: variant field name `conflict` conflicts with internal tag
--> $DIR/internal-tag.rs:4:1 --> tests/ui/conflict/internal-tag.rs:4:1
| |
4 | / #[serde(tag = "conflict")] 4 | / #[serde(tag = "conflict")]
5 | | enum E { 5 | | enum E {
@@ -1,5 +1,5 @@
error: #[serde(default)] can only be used on structs with named fields error: #[serde(default)] can only be used on structs with named fields
--> $DIR/enum.rs:5:1 --> tests/ui/default-attribute/enum.rs:5:1
| |
5 | enum E { 5 | enum E {
| ^^^^ | ^^^^
@@ -1,5 +1,5 @@
error: #[serde(default = "...")] can only be used on structs with named fields error: #[serde(default = "...")] can only be used on structs with named fields
--> $DIR/enum_path.rs:5:1 --> tests/ui/default-attribute/enum_path.rs:5:1
| |
5 | enum E { 5 | enum E {
| ^^^^ | ^^^^
@@ -1,5 +1,5 @@
error: #[serde(default)] can only be used on structs with named fields error: #[serde(default)] can only be used on structs with named fields
--> $DIR/nameless_struct_fields.rs:5:9 --> tests/ui/default-attribute/nameless_struct_fields.rs:5:9
| |
5 | struct T(u8, u8); 5 | struct T(u8, u8);
| ^^^^^^^^ | ^^^^^^^^
@@ -1,5 +1,5 @@
error: #[serde(default = "...")] can only be used on structs with named fields error: #[serde(default = "...")] can only be used on structs with named fields
--> $DIR/nameless_struct_fields_path.rs:5:9 --> tests/ui/default-attribute/nameless_struct_fields_path.rs:5:9
| |
5 | struct T(u8, u8); 5 | struct T(u8, u8);
| ^^^^^^^^ | ^^^^^^^^
@@ -1,5 +1,5 @@
error: unknown serde field attribute `serialize` error: unknown serde field attribute `serialize`
--> $DIR/rename-and-ser.rs:5:27 --> tests/ui/duplicate-attribute/rename-and-ser.rs:5:27
| |
5 | #[serde(rename = "x", serialize = "y")] 5 | #[serde(rename = "x", serialize = "y")]
| ^^^^^^^^^ | ^^^^^^^^^
@@ -1,5 +1,5 @@
error: duplicate serde attribute `rename` error: duplicate serde attribute `rename`
--> $DIR/rename-ser-rename-ser.rs:5:38 --> tests/ui/duplicate-attribute/rename-ser-rename-ser.rs:5:38
| |
5 | #[serde(rename(serialize = "x"), rename(serialize = "y"))] 5 | #[serde(rename(serialize = "x"), rename(serialize = "y"))]
| ^^^^^^ | ^^^^^^
@@ -1,5 +1,5 @@
error: duplicate serde attribute `rename` error: duplicate serde attribute `rename`
--> $DIR/rename-ser-rename.rs:6:13 --> tests/ui/duplicate-attribute/rename-ser-rename.rs:6:13
| |
6 | #[serde(rename = "y")] 6 | #[serde(rename = "y")]
| ^^^^^^ | ^^^^^^
@@ -1,5 +1,5 @@
error: duplicate serde attribute `rename` error: duplicate serde attribute `rename`
--> $DIR/rename-ser-ser.rs:5:37 --> tests/ui/duplicate-attribute/rename-ser-ser.rs:5:37
| |
5 | #[serde(rename(serialize = "x", serialize = "y"))] 5 | #[serde(rename(serialize = "x", serialize = "y"))]
| ^^^^^^^^^ | ^^^^^^^^^
@@ -1,5 +1,5 @@
error: duplicate serde attribute `rename` error: duplicate serde attribute `rename`
--> $DIR/two-rename-ser.rs:6:13 --> tests/ui/duplicate-attribute/two-rename-ser.rs:6:13
| |
6 | #[serde(rename(serialize = "y"))] 6 | #[serde(rename(serialize = "y"))]
| ^^^^^^ | ^^^^^^
@@ -1,5 +1,5 @@
error: duplicate serde attribute `serialize_with` error: duplicate serde attribute `serialize_with`
--> $DIR/with-and-serialize-with.rs:5:25 --> tests/ui/duplicate-attribute/with-and-serialize-with.rs:5:25
| |
5 | #[serde(with = "w", serialize_with = "s")] 5 | #[serde(with = "w", serialize_with = "s")]
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
@@ -1,5 +1,5 @@
error: #[serde(tag = "...", content = "...")] must be used together error: #[serde(tag = "...", content = "...")] must be used together
--> $DIR/content-no-tag.rs:4:9 --> tests/ui/enum-representation/content-no-tag.rs:4:9
| |
4 | #[serde(content = "c")] 4 | #[serde(content = "c")]
| ^^^^^^^ | ^^^^^^^
@@ -1,5 +1,5 @@
error: #[serde(tag = "...")] cannot be used with tuple variants error: #[serde(tag = "...")] cannot be used with tuple variants
--> $DIR/internal-tuple-variant.rs:6:5 --> tests/ui/enum-representation/internal-tuple-variant.rs:6:5
| |
6 | Tuple(u8, u8), 6 | Tuple(u8, u8),
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@@ -1,17 +1,17 @@
error: untagged enum cannot have #[serde(tag = "...", content = "...")] error: untagged enum cannot have #[serde(tag = "...", content = "...")]
--> $DIR/untagged-and-adjacent.rs:4:9 --> tests/ui/enum-representation/untagged-and-adjacent.rs:4:9
| |
4 | #[serde(untagged)] 4 | #[serde(untagged)]
| ^^^^^^^^ | ^^^^^^^^
error: untagged enum cannot have #[serde(tag = "...", content = "...")] error: untagged enum cannot have #[serde(tag = "...", content = "...")]
--> $DIR/untagged-and-adjacent.rs:5:9 --> tests/ui/enum-representation/untagged-and-adjacent.rs:5:9
| |
5 | #[serde(tag = "t", content = "c")] 5 | #[serde(tag = "t", content = "c")]
| ^^^ | ^^^
error: untagged enum cannot have #[serde(tag = "...", content = "...")] error: untagged enum cannot have #[serde(tag = "...", content = "...")]
--> $DIR/untagged-and-adjacent.rs:5:20 --> tests/ui/enum-representation/untagged-and-adjacent.rs:5:20
| |
5 | #[serde(tag = "t", content = "c")] 5 | #[serde(tag = "t", content = "c")]
| ^^^^^^^ | ^^^^^^^
@@ -1,11 +1,11 @@
error: untagged enum cannot have #[serde(content = "...")] error: untagged enum cannot have #[serde(content = "...")]
--> $DIR/untagged-and-content.rs:4:9 --> tests/ui/enum-representation/untagged-and-content.rs:4:9
| |
4 | #[serde(untagged)] 4 | #[serde(untagged)]
| ^^^^^^^^ | ^^^^^^^^
error: untagged enum cannot have #[serde(content = "...")] error: untagged enum cannot have #[serde(content = "...")]
--> $DIR/untagged-and-content.rs:5:9 --> tests/ui/enum-representation/untagged-and-content.rs:5:9
| |
5 | #[serde(content = "c")] 5 | #[serde(content = "c")]
| ^^^^^^^ | ^^^^^^^
@@ -1,11 +1,11 @@
error: enum cannot be both untagged and internally tagged error: enum cannot be both untagged and internally tagged
--> $DIR/untagged-and-internal.rs:4:9 --> tests/ui/enum-representation/untagged-and-internal.rs:4:9
| |
4 | #[serde(untagged)] 4 | #[serde(untagged)]
| ^^^^^^^^ | ^^^^^^^^
error: enum cannot be both untagged and internally tagged error: enum cannot be both untagged and internally tagged
--> $DIR/untagged-and-internal.rs:5:9 --> tests/ui/enum-representation/untagged-and-internal.rs:5:9
| |
5 | #[serde(tag = "type")] 5 | #[serde(tag = "type")]
| ^^^ | ^^^
@@ -1,5 +1,5 @@
error: #[serde(untagged)] can only be used on enums error: #[serde(untagged)] can only be used on enums
--> $DIR/untagged-struct.rs:5:1 --> tests/ui/enum-representation/untagged-struct.rs:5:1
| |
5 | struct S; 5 | struct S;
| ^^^^^^ | ^^^^^^
@@ -1,5 +1,5 @@
error: expected serde rename attribute to be a string: `rename = "..."` error: expected serde rename attribute to be a string: `rename = "..."`
--> $DIR/boolean.rs:5:22 --> tests/ui/expected-string/boolean.rs:5:22
| |
5 | #[serde(rename = true)] 5 | #[serde(rename = true)]
| ^^^^ | ^^^^
@@ -1,5 +1,5 @@
error: expected serde rename attribute to be a string: `rename = "..."` error: expected serde rename attribute to be a string: `rename = "..."`
--> $DIR/byte_character.rs:5:22 --> tests/ui/expected-string/byte_character.rs:5:22
| |
5 | #[serde(rename = b'a')] 5 | #[serde(rename = b'a')]
| ^^^^ | ^^^^
@@ -1,5 +1,5 @@
error: expected serde rename attribute to be a string: `rename = "..."` error: expected serde rename attribute to be a string: `rename = "..."`
--> $DIR/byte_string.rs:5:22 --> tests/ui/expected-string/byte_string.rs:5:22
| |
5 | #[serde(rename = b"byte string")] 5 | #[serde(rename = b"byte string")]
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
@@ -1,5 +1,5 @@
error: expected serde rename attribute to be a string: `rename = "..."` error: expected serde rename attribute to be a string: `rename = "..."`
--> $DIR/character.rs:5:22 --> tests/ui/expected-string/character.rs:5:22
| |
5 | #[serde(rename = 'a')] 5 | #[serde(rename = 'a')]
| ^^^ | ^^^
@@ -1,5 +1,5 @@
error: expected serde rename attribute to be a string: `rename = "..."` error: expected serde rename attribute to be a string: `rename = "..."`
--> $DIR/float.rs:5:22 --> tests/ui/expected-string/float.rs:5:22
| |
5 | #[serde(rename = 3.14)] 5 | #[serde(rename = 3.14)]
| ^^^^ | ^^^^
@@ -1,5 +1,5 @@
error: expected serde rename attribute to be a string: `rename = "..."` error: expected serde rename attribute to be a string: `rename = "..."`
--> $DIR/integer.rs:5:22 --> tests/ui/expected-string/integer.rs:5:22
| |
5 | #[serde(rename = 100)] 5 | #[serde(rename = 100)]
| ^^^ | ^^^
+2 -2
View File
@@ -1,11 +1,11 @@
error: #[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set error: #[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set
--> $DIR/both.rs:4:9 --> tests/ui/identifier/both.rs:4:9
| |
4 | #[serde(field_identifier, variant_identifier)] 4 | #[serde(field_identifier, variant_identifier)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: #[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set error: #[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set
--> $DIR/both.rs:4:27 --> tests/ui/identifier/both.rs:4:27
| |
4 | #[serde(field_identifier, variant_identifier)] 4 | #[serde(field_identifier, variant_identifier)]
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
@@ -1,5 +1,5 @@
error: #[serde(field_identifier)] can only be used on an enum error: #[serde(field_identifier)] can only be used on an enum
--> $DIR/field_struct.rs:5:1 --> tests/ui/identifier/field_struct.rs:5:1
| |
5 | struct S; 5 | struct S;
| ^^^^^^ | ^^^^^^
@@ -1,5 +1,5 @@
error: #[serde(field_identifier)] may only contain unit variants error: #[serde(field_identifier)] may only contain unit variants
--> $DIR/field_tuple.rs:7:5 --> tests/ui/identifier/field_tuple.rs:7:5
| |
7 | B(u8, u8), 7 | B(u8, u8),
| ^^^^^^^^^ | ^^^^^^^^^
@@ -1,5 +1,5 @@
error: `Other` must be the last variant error: `Other` must be the last variant
--> $DIR/newtype_not_last.rs:7:5 --> tests/ui/identifier/newtype_not_last.rs:7:5
| |
7 | Other(String), 7 | Other(String),
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@@ -1,5 +1,5 @@
error: #[serde(other)] must be on a unit variant error: #[serde(other)] must be on a unit variant
--> $DIR/not_unit.rs:7:5 --> tests/ui/identifier/not_unit.rs:7:5
| |
7 | / #[serde(other)] 7 | / #[serde(other)]
8 | | Other(u8, u8), 8 | | Other(u8, u8),
@@ -1,5 +1,5 @@
error: #[serde(other)] must be on the last variant error: #[serde(other)] must be on the last variant
--> $DIR/other_not_last.rs:7:5 --> tests/ui/identifier/other_not_last.rs:7:5
| |
7 | / #[serde(other)] 7 | / #[serde(other)]
8 | | Other, 8 | | Other,
@@ -1,5 +1,5 @@
error: #[serde(other)] cannot appear on untagged enum error: #[serde(other)] cannot appear on untagged enum
--> $DIR/other_untagged.rs:6:5 --> tests/ui/identifier/other_untagged.rs:6:5
| |
6 | / #[serde(other)] 6 | / #[serde(other)]
7 | | Other, 7 | | Other,
@@ -1,5 +1,5 @@
error: #[serde(other)] may not be used on a variant identifier error: #[serde(other)] may not be used on a variant identifier
--> $DIR/other_variant.rs:6:5 --> tests/ui/identifier/other_variant.rs:6:5
| |
6 | / #[serde(other)] 6 | / #[serde(other)]
7 | | Other, 7 | | Other,
@@ -1,5 +1,5 @@
error: #[serde(variant_identifier)] can only be used on an enum error: #[serde(variant_identifier)] can only be used on an enum
--> $DIR/variant_struct.rs:5:1 --> tests/ui/identifier/variant_struct.rs:5:1
| |
5 | struct S; 5 | struct S;
| ^^^^^^ | ^^^^^^
@@ -1,5 +1,5 @@
error: #[serde(variant_identifier)] may only contain unit variants error: #[serde(variant_identifier)] may only contain unit variants
--> $DIR/variant_tuple.rs:7:5 --> tests/ui/identifier/variant_tuple.rs:7:5
| |
7 | B(u8, u8), 7 | B(u8, u8),
| ^^^^^^^^^ | ^^^^^^^^^
+1 -1
View File
@@ -1,5 +1,5 @@
error: malformed bound attribute, expected `bound(serialize = ..., deserialize = ...)` error: malformed bound attribute, expected `bound(serialize = ..., deserialize = ...)`
--> $DIR/bound.rs:5:19 --> tests/ui/malformed/bound.rs:5:19
| |
5 | #[serde(bound(unknown))] 5 | #[serde(bound(unknown))]
| ^^^^^^^ | ^^^^^^^
+1 -1
View File
@@ -1,5 +1,5 @@
error: unexpected end of input, expected literal error: unexpected end of input, expected literal
--> $DIR/cut_off.rs:4:17 --> tests/ui/malformed/cut_off.rs:4:17
| |
4 | #[serde(rename =)] 4 | #[serde(rename =)]
| ^ | ^
@@ -1,11 +1,11 @@
error: expected #[serde(...)] error: expected #[serde(...)]
--> $DIR/not_list.rs:4:3 --> tests/ui/malformed/not_list.rs:4:3
| |
4 | #[serde] 4 | #[serde]
| ^^^^^ | ^^^^^
error: expected #[serde(...)] error: expected #[serde(...)]
--> $DIR/not_list.rs:5:3 --> tests/ui/malformed/not_list.rs:5:3
| |
5 | #[serde = "?"] 5 | #[serde = "?"]
| ^^^^^^^^^^^ | ^^^^^^^^^^^
+1 -1
View File
@@ -1,5 +1,5 @@
error: malformed rename attribute, expected `rename(serialize = ..., deserialize = ...)` error: malformed rename attribute, expected `rename(serialize = ..., deserialize = ...)`
--> $DIR/rename.rs:5:20 --> tests/ui/malformed/rename.rs:5:20
| |
5 | #[serde(rename(unknown))] 5 | #[serde(rename(unknown))]
| ^^^^^^^ | ^^^^^^^
@@ -1,5 +1,5 @@
error: cannot deserialize when there is a lifetime parameter called 'de error: cannot deserialize when there is a lifetime parameter called 'de
--> $DIR/deserialize_de_lifetime.rs:4:10 --> tests/ui/precondition/deserialize_de_lifetime.rs:4:10
| |
4 | struct S<'de> { 4 | struct S<'de> {
| ^^^ | ^^^
@@ -1,5 +1,5 @@
error: cannot deserialize a dynamically sized struct error: cannot deserialize a dynamically sized struct
--> $DIR/deserialize_dst.rs:4:1 --> tests/ui/precondition/deserialize_dst.rs:4:1
| |
4 | / struct S { 4 | / struct S {
5 | | string: String, 5 | | string: String,
@@ -1,5 +1,5 @@
error: field identifiers cannot be serialized error: field identifiers cannot be serialized
--> $DIR/serialize_field_identifier.rs:4:1 --> tests/ui/precondition/serialize_field_identifier.rs:4:1
| |
4 | / #[serde(field_identifier)] 4 | / #[serde(field_identifier)]
5 | | enum F { 5 | | enum F {
@@ -1,5 +1,5 @@
error: variant identifiers cannot be serialized error: variant identifiers cannot be serialized
--> $DIR/serialize_variant_identifier.rs:4:1 --> tests/ui/precondition/serialize_variant_identifier.rs:4:1
| |
4 | / #[serde(variant_identifier)] 4 | / #[serde(variant_identifier)]
5 | | enum F { 5 | | enum F {
+1 -1
View File
@@ -1,5 +1,5 @@
error: failed to parse path: "~~~" error: failed to parse path: "~~~"
--> $DIR/bad_getter.rs:12:22 --> tests/ui/remote/bad_getter.rs:12:22
| |
12 | #[serde(getter = "~~~")] 12 | #[serde(getter = "~~~")]
| ^^^^^ | ^^^^^
+1 -1
View File
@@ -1,5 +1,5 @@
error: failed to parse path: "~~~" error: failed to parse path: "~~~"
--> $DIR/bad_remote.rs:10:18 --> tests/ui/remote/bad_remote.rs:10:18
| |
10 | #[serde(remote = "~~~")] 10 | #[serde(remote = "~~~")]
| ^^^^^ | ^^^^^
@@ -1,5 +1,5 @@
error: #[serde(getter = "...")] is not allowed in an enum error: #[serde(getter = "...")] is not allowed in an enum
--> $DIR/enum_getter.rs:10:1 --> tests/ui/remote/enum_getter.rs:10:1
| |
10 | / #[serde(remote = "remote::E")] 10 | / #[serde(remote = "remote::E")]
11 | | pub enum E { 11 | | pub enum E {
@@ -1,5 +1,5 @@
error[E0063]: missing field `b` in initializer of `remote::S` error[E0063]: missing field `b` in initializer of `remote::S`
--> $DIR/missing_field.rs:11:18 --> tests/ui/remote/missing_field.rs:11:18
| |
11 | #[serde(remote = "remote::S")] 11 | #[serde(remote = "remote::S")]
| ^^^^^^^^^^^ missing `b` | ^^^^^^^^^^^ missing `b`
@@ -1,5 +1,5 @@
error: #[serde(getter = "...")] can only be used in structs that have #[serde(remote = "...")] error: #[serde(getter = "...")] can only be used in structs that have #[serde(remote = "...")]
--> $DIR/nonremote_getter.rs:4:1 --> tests/ui/remote/nonremote_getter.rs:4:1
| |
4 | / struct S { 4 | / struct S {
5 | | #[serde(getter = "S::get")] 5 | | #[serde(getter = "S::get")]
@@ -1,11 +1,11 @@
error[E0609]: no field `b` on type `&remote::S` error[E0609]: no field `b` on type `&remote::S`
--> $DIR/unknown_field.rs:12:5 --> tests/ui/remote/unknown_field.rs:12:5
| |
12 | b: u8, 12 | b: u8,
| ^ help: a field with a similar name exists: `a` | ^ help: a field with a similar name exists: `a`
error[E0560]: struct `remote::S` has no field named `b` error[E0560]: struct `remote::S` has no field named `b`
--> $DIR/unknown_field.rs:12:5 --> tests/ui/remote/unknown_field.rs:12:5
| |
12 | b: u8, 12 | b: u8,
| ^ help: a field with a similar name exists: `a` | ^ help: a field with a similar name exists: `a`
+6 -5
View File
@@ -1,10 +1,11 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/wrong_de.rs:7:10 --> tests/ui/remote/wrong_de.rs:7:10
| |
7 | #[derive(Deserialize)] 7 | #[derive(Deserialize)]
| ^^^^^^^^^^^ | ^^^^^^^^^^^ expected `u16`, found `u8`
| |
| expected `u16`, found `u8`
| help: you can convert a `u8` to a `u16`: `Deserialize.into()`
| |
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you can convert a `u8` to a `u16`
|
7 | #[derive(Deserialize.into())]
| +++++++
@@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/wrong_getter.rs:15:10 --> tests/ui/remote/wrong_getter.rs:15:10
| |
15 | #[derive(Serialize)] 15 | #[derive(Serialize)]
| ^^^^^^^^^ expected `u8`, found `u16` | ^^^^^^^^^ expected `u8`, found `u16`

Some files were not shown because too many files have changed in this diff Show More