Compare commits

...

77 Commits

Author SHA1 Message Date
David Tolnay 8939af48fe Release 1.0.215 2024-11-11 13:03:35 -08:00
David Tolnay fa5d58cd00 Use ui test syntax that does not interfere with rustfmt 2024-11-10 23:50:37 -08:00
David Tolnay 1a3cf4b3c1 Update PR 2562 ui tests 2024-11-10 23:46:31 -08:00
David Tolnay 7d96352e96 Merge pull request #2857 from dtolnay/collide
Revert the colliding aliases hard error (PRs #2562 & #2853)
2024-11-10 23:37:01 -08:00
David Tolnay 111ecc5d8c Update ui tests for warning on colliding aliases 2024-11-10 23:31:55 -08:00
David Tolnay edd6fe954b Revert "Add checks for conflicts for aliases"
This reverts commit 5f9fffa53e.
2024-11-10 23:31:55 -08:00
David Tolnay a20e9249c5 Revert "pacify clippy"
This reverts commit 951ca5ace0.
2024-11-10 23:31:55 -08:00
David Tolnay b1353a99cd Merge pull request #2856 from dtolnay/dename
Produce a separate warning for every colliding name
2024-11-10 23:31:44 -08:00
David Tolnay c59e876bb3 Produce a separate warning for every colliding name 2024-11-10 23:23:09 -08:00
David Tolnay 7f1e697c0d Merge pull request #2855 from dtolnay/namespan
Produce unreachable_patterns warning when deserialization names collide
2024-11-10 23:21:46 -08:00
David Tolnay 373edcd055 Keep track of a span for alias strings 2024-11-10 23:08:40 -08:00
David Tolnay f0b5c4f857 Move MultiName to a new module 2024-11-10 22:32:49 -08:00
David Tolnay 3035d4fa34 Rename Name -> MultiName 2024-11-10 22:32:49 -08:00
David Tolnay 60ac737439 Prevent upload-artifact step from causing CI failure
This step has been failing way more than reasonable across my various repos.

    With the provided path, there will be 1 file uploaded
    Artifact name is valid!
    Root directory input is valid!
    Attempt 1 of 5 failed with error: Request timeout: /twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact. Retrying request in 3000 ms...
    Attempt 2 of 5 failed with error: Request timeout: /twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact. Retrying request in 6029 ms...
    Attempt 3 of 5 failed with error: Request timeout: /twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact. Retrying request in 8270 ms...
    Attempt 4 of 5 failed with error: Request timeout: /twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact. Retrying request in 12577 ms...
    Error: Failed to CreateArtifact: Failed to make request after 5 attempts: Request timeout: /twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact
2024-11-08 21:45:52 -05:00
Oli Scherer a95b0d301e Merge pull request #2853 from serde-rs/oli-obk-patch-1
pacify clippy
2024-11-01 15:25:08 +01:00
Oli Scherer 951ca5ace0 pacify clippy 2024-11-01 15:20:51 +01:00
Oli Scherer adf05a5bf6 Merge pull request #2562 from Mingun/alias-check
Add checks for conflicts for aliases
2024-11-01 15:14:15 +01:00
David Tolnay 418062165f Release 1.0.214 2024-10-28 09:41:44 -07:00
David Tolnay 210373b3b6 Merge pull request #2568 from Mingun/into_deserializer-for-deserializers
Implement `IntoDeserializer` for all `Deserializer`s in `serde::de::value` module
2024-10-28 09:40:57 -07:00
Mingun 5f9fffa53e Add checks for conflicts for aliases
- Check that alias is not the same as name of other field (it still can be the name of owning field/variant)
- Check that aliases are unique, i. e. two different fields does not use the same alias
2024-10-25 19:18:31 +05:00
Mingun 9cda015733 Implement IntoDeserializer for all Deserializers in serde::de::value module
Unfortunately, blanket implementation IntoDeserializer for Deserializer is impossible
right now because this would be a breaking change. External crates may have this
such implementation (and serde_json actually have it for Value)
2024-10-25 19:17:50 +05:00
David Tolnay 58a8d22931 Release 1.0.213 2024-10-22 11:14:58 -07:00
David Tolnay ef0ed22593 Merge pull request #2847 from dtolnay/newtypewith
Hygiene for macro-generated newtype struct deserialization with `with` attr
2024-10-22 11:14:18 -07:00
David Tolnay 79925ac394 Ignore dead_code warning in regression test
warning: field `0` is never read
      --> test_suite/tests/regression/issue2846.rs:8:45
       |
    8  |         pub struct S(#[serde(with = $with)] i32);
       |                    - field in this struct   ^^^
    ...
    12 | declare_in_macro!("with");
       | ------------------------- in this macro invocation
       |
       = help: consider removing this field
       = note: `#[warn(dead_code)]` on by default
       = note: this warning originates in the macro `declare_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
2024-10-22 11:10:52 -07:00
David Tolnay b60e4092ec Hygiene for macro-generated newtype struct deserialization with 'with' attr 2024-10-22 11:10:40 -07:00
David Tolnay fdc36e5c06 Add regression test for issue 2846
error[E0425]: cannot find value `__e` in this scope
      --> test_suite/tests/regression/issue2846.rs:12:19
       |
    12 | declare_in_macro!("with");
       |                   ^^^^^^ not found in this scope
2024-10-22 11:08:22 -07:00
David Tolnay 49e11ce1ba Ignore trivially_copy_pass_by_ref pedantic clippy lint in test
warning: this argument (4 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
      --> test_suite/tests/regression/issue2844.rs:18:28
       |
    18 |     pub fn serialize<S>(_: &i32, _: S) -> Result<S::Ok, S::Error>
       |                            ^^^^ help: consider passing by value instead: `i32`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref
       = note: `-W clippy::trivially-copy-pass-by-ref` implied by `-W clippy::pedantic`
       = help: to override `-W clippy::pedantic` add `#[allow(clippy::trivially_copy_pass_by_ref)]`
2024-10-22 09:56:12 -07:00
David Tolnay 7ae1b5f8f3 Release 1.0.212 2024-10-22 09:41:55 -07:00
David Tolnay 1ac054b34a Merge pull request #2845 from dtolnay/withlocal
Fix hygiene of macro-generated local variable accesses in serde(with) wrappers
2024-10-22 09:41:27 -07:00
David Tolnay 1e36ef551d Fix hygiene of macro-generated local variable accesses in serde(with) wrappers 2024-10-22 09:38:06 -07:00
David Tolnay 0058c7226e Add regression test for issue 2844
error[E0424]: expected value, found module `self`
      --> test_suite/tests/regression/issue2844.rs:13:19
       |
    5  |         #[derive(Serialize, Deserialize)]
       |                  --------- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters
    ...
    13 | declare_in_macro!("with");
       |                   ^^^^^^ `self` value is a keyword only available in methods with a `self` parameter

    error[E0425]: cannot find value `__s` in this scope
      --> test_suite/tests/regression/issue2844.rs:13:19
       |
    13 | declare_in_macro!("with");
       |                   ^^^^^^ not found in this scope

    error[E0425]: cannot find value `__deserializer` in this scope
      --> test_suite/tests/regression/issue2844.rs:13:19
       |
    13 | declare_in_macro!("with");
       |                   ^^^^^^ not found in this scope
2024-10-22 09:37:58 -07:00
David Tolnay 29d4f3e887 Format regression tests with rustfmt 2024-10-22 09:28:10 -07:00
David Tolnay 1b8310d98a Release 1.0.211 2024-10-21 23:27:57 -07:00
David Tolnay af4c388dff Merge pull request #2843 from dtolnay/fieldwithaliases
Collect field ident and aliases into a struct
2024-10-21 23:23:28 -07:00
David Tolnay 09f6d9361d Collect field ident and aliases into a struct 2024-10-21 23:16:05 -07:00
David Tolnay 1f9eb8300f Merge pull request #2842 from dtolnay/identsaliases
Rename field_names_idents -> field_idents_aliases
2024-10-21 23:13:23 -07:00
David Tolnay c6a5be7f6a Rename variant_names_idents -> variant_idents_aliases 2024-10-21 22:56:07 -07:00
David Tolnay 0a06af8d21 Rename field_names_idents -> field_idents_aliases 2024-10-21 22:48:02 -07:00
David Tolnay 3393ad6760 Make most of prepare_enum_variant_enum independent of variant_names_idents item type 2024-10-21 22:47:42 -07:00
David Tolnay 830309fcb5 Merge pull request #2841 from dtolnay/serializewith
Reduce scope of quote_spanned on SerializeWith wrapper
2024-10-21 21:56:51 -07:00
David Tolnay ab4f3f3111 Reduce scope of quote_spanned on SerializeWith wrapper 2024-10-21 21:09:18 -07:00
David Tolnay 00460b8dee Fix wording in comments from PR 2558 2024-10-21 21:07:13 -07:00
David Tolnay d4486be2b9 Format all ui tests from PR 2558 using rustfmt 2024-10-21 19:43:45 -07:00
David Tolnay 991e344804 Raise required compiler for serde_derive to 1.61
This is the rust-version declared by recent versions of Syn.
2024-10-21 19:30:51 -07:00
David Tolnay 6a7de26e5a Ignore uninlined_format_args pedantic clippy lint
warning: variables can be used directly in the `format!` string
       --> serde_derive/src/internals/attr.rs:546:36
        |
    546 |                         meta.error(format_args!("unknown serde container attribute `{}`", path))
        |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
        = note: `-W clippy::uninlined-format-args` implied by `-W clippy::pedantic`
        = help: to override `-W clippy::pedantic` add `#[allow(clippy::uninlined_format_args)]`
    help: change this to
        |
    546 -                         meta.error(format_args!("unknown serde container attribute `{}`", path))
    546 +                         meta.error(format_args!("unknown serde container attribute `{path}`"))
        |

    warning: variables can be used directly in the `format!` string
       --> serde_derive/src/internals/attr.rs:940:36
        |
    940 |                         meta.error(format_args!("unknown serde variant attribute `{}`", path))
        |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
        |
    940 -                         meta.error(format_args!("unknown serde variant attribute `{}`", path))
    940 +                         meta.error(format_args!("unknown serde variant attribute `{path}`"))
        |

    warning: variables can be used directly in the `format!` string
        --> serde_derive/src/internals/attr.rs:1095:33
         |
    1095 | ...                   format!("field `{}` does not have lifetime {}", ident, lifetime);
         |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
         |
    1095 -                                 format!("field `{}` does not have lifetime {}", ident, lifetime);
    1095 +                                 format!("field `{ident}` does not have lifetime {lifetime}");
         |

    warning: variables can be used directly in the `format!` string
        --> serde_derive/src/internals/attr.rs:1196:47
         |
    1196 |   ...                   let msg = format!(
         |  _________________________________^
    1197 | | ...                       "field `{}` does not have lifetime {}",
    1198 | | ...                       ident, lifetime,
    1199 | | ...                   );
         | |_______________________^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args

    warning: variables can be used directly in the `format!` string
        --> serde_derive/src/internals/attr.rs:1222:36
         |
    1222 |                         meta.error(format_args!("unknown serde field attribute `{}`", path))
         |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
         |
    1222 -                         meta.error(format_args!("unknown serde field attribute `{}`", path))
    1222 +                         meta.error(format_args!("unknown serde field attribute `{path}`"))
         |

    warning: variables can be used directly in the `format!` string
        --> serde_derive/src/internals/attr.rs:1415:39
         |
    1415 |                   return Err(meta.error(format_args!(
         |  _______________________________________^
    1416 | |                     "malformed {0} attribute, expected `{0}(serialize = ..., deserialize = ...)`",
    1417 | |                     attr_name,
    1418 | |                 )));
         | |_________________^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args

    warning: variables can be used directly in the `format!` string
        --> serde_derive/src/internals/attr.rs:1482:17
         |
    1482 |                 format!("unexpected suffix `{}` on string literal", suffix),
         |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
         |
    1482 -                 format!("unexpected suffix `{}` on string literal", suffix),
    1482 +                 format!("unexpected suffix `{suffix}` on string literal"),
         |

    warning: variables can be used directly in the `format!` string
        --> serde_derive/src/internals/attr.rs:1489:13
         |
    1489 | /             format!(
    1490 | |                 "expected serde {} attribute to be a string: `{} = \"...\"`",
    1491 | |                 attr_name, meta_item_name
    1492 | |             ),
         | |_____________^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args

    warning: variables can be used directly in the `format!` string
        --> serde_derive/src/internals/attr.rs:1604:21
         |
    1604 |                     format!("duplicate borrowed lifetime `{}`", lifetime),
         |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
         |
    1604 -                     format!("duplicate borrowed lifetime `{}`", lifetime),
    1604 +                     format!("duplicate borrowed lifetime `{lifetime}`"),
         |

    warning: variables can be used directly in the `format!` string
        --> serde_derive/src/internals/attr.rs:1778:19
         |
    1778 |         let msg = format!("field `{}` has no lifetimes to borrow", name);
         |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
         |
    1778 -         let msg = format!("field `{}` has no lifetimes to borrow", name);
    1778 +         let msg = format!("field `{name}` has no lifetimes to borrow");
         |

    warning: variables can be used directly in the `format!` string
      --> serde_derive/src/internals/check.rs:41:29
       |
    41 | ...   format!("field must have #[serde(default)] because previous field {} has #[serde(default)]", first),
       |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
       |
    41 -                             format!("field must have #[serde(default)] because previous field {} has #[serde(default)]", first),
    41 +                             format!("field must have #[serde(default)] because previous field {first} has #[serde(default)]"),
       |

    warning: variables can be used directly in the `format!` string
       --> serde_derive/src/internals/check.rs:314:13
        |
    314 |             format!("variant field name `{}` conflicts with internal tag", tag),
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
        |
    314 -             format!("variant field name `{}` conflicts with internal tag", tag),
    314 +             format!("variant field name `{tag}` conflicts with internal tag"),
        |

    warning: variables can be used directly in the `format!` string
       --> serde_derive/src/internals/check.rs:361:13
        |
    361 | /             format!(
    362 | |                 "enum tags `{}` for type and content conflict with each other",
    363 | |                 type_tag
    364 | |             ),
        | |_____________^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args

    warning: variables can be used directly in the `format!` string
       --> serde_derive/src/internals/check.rs:450:33
        |
    450 |         Member::Named(ident) => format!("`{}`", ident),
        |                                 ^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
        |
    450 -         Member::Named(ident) => format!("`{}`", ident),
    450 +         Member::Named(ident) => format!("`{ident}`"),
        |

    warning: variables can be used directly in the `format!` string
       --> serde_derive/src/de.rs:697:9
        |
    697 |         format!("{} with 1 element", expecting)
        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
        |
    697 -         format!("{} with 1 element", expecting)
    697 +         format!("{expecting} with 1 element")
        |

    warning: variables can be used directly in the `format!` string
       --> serde_derive/src/de.rs:699:9
        |
    699 |         format!("{} with {} elements", expecting, deserialized_count)
        |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
        |
    699 -         format!("{} with {} elements", expecting, deserialized_count)
    699 +         format!("{expecting} with {deserialized_count} elements")
        |

    warning: variables can be used directly in the `format!` string
        --> serde_derive/src/de.rs:1442:21
         |
    1442 |     let expecting = format!("adjacently tagged enum {}", rust_name);
         |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
         |
    1442 -     let expecting = format!("adjacently tagged enum {}", rust_name);
    1442 +     let expecting = format!("adjacently tagged enum {rust_name}");
         |

    warning: variables can be used directly in the `format!` string
        --> serde_derive/src/de.rs:2842:17
         |
    2842 |     Ident::new(&format!("__field{}", i), Span::call_site())
         |                 ^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
         |
    2842 -     Ident::new(&format!("__field{}", i), Span::call_site())
    2842 +     Ident::new(&format!("__field{i}"), Span::call_site())
         |

    warning: variables can be used directly in the `format!` string
       --> serde_derive/src/ser.rs:457:42
        |
    457 |                     .map(|i| Ident::new(&format!("__field{}", i), Span::call_site()));
        |                                          ^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
        |
    457 -                     .map(|i| Ident::new(&format!("__field{}", i), Span::call_site()));
    457 +                     .map(|i| Ident::new(&format!("__field{i}"), Span::call_site()));
        |

    warning: variables can be used directly in the `format!` string
       --> serde_derive/src/ser.rs:714:48
        |
    714 |             .map(|i| Member::Named(Ident::new(&format!("__field{}", i), Span::call_site())))
        |                                                ^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
        |
    714 -             .map(|i| Member::Named(Ident::new(&format!("__field{}", i), Span::call_site())))
    714 +             .map(|i| Member::Named(Ident::new(&format!("__field{i}"), Span::call_site())))
        |

    warning: variables can be used directly in the `format!` string
       --> serde_derive/src/ser.rs:832:46
        |
    832 |                 let field_expr = Ident::new(&format!("__field{}", i), Span::call_site());
        |                                              ^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
        |
    832 -                 let field_expr = Ident::new(&format!("__field{}", i), Span::call_site());
    832 +                 let field_expr = Ident::new(&format!("__field{i}"), Span::call_site());
        |

    warning: variables can be used directly in the `format!` string
        --> serde_derive/src/ser.rs:1062:38
         |
    1062 |                 let id = Ident::new(&format!("__field{}", i), Span::call_site());
         |                                      ^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    help: change this to
         |
    1062 -                 let id = Ident::new(&format!("__field{}", i), Span::call_site());
    1062 +                 let id = Ident::new(&format!("__field{i}"), Span::call_site());
         |
2024-10-21 19:30:51 -07:00
David Tolnay 5382ef3b0b Merge pull request #2840 from dtolnay/needlesslifetimes
Ignore needless_lifetimes clippy lint in generated code
2024-10-21 19:25:40 -07:00
David Tolnay a8cbc9184e Ignore needless_lifetimes clippy lint in generated code 2024-10-21 19:12:52 -07:00
David Tolnay 966e9ccf0c Merge pull request #2839 from dtolnay/pr2558
Update ui tests from PR 2558
2024-10-21 18:58:21 -07:00
David Tolnay 53ade10137 Update ui tests from PR 2558 2024-10-21 18:52:49 -07:00
David Tolnay 422c719352 Temporarily disable 1.56 CI
While fixing other errors from recently merged PRs.
2024-10-21 18:47:54 -07:00
Oli Scherer 3415619bfd Merge pull request #2566 from Mingun/variant-aliases
Show variant aliases in error message
2024-10-21 21:40:57 +02:00
Oli Scherer 04bb76bc00 Merge pull request #2558 from Mingun/correct-span
Improve error reporting about mismatched signature in `with` and `default` attributes
2024-10-21 21:38:09 +02:00
David Tolnay 8b0f482666 Update for precise capture bounds
warning: some variants are not matched explicitly
       --> serde_derive/src/internals/receiver.rs:209:15
        |
    209 |         match bound {
        |               ^^^^^ pattern `&mut TypeParamBound::PreciseCapture(_)` not covered
        |
        = help: ensure that all variants are matched explicitly by adding the suggested match arms
        = note: the matched value is of type `&mut TypeParamBound` and the `non_exhaustive_omitted_patterns` attribute was found
    note: the lint level is defined here
       --> serde_derive/src/internals/receiver.rs:210:53
        |
    210 |             #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
        |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    warning: some variants are not matched explicitly
       --> serde_derive/src/bound.rs:227:19
        |
    227 |             match bound {
        |                   ^^^^^ pattern `&TypeParamBound::PreciseCapture(_)` not covered
        |
        = help: ensure that all variants are matched explicitly by adding the suggested match arms
        = note: the matched value is of type `&TypeParamBound` and the `non_exhaustive_omitted_patterns` attribute was found
    note: the lint level is defined here
       --> serde_derive/src/bound.rs:228:57
        |
    228 |                 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
        |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-10-20 20:35:48 -07:00
David Tolnay 4b3178b053 Ignore needless_lifetimes clippy lint
warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/value.rs:124:6
        |
    124 | impl<'de, E> IntoDeserializer<'de, E> for ()
        |      ^^^                      ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
        = note: `-W clippy::needless-lifetimes` implied by `-W clippy::all`
        = help: to override `-W clippy::all` add `#[allow(clippy::needless_lifetimes)]`
    help: elide the lifetimes
        |
    124 - impl<'de, E> IntoDeserializer<'de, E> for ()
    124 + impl<E> IntoDeserializer<'_, E> for ()
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/value.rs:196:6
        |
    196 | impl<'de, E> IntoDeserializer<'de, E> for !
        |      ^^^                      ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    196 - impl<'de, E> IntoDeserializer<'de, E> for !
    196 + impl<E> IntoDeserializer<'_, E> for !
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/value.rs:317:6
        |
    317 | impl<'de, E> IntoDeserializer<'de, E> for u32
        |      ^^^                      ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    317 - impl<'de, E> IntoDeserializer<'de, E> for u32
    317 + impl<E> IntoDeserializer<'_, E> for u32
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/value.rs:406:6
        |
    406 | impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str
        |      ^^^                          ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    406 - impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str
    406 + impl<'a, E> IntoDeserializer<'_, E> for &'a str
        |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/value.rs:427:11
        |
    427 | impl<'de, 'a, E> de::Deserializer<'de> for StrDeserializer<'a, E>
        |           ^^                                               ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    427 - impl<'de, 'a, E> de::Deserializer<'de> for StrDeserializer<'a, E>
    427 + impl<'de, E> de::Deserializer<'de> for StrDeserializer<'_, E>
        |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/value.rs:461:11
        |
    461 | impl<'de, 'a, E> de::EnumAccess<'de> for StrDeserializer<'a, E>
        |           ^^                                             ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    461 - impl<'de, 'a, E> de::EnumAccess<'de> for StrDeserializer<'a, E>
    461 + impl<'de, E> de::EnumAccess<'de> for StrDeserializer<'_, E>
        |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/value.rs:476:6
        |
    476 | impl<'a, E> Debug for StrDeserializer<'a, E> {
        |      ^^                               ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    476 - impl<'a, E> Debug for StrDeserializer<'a, E> {
    476 + impl<E> Debug for StrDeserializer<'_, E> {
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/value.rs:555:6
        |
    555 | impl<'de, E> Debug for BorrowedStrDeserializer<'de, E> {
        |      ^^^                                       ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    555 - impl<'de, E> Debug for BorrowedStrDeserializer<'de, E> {
    555 + impl<E> Debug for BorrowedStrDeserializer<'_, E> {
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/value.rs:586:6
        |
    586 | impl<'de, E> IntoDeserializer<'de, E> for String
        |      ^^^                      ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    586 - impl<'de, E> IntoDeserializer<'de, E> for String
    586 + impl<E> IntoDeserializer<'_, E> for String
        |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/value.rs:680:6
        |
    680 | impl<'a, E> Clone for CowStrDeserializer<'a, E> {
        |      ^^                                  ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    680 - impl<'a, E> Clone for CowStrDeserializer<'a, E> {
    680 + impl<E> Clone for CowStrDeserializer<'_, E> {
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/value.rs:691:6
        |
    691 | impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str>
        |      ^^^                          ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    691 - impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str>
    691 + impl<'a, E> IntoDeserializer<'_, E> for Cow<'a, str>
        |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/value.rs:714:11
        |
    714 | impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E>
        |           ^^                                                  ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    714 - impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E>
    714 + impl<'de, E> de::Deserializer<'de> for CowStrDeserializer<'_, E>
        |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/value.rs:752:11
        |
    752 | impl<'de, 'a, E> de::EnumAccess<'de> for CowStrDeserializer<'a, E>
        |           ^^                                                ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    752 - impl<'de, 'a, E> de::EnumAccess<'de> for CowStrDeserializer<'a, E>
    752 + impl<'de, E> de::EnumAccess<'de> for CowStrDeserializer<'_, E>
        |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/value.rs:768:6
        |
    768 | impl<'a, E> Debug for CowStrDeserializer<'a, E> {
        |      ^^                                  ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    768 - impl<'a, E> Debug for CowStrDeserializer<'a, E> {
    768 + impl<E> Debug for CowStrDeserializer<'_, E> {
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/value.rs:797:6
        |
    797 | impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a [u8]
        |      ^^^                          ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    797 - impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a [u8]
    797 + impl<'a, E> IntoDeserializer<'_, E> for &'a [u8]
        |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/value.rs:808:11
        |
    808 | impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
        |           ^^                                             ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    808 - impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
    808 + impl<'de, E> Deserializer<'de> for BytesDeserializer<'_, E>
        |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/value.rs:828:6
        |
    828 | impl<'a, E> Debug for BytesDeserializer<'a, E> {
        |      ^^                                 ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    828 - impl<'a, E> Debug for BytesDeserializer<'a, E> {
    828 + impl<E> Debug for BytesDeserializer<'_, E> {
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/value.rs:876:6
        |
    876 | impl<'de, E> Debug for BorrowedBytesDeserializer<'de, E> {
        |      ^^^                                         ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    876 - impl<'de, E> Debug for BorrowedBytesDeserializer<'de, E> {
    876 + impl<E> Debug for BorrowedBytesDeserializer<'_, E> {
        |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/value.rs:1101:6
         |
    1101 | impl<'de, I, E> MapDeserializer<'de, I, E>
         |      ^^^                        ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1101 - impl<'de, I, E> MapDeserializer<'de, I, E>
    1101 + impl<I, E> MapDeserializer<'_, I, E>
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/value.rs:1118:6
         |
    1118 | impl<'de, I, E> MapDeserializer<'de, I, E>
         |      ^^^                        ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1118 - impl<'de, I, E> MapDeserializer<'de, I, E>
    1118 + impl<I, E> MapDeserializer<'_, I, E>
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/value.rs:1141:6
         |
    1141 | impl<'de, I, E> MapDeserializer<'de, I, E>
         |      ^^^                        ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1141 - impl<'de, I, E> MapDeserializer<'de, I, E>
    1141 + impl<I, E> MapDeserializer<'_, I, E>
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/value.rs:1287:6
         |
    1287 | impl<'de, I, E> Clone for MapDeserializer<'de, I, E>
         |      ^^^                                  ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1287 - impl<'de, I, E> Clone for MapDeserializer<'de, I, E>
    1287 + impl<I, E> Clone for MapDeserializer<'_, I, E>
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/value.rs:1304:6
         |
    1304 | impl<'de, I, E> Debug for MapDeserializer<'de, I, E>
         |      ^^^                                  ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1304 - impl<'de, I, E> Debug for MapDeserializer<'de, I, E>
    1304 + impl<I, E> Debug for MapDeserializer<'_, I, E>
         |

    warning: the following explicit lifetimes could be elided: 'de
      --> serde/src/de/impls.rs:17:6
       |
    17 | impl<'de> Visitor<'de> for UnitVisitor {
       |      ^^^          ^^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
       |
    17 - impl<'de> Visitor<'de> for UnitVisitor {
    17 + impl Visitor<'_> for UnitVisitor {
       |

    warning: the following explicit lifetimes could be elided: 'de
      --> serde/src/de/impls.rs:56:6
       |
    56 | impl<'de> Visitor<'de> for BoolVisitor {
       |      ^^^          ^^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
       |
    56 - impl<'de> Visitor<'de> for BoolVisitor {
    56 + impl Visitor<'_> for BoolVisitor {
       |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/impls.rs:550:6
        |
    550 | impl<'de> Visitor<'de> for CharVisitor {
        |      ^^^          ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    550 - impl<'de> Visitor<'de> for CharVisitor {
    550 + impl Visitor<'_> for CharVisitor {
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/impls.rs:596:6
        |
    596 | impl<'de> Visitor<'de> for StringVisitor {
        |      ^^^          ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    596 - impl<'de> Visitor<'de> for StringVisitor {
    596 + impl Visitor<'_> for StringVisitor {
        |

    warning: the following explicit lifetimes could be elided: 'de, 'a
       --> serde/src/de/impls.rs:642:6
        |
    642 | impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
        |      ^^  ^^^          ^^^                           ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    642 - impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
    642 + impl Visitor<'_> for StringInPlaceVisitor<'_> {
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/de/impls.rs:953:6
        |
    953 | impl<'de, T> Visitor<'de> for PhantomDataVisitor<T>
        |      ^^^             ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    953 - impl<'de, T> Visitor<'de> for PhantomDataVisitor<T>
    953 + impl<T> Visitor<'_> for PhantomDataVisitor<T>
        |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/de/impls.rs:1195:14
         |
    1195 |         impl<'a, 'de, T> Visitor<'de> for VecInPlaceVisitor<'a, T>
         |              ^^                                             ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1195 -         impl<'a, 'de, T> Visitor<'de> for VecInPlaceVisitor<'a, T>
    1195 +         impl<'de, T> Visitor<'de> for VecInPlaceVisitor<'_, T>
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/impls.rs:1838:6
         |
    1838 | impl<'de> Visitor<'de> for PathBufVisitor {
         |      ^^^          ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1838 - impl<'de> Visitor<'de> for PathBufVisitor {
    1838 + impl Visitor<'_> for PathBufVisitor {
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/de/impls.rs:1991:11
         |
    1991 | impl<'de, 'a, T> Deserialize<'de> for Cow<'a, T>
         |           ^^                              ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1991 - impl<'de, 'a, T> Deserialize<'de> for Cow<'a, T>
    1991 + impl<'de, T> Deserialize<'de> for Cow<'_, T>
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/impls.rs:2161:22
         |
    2161 |                 impl<'de> Visitor<'de> for FieldVisitor {
         |                      ^^^          ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2161 -                 impl<'de> Visitor<'de> for FieldVisitor {
    2161 +                 impl Visitor<'_> for FieldVisitor {
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/impls.rs:2300:22
         |
    2300 |                 impl<'de> Visitor<'de> for FieldVisitor {
         |                      ^^^          ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2300 -                 impl<'de> Visitor<'de> for FieldVisitor {
    2300 +                 impl Visitor<'_> for FieldVisitor {
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/impls.rs:2501:18
         |
    2501 |             impl<'de> Visitor<'de> for FieldVisitor {
         |                  ^^^          ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2501 -             impl<'de> Visitor<'de> for FieldVisitor {
    2501 +             impl Visitor<'_> for FieldVisitor {
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/impls.rs:2658:18
         |
    2658 |             impl<'de> Visitor<'de> for FieldVisitor {
         |                  ^^^          ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2658 -             impl<'de> Visitor<'de> for FieldVisitor {
    2658 +             impl Visitor<'_> for FieldVisitor {
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/impls.rs:2796:18
         |
    2796 |             impl<'de> Visitor<'de> for FieldVisitor {
         |                  ^^^          ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2796 -             impl<'de> Visitor<'de> for FieldVisitor {
    2796 +             impl Visitor<'_> for FieldVisitor {
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/impls.rs:2907:22
         |
    2907 |                 impl<'de> Visitor<'de> for FieldVisitor {
         |                      ^^^          ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2907 -                 impl<'de> Visitor<'de> for FieldVisitor {
    2907 +                 impl Visitor<'_> for FieldVisitor {
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/impls.rs:3018:22
         |
    3018 |                 impl<'de> Visitor<'de> for FieldVisitor {
         |                      ^^^          ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    3018 -                 impl<'de> Visitor<'de> for FieldVisitor {
    3018 +                 impl Visitor<'_> for FieldVisitor {
         |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/de/impls.rs:3166:6
         |
    3166 | impl<'de, T> Visitor<'de> for FromStrVisitor<T>
         |      ^^^             ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    3166 - impl<'de, T> Visitor<'de> for FromStrVisitor<T>
    3166 + impl<T> Visitor<'_> for FromStrVisitor<T>
         |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/mod.rs:397:6
        |
    397 | impl<'a> fmt::Display for Unexpected<'a> {
        |      ^^                              ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    397 - impl<'a> fmt::Display for Unexpected<'a> {
    397 + impl fmt::Display for Unexpected<'_> {
        |

    warning: the following explicit lifetimes could be elided: 'f, 'a
        --> serde/src/de/mod.rs:2309:14
         |
    2309 |         impl<'f, 'a> fmt::Write for LookForDecimalPoint<'f, 'a> {
         |              ^^  ^^                                     ^^  ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2309 -         impl<'f, 'a> fmt::Write for LookForDecimalPoint<'f, 'a> {
    2309 +         impl fmt::Write for LookForDecimalPoint<'_, '_> {
         |

    warning: the following explicit lifetimes could be elided: 'a
      --> serde/src/ser/fmt.rs:38:6
       |
    38 | impl<'a> Serializer for &mut fmt::Formatter<'a> {
       |      ^^                                     ^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
       |
    38 - impl<'a> Serializer for &mut fmt::Formatter<'a> {
    38 + impl Serializer for &mut fmt::Formatter<'_> {
       |

    warning: the following explicit lifetimes could be elided: 'a
      --> serde/src/ser/impls.rs:62:6
       |
    62 | impl<'a> Serialize for fmt::Arguments<'a> {
       |      ^^                               ^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
       |
    62 - impl<'a> Serialize for fmt::Arguments<'a> {
    62 + impl Serialize for fmt::Arguments<'_> {
       |

    warning: the following explicit lifetimes could be elided: 'a
      --> serde/src/format.rs:20:6
       |
    20 | impl<'a> Write for Buf<'a> {
       |      ^^                ^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
       |
    20 - impl<'a> Write for Buf<'a> {
    20 + impl Write for Buf<'_> {
       |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/private/de.rs:254:10
        |
    254 |     impl<'de> Content<'de> {
        |          ^^^          ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    254 -     impl<'de> Content<'de> {
    254 +     impl Content<'_> {
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/private/de.rs:333:10
        |
    333 |     impl<'de> ContentVisitor<'de> {
        |          ^^^                 ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    333 -     impl<'de> ContentVisitor<'de> {
    333 +     impl ContentVisitor<'_> {
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/private/de.rs:553:10
        |
    553 |     impl<'de> TagOrContentVisitor<'de> {
        |          ^^^                      ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    553 -     impl<'de> TagOrContentVisitor<'de> {
    553 +     impl TagOrContentVisitor<'_> {
        |

    warning: the following explicit lifetimes could be elided: 'de
       --> serde/src/private/de.rs:937:10
        |
    937 |     impl<'de> Visitor<'de> for TagOrContentFieldVisitor {
        |          ^^^          ^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    937 -     impl<'de> Visitor<'de> for TagOrContentFieldVisitor {
    937 +     impl Visitor<'_> for TagOrContentFieldVisitor {
        |

    warning: the following explicit lifetimes could be elided: 'de
        --> serde/src/private/de.rs:1014:10
         |
    1014 |     impl<'de> Visitor<'de> for TagContentOtherFieldVisitor {
         |          ^^^          ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1014 -     impl<'de> Visitor<'de> for TagContentOtherFieldVisitor {
    1014 +     impl Visitor<'_> for TagContentOtherFieldVisitor {
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/private/de.rs:1652:10
         |
    1652 |     impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E>
         |          ^^                                 ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1652 -     impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E>
    1652 +     impl<'de, E> ContentRefDeserializer<'_, 'de, E>
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/private/de.rs:1735:15
         |
    1735 |     impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, 'de, E>
         |               ^^                                                  ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1735 -     impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, 'de, E>
    1735 +     impl<'de, E> Deserializer<'de> for ContentRefDeserializer<'_, 'de, E>
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/private/de.rs:2162:15
         |
    2162 |     impl<'de, 'a, E> de::VariantAccess<'de> for VariantRefDeserializer<'a, 'de, E>
         |               ^^                                                       ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2162 -     impl<'de, 'a, E> de::VariantAccess<'de> for VariantRefDeserializer<'a, 'de, E>
    2162 +     impl<'de, E> de::VariantAccess<'de> for VariantRefDeserializer<'_, 'de, E>
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/private/de.rs:2259:15
         |
    2259 |     impl<'de, 'a, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'a, 'de, E>
         |               ^^                                                             ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2259 -     impl<'de, 'a, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'a, 'de, E>
    2259 +     impl<'de, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'_, 'de, E>
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/private/de.rs:2288:15
         |
    2288 |     impl<'de, 'a> Visitor<'de> for InternallyTaggedUnitVisitor<'a> {
         |               ^^                                               ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2288 -     impl<'de, 'a> Visitor<'de> for InternallyTaggedUnitVisitor<'a> {
    2288 +     impl<'de> Visitor<'de> for InternallyTaggedUnitVisitor<'_> {
         |

    warning: the following explicit lifetimes could be elided: 'a, 'de
        --> serde/src/private/de.rs:2333:10
         |
    2333 |     impl<'de, 'a> Visitor<'de> for UntaggedUnitVisitor<'a> {
         |          ^^^  ^^          ^^^                          ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2333 -     impl<'de, 'a> Visitor<'de> for UntaggedUnitVisitor<'a> {
    2333 +     impl Visitor<'_> for UntaggedUnitVisitor<'_> {
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/private/de.rs:2396:11
         |
    2396 | impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E>
         |           ^^                                           ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2396 - impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E>
    2396 + impl<'de, E> Deserializer<'de> for StrDeserializer<'_, E>
         |

    warning: the following explicit lifetimes could be elided: 'a, 'de
        --> serde/src/private/de.rs:2498:6
         |
    2498 | impl<'a, 'de, E> FlatMapDeserializer<'a, 'de, E>
         |      ^^  ^^^                         ^^  ^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2498 - impl<'a, 'de, E> FlatMapDeserializer<'a, 'de, E>
    2498 + impl<E> FlatMapDeserializer<'_, '_, E>
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/private/de.rs:2522:6
         |
    2522 | impl<'a, 'de, E> Deserializer<'de> for FlatMapDeserializer<'a, 'de, E>
         |      ^^                                                    ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2522 - impl<'a, 'de, E> Deserializer<'de> for FlatMapDeserializer<'a, 'de, E>
    2522 + impl<'de, E> Deserializer<'de> for FlatMapDeserializer<'_, 'de, E>
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/private/de.rs:2658:6
         |
    2658 | impl<'a, 'de, E> MapAccess<'de> for FlatMapAccess<'a, 'de, E>
         |      ^^                                           ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2658 - impl<'a, 'de, E> MapAccess<'de> for FlatMapAccess<'a, 'de, E>
    2658 + impl<'de, E> MapAccess<'de> for FlatMapAccess<'_, 'de, E>
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/private/de.rs:2702:6
         |
    2702 | impl<'a, 'de, E> MapAccess<'de> for FlatStructAccess<'a, 'de, E>
         |      ^^                                              ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    2702 - impl<'a, 'de, E> MapAccess<'de> for FlatStructAccess<'a, 'de, E>
    2702 + impl<'de, E> MapAccess<'de> for FlatStructAccess<'_, 'de, E>
         |

    warning: the following explicit lifetimes could be elided: 'a
     --> serde/src/de/seed.rs:8:6
      |
    8 | impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T>
      |      ^^                                               ^^
      |
      = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
      |
    8 - impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T>
    8 + impl<'de, T> DeserializeSeed<'de> for InPlaceSeed<'_, T>
      |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde_derive/src/internals/case.rs:124:6
        |
    124 | impl<'a> Display for ParseError<'a> {
        |      ^^                         ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
        = note: `-W clippy::needless-lifetimes` implied by `-W clippy::all`
        = help: to override `-W clippy::all` add `#[allow(clippy::needless_lifetimes)]`
    help: elide the lifetimes
        |
    124 - impl<'a> Display for ParseError<'a> {
    124 + impl Display for ParseError<'_> {
        |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde_derive/src/de.rs:3042:6
         |
    3042 | impl<'a> ToTokens for DeImplGenerics<'a> {
         |      ^^                              ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    3042 - impl<'a> ToTokens for DeImplGenerics<'a> {
    3042 + impl ToTokens for DeImplGenerics<'_> {
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde_derive/src/de.rs:3124:6
         |
    3124 | impl<'a> ToTokens for DeTypeGenerics<'a> {
         |      ^^                              ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    3124 - impl<'a> ToTokens for DeTypeGenerics<'a> {
    3124 + impl ToTokens for DeTypeGenerics<'_> {
         |

    warning: the following explicit lifetimes could be elided: 'a
      --> test_suite/tests/test_serde_path.rs:15:10
       |
    15 |     impl<'a> AssertNotSerdeDeserialize<'a> for Foo {}
       |          ^^                            ^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
       = note: `-W clippy::needless-lifetimes` implied by `-W clippy::all`
       = help: to override `-W clippy::all` add `#[allow(clippy::needless_lifetimes)]`
    help: elide the lifetimes
       |
    15 -     impl<'a> AssertNotSerdeDeserialize<'a> for Foo {}
    15 +     impl AssertNotSerdeDeserialize<'_> for Foo {}
       |
2024-10-07 21:02:22 +02:00
David Tolnay 8e1ae68569 Resolve some needless_lifetimes clippy lints
warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/mod.rs:489:6
        |
    489 | impl<'a> Expected for &'a str {
        |      ^^                ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    489 - impl<'a> Expected for &'a str {
    489 + impl Expected for &str {
        |

    warning: the following explicit lifetimes could be elided: 'a
       --> serde/src/de/mod.rs:495:6
        |
    495 | impl<'a> Display for Expected + 'a {
        |      ^^                         ^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
        |
    495 - impl<'a> Display for Expected + 'a {
    495 + impl Display for Expected + '_ {
        |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/de/mod.rs:1744:11
         |
    1744 | impl<'de, 'a, A> SeqAccess<'de> for &'a mut A
         |           ^^                         ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1744 - impl<'de, 'a, A> SeqAccess<'de> for &'a mut A
    1744 + impl<'de, A> SeqAccess<'de> for &mut A
         |

    warning: the following explicit lifetimes could be elided: 'a
        --> serde/src/de/mod.rs:1897:11
         |
    1897 | impl<'de, 'a, A> MapAccess<'de> for &'a mut A
         |           ^^                         ^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
         |
    1897 - impl<'de, 'a, A> MapAccess<'de> for &'a mut A
    1897 + impl<'de, A> MapAccess<'de> for &mut A
         |

    warning: the following explicit lifetimes could be elided: 'a, 'b
      --> serde/src/ser/fmt.rs:38:6
       |
    38 | impl<'a, 'b> Serializer for &'a mut fmt::Formatter<'b> {
       |      ^^  ^^                  ^^                    ^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
       |
    38 - impl<'a, 'b> Serializer for &'a mut fmt::Formatter<'b> {
    38 + impl Serializer for &mut fmt::Formatter<'_> {
       |

    warning: the following explicit lifetimes could be elided: 'a
      --> serde_derive/src/internals/symbol.rs:49:6
       |
    49 | impl<'a> PartialEq<Symbol> for &'a Ident {
       |      ^^                         ^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
       |
    49 - impl<'a> PartialEq<Symbol> for &'a Ident {
    49 + impl PartialEq<Symbol> for &Ident {
       |

    warning: the following explicit lifetimes could be elided: 'a
      --> serde_derive/src/internals/symbol.rs:61:6
       |
    61 | impl<'a> PartialEq<Symbol> for &'a Path {
       |      ^^                         ^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
       |
    61 - impl<'a> PartialEq<Symbol> for &'a Path {
    61 + impl PartialEq<Symbol> for &Path {
       |
2024-10-07 20:58:23 +02:00
David Tolnay 31000e1874 Add a funding file 2024-09-23 15:38:18 -07:00
David Tolnay 4487cb26c7 Merge pull request #2822 from dtolnay/mapcontentdeserializer
Remove explicit ContentDeserializer construction in visit functions
2024-09-07 16:41:38 -07:00
David Tolnay aba4e18553 Remove explicit ContentDeserializer construction in visit functions 2024-09-07 16:31:03 -07:00
David Tolnay c82f2580b4 Merge pull request #2821 from dtolnay/clos
Eliminate closures capturing needlessly many type parameters
2024-09-06 16:54:36 -07:00
David Tolnay 1d7b009aec Eliminate closures capturing needlessly many type parameters 2024-09-06 16:29:41 -07:00
David Tolnay 89c4b02bf3 Release 1.0.210 2024-09-06 11:17:20 -07:00
David Tolnay eeb8e44cda Merge pull request #2818 from dtolnay/coreerror
Stabilize no-std Error trait
2024-09-06 11:16:43 -07:00
David Tolnay 785c2d9605 Stabilize no-std StdError trait 2024-09-06 11:12:13 -07:00
David Tolnay d549f048e1 Reformat parse_ip_impl definition and calls 2024-09-06 11:05:54 -07:00
David Tolnay 4c0dd63011 Delete attr support from core::net deserialization macros 2024-09-06 11:05:54 -07:00
David Tolnay 26fb134165 Relocate cfg attrs out of parse_ip_impl and parse_socket_impl 2024-09-06 11:05:53 -07:00
David Tolnay 07e614b52b Merge pull request #2817 from dtolnay/corenet
Delete doc(cfg) attribute from impls that are supported in no-std
2024-09-06 11:05:48 -07:00
David Tolnay b1f899fbe8 Delete doc(cfg) attribute from impls that are supported in no-std 2024-09-06 11:00:55 -07:00
David Tolnay b4f860e627 Merge pull request #2816 from MathiasKoch/chore/core-net
Implement serialize/deserialize for core::net instead of std::net
2024-09-06 10:59:24 -07:00
Mathias d940fe1b49 Reuse existing Buf wrapper as replacement for std::io::Write 2024-09-05 14:24:44 +02:00
Mathias f2899a9e06 Implement serialize/deserialize for core::net instead of std::net if running rust version newer than 1.77, where core::net was stabilized 2024-09-05 11:07:09 +02:00
David Tolnay 3aca38d2d3 Upload CI Cargo.lock for reproducing failures 2024-08-25 12:12:25 -07:00
Mingun 8b769fcc20 Remove unused component from tuple 2024-08-12 19:05:57 +05:00
Mingun 9c954264f4 Include variant aliases in error messages 2024-08-12 19:05:04 +05:00
Mingun 74b538b8ec Produce error about mismatched types of #[serde(with = "...")] and #[serde(default = "...")] attributes on the attribute itself 2024-08-05 00:29:37 +05:00
Mingun 291ec50d98 Add tests that ensures that error reported for a path for with and default attributes 2024-08-05 00:29:37 +05:00
Mingun 21c7fd1bd5 Add tests of #[serde(default)] attribute for units and unions 2024-07-23 21:00:11 +05:00
61 changed files with 1504 additions and 296 deletions
+1
View File
@@ -0,0 +1 @@
github: dtolnay
+12 -3
View File
@@ -21,6 +21,12 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- run: cd test_suite && cargo test --features unstable
- uses: actions/upload-artifact@v4
if: always()
with:
name: Cargo.lock
path: Cargo.lock
continue-on-error: true
windows:
name: Test suite (windows)
@@ -90,13 +96,16 @@ jobs:
- run: cd serde && cargo build
derive:
name: Rust 1.56.0
name: Rust 1.61.0
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.56.0
- run: sed -i '/"test_suite"/d' Cargo.toml
- uses: dtolnay/rust-toolchain@1.61.0
- run: |
sed -i 's/proc-macro2 = { workspace = true/proc-macro2 = { version = "1"/' serde_derive*/Cargo.toml
sed -i 's/quote = { workspace = true/quote = { version = "1"/' serde_derive*/Cargo.toml
sed -i 's/syn = { workspace = true/syn = { version = "2"/' serde_derive*/Cargo.toml
- run: cd serde && cargo check --no-default-features
- run: cd serde && cargo check
- run: cd serde_derive && cargo check
+1 -1
View File
@@ -12,4 +12,4 @@ serde = { path = "serde" }
[workspace.dependencies]
proc-macro2 = { version = "1.0.74", default-features = false }
quote = { version = "1.0.35", default-features = false }
syn = { version = "2.0.46", default-features = false }
syn = { version = "2.0.81", default-features = false }
+2 -2
View File
@@ -1,4 +1,4 @@
# Serde &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![serde msrv]][Rust 1.31] [![serde_derive msrv]][Rust 1.56]
# Serde &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![serde msrv]][Rust 1.31] [![serde_derive msrv]][Rust 1.61]
[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master
[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster
@@ -7,7 +7,7 @@
[serde msrv]: https://img.shields.io/crates/msrv/serde.svg?label=serde%20msrv&color=lightgray
[serde_derive msrv]: https://img.shields.io/crates/msrv/serde_derive.svg?label=serde_derive%20msrv&color=lightgray
[Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html
[Rust 1.56]: https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html
[Rust 1.61]: https://blog.rust-lang.org/2022/05/19/Rust-1.61.0.html
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.209"
version = "1.0.215"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs"
categories = ["encoding", "no-std", "no-std::no-alloc"]
@@ -37,7 +37,7 @@ rustdoc-args = ["--generate-link-to-definition"]
# is compatible with exactly one serde release because the generated code
# involves nonpublic APIs which are not bound by semver.
[target.'cfg(any())'.dependencies]
serde_derive = { version = "=1.0.209", path = "../serde_derive" }
serde_derive = { version = "=1.0.215", path = "../serde_derive" }
### FEATURES #################################################################
+19 -5
View File
@@ -15,6 +15,8 @@ fn main() {
if minor >= 77 {
println!("cargo:rustc-check-cfg=cfg(no_core_cstr)");
println!("cargo:rustc-check-cfg=cfg(no_core_error)");
println!("cargo:rustc-check-cfg=cfg(no_core_net)");
println!("cargo:rustc-check-cfg=cfg(no_core_num_saturating)");
println!("cargo:rustc-check-cfg=cfg(no_core_try_from)");
println!("cargo:rustc-check-cfg=cfg(no_diagnostic_namespace)");
@@ -48,11 +50,6 @@ fn main() {
println!("cargo:rustc-cfg=no_float_copysign");
}
// Current minimum supported version of serde_derive crate is Rust 1.56.
if minor < 56 {
println!("cargo:rustc-cfg=no_serde_derive");
}
// Support for #[cfg(target_has_atomic = "...")] stabilized in Rust 1.60.
if minor < 60 {
println!("cargo:rustc-cfg=no_target_has_atomic");
@@ -74,6 +71,11 @@ fn main() {
}
}
// Current minimum supported version of serde_derive crate is Rust 1.61.
if minor < 61 {
println!("cargo:rustc-cfg=no_serde_derive");
}
// Support for core::ffi::CStr and alloc::ffi::CString stabilized in Rust 1.64.
// https://blog.rust-lang.org/2022/09/22/Rust-1.64.0.html#c-compatible-ffi-types-in-core-and-alloc
if minor < 64 {
@@ -86,11 +88,23 @@ fn main() {
println!("cargo:rustc-cfg=no_core_num_saturating");
}
// Support for core::net stabilized in Rust 1.77.
// https://blog.rust-lang.org/2024/03/21/Rust-1.77.0.html
if minor < 77 {
println!("cargo:rustc-cfg=no_core_net");
}
// Support for the `#[diagnostic]` tool attribute namespace
// https://blog.rust-lang.org/2024/05/02/Rust-1.78.0.html#diagnostic-attributes
if minor < 78 {
println!("cargo:rustc-cfg=no_diagnostic_namespace");
}
// The Error trait became available in core in 1.81.
// https://blog.rust-lang.org/2024/09/05/Rust-1.81.0.html#coreerrorerror
if minor < 81 {
println!("cargo:rustc-cfg=no_core_error");
}
}
fn rustc_minor_version() -> Option<u32> {
+16 -30
View File
@@ -1583,12 +1583,9 @@ map_impl! {
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", not(no_core_net)))]
macro_rules! parse_ip_impl {
(
$(#[$attr:meta])*
$ty:ty, $expecting:expr, $size:tt
) => {
$(#[$attr])*
($ty:ty, $expecting:expr, $size:tt) => {
impl<'de> Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1604,7 +1601,7 @@ macro_rules! parse_ip_impl {
};
}
#[cfg(feature = "std")]
#[cfg(any(feature = "std", not(no_core_net)))]
macro_rules! variant_identifier {
(
$name_kind:ident ($($variant:ident; $bytes:expr; $index:expr),*)
@@ -1679,7 +1676,7 @@ macro_rules! variant_identifier {
}
}
#[cfg(feature = "std")]
#[cfg(any(feature = "std", not(no_core_net)))]
macro_rules! deserialize_enum {
(
$name:ident $name_kind:ident ($($variant:ident; $bytes:expr; $index:expr),*)
@@ -1716,8 +1713,7 @@ macro_rules! deserialize_enum {
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[cfg(any(feature = "std", not(no_core_net)))]
impl<'de> Deserialize<'de> for net::IpAddr {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1736,25 +1732,18 @@ impl<'de> Deserialize<'de> for net::IpAddr {
}
}
parse_ip_impl! {
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
net::Ipv4Addr, "IPv4 address", 4
}
#[cfg(any(feature = "std", not(no_core_net)))]
parse_ip_impl!(net::Ipv4Addr, "IPv4 address", 4);
parse_ip_impl! {
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
net::Ipv6Addr, "IPv6 address", 16
}
#[cfg(any(feature = "std", not(no_core_net)))]
parse_ip_impl!(net::Ipv6Addr, "IPv6 address", 16);
#[cfg(any(feature = "std", not(no_core_net)))]
macro_rules! parse_socket_impl {
(
$(#[$attr:meta])*
$ty:ty, $expecting:tt,
$new:expr,
) => {
$(#[$attr])*
impl<'de> Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1770,8 +1759,7 @@ macro_rules! parse_socket_impl {
};
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[cfg(any(feature = "std", not(no_core_net)))]
impl<'de> Deserialize<'de> for net::SocketAddr {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1790,16 +1778,14 @@ impl<'de> Deserialize<'de> for net::SocketAddr {
}
}
#[cfg(any(feature = "std", not(no_core_net)))]
parse_socket_impl! {
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
net::SocketAddrV4, "IPv4 socket address",
|(ip, port)| net::SocketAddrV4::new(ip, port),
}
#[cfg(any(feature = "std", not(no_core_net)))]
parse_socket_impl! {
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
net::SocketAddrV6, "IPv6 socket address",
|(ip, port)| net::SocketAddrV6::new(ip, port, 0, 0),
}
@@ -3160,13 +3146,13 @@ atomic_impl! {
AtomicU64 "64"
}
#[cfg(feature = "std")]
#[cfg(any(feature = "std", not(no_core_net)))]
struct FromStrVisitor<T> {
expecting: &'static str,
ty: PhantomData<T>,
}
#[cfg(feature = "std")]
#[cfg(any(feature = "std", not(no_core_net)))]
impl<T> FromStrVisitor<T> {
fn new(expecting: &'static str) -> Self {
FromStrVisitor {
@@ -3176,7 +3162,7 @@ impl<T> FromStrVisitor<T> {
}
}
#[cfg(feature = "std")]
#[cfg(any(feature = "std", not(no_core_net)))]
impl<'de, T> Visitor<'de> for FromStrVisitor<T>
where
T: str::FromStr,
+8 -9
View File
@@ -118,17 +118,16 @@ use crate::lib::*;
pub mod value;
mod format;
mod ignored_any;
mod impls;
pub(crate) mod size_hint;
pub use self::ignored_any::IgnoredAny;
#[cfg(not(any(feature = "std", feature = "unstable")))]
#[cfg(all(not(feature = "std"), no_core_error))]
#[doc(no_inline)]
pub use crate::std_error::Error as StdError;
#[cfg(all(feature = "unstable", not(feature = "std")))]
#[cfg(not(any(feature = "std", no_core_error)))]
#[doc(no_inline)]
pub use core::error::Error as StdError;
#[cfg(feature = "std")]
@@ -487,13 +486,13 @@ where
}
}
impl<'a> Expected for &'a str {
impl Expected for &str {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(self)
}
}
impl<'a> Display for Expected + 'a {
impl Display for Expected + '_ {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Expected::fmt(self, formatter)
}
@@ -1374,7 +1373,7 @@ pub trait Visitor<'de>: Sized {
E: Error,
{
let mut buf = [0u8; 58];
let mut writer = format::Buf::new(&mut buf);
let mut writer = crate::format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as i128", v)).unwrap();
Err(Error::invalid_type(
Unexpected::Other(writer.as_str()),
@@ -1436,7 +1435,7 @@ pub trait Visitor<'de>: Sized {
E: Error,
{
let mut buf = [0u8; 57];
let mut writer = format::Buf::new(&mut buf);
let mut writer = crate::format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as u128", v)).unwrap();
Err(Error::invalid_type(
Unexpected::Other(writer.as_str()),
@@ -1742,7 +1741,7 @@ pub trait SeqAccess<'de> {
}
}
impl<'de, 'a, A> SeqAccess<'de> for &'a mut A
impl<'de, A> SeqAccess<'de> for &mut A
where
A: ?Sized + SeqAccess<'de>,
{
@@ -1895,7 +1894,7 @@ pub trait MapAccess<'de> {
}
}
impl<'de, 'a, A> MapAccess<'de> for &'a mut A
impl<'de, A> MapAccess<'de> for &mut A
where
A: ?Sized + MapAccess<'de>,
{
+174
View File
@@ -175,6 +175,17 @@ where
}
}
impl<'de, E> IntoDeserializer<'de, E> for UnitDeserializer<E>
where
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
impl<E> Debug for UnitDeserializer<E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.debug_struct("UnitDeserializer").finish()
@@ -225,6 +236,18 @@ where
}
}
#[cfg(feature = "unstable")]
impl<'de, E> IntoDeserializer<'de, E> for NeverDeserializer<E>
where
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
////////////////////////////////////////////////////////////////////////////////
macro_rules! primitive_deserializer {
@@ -279,6 +302,17 @@ macro_rules! primitive_deserializer {
}
}
impl<'de, E> IntoDeserializer<'de, E> for $name<E>
where
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
impl<E> Debug for $name<E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
@@ -369,6 +403,17 @@ where
}
}
impl<'de, E> IntoDeserializer<'de, E> for U32Deserializer<E>
where
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
impl<'de, E> de::EnumAccess<'de> for U32Deserializer<E>
where
E: de::Error,
@@ -458,6 +503,17 @@ where
}
}
impl<'de, 'a, E> IntoDeserializer<'de, E> for StrDeserializer<'a, E>
where
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
impl<'de, 'a, E> de::EnumAccess<'de> for StrDeserializer<'a, E>
where
E: de::Error,
@@ -537,6 +593,17 @@ where
}
}
impl<'de, E> IntoDeserializer<'de, E> for BorrowedStrDeserializer<'de, E>
where
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
impl<'de, E> de::EnumAccess<'de> for BorrowedStrDeserializer<'de, E>
where
E: de::Error,
@@ -640,6 +707,18 @@ where
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, E> IntoDeserializer<'de, E> for StringDeserializer<E>
where
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, E> de::EnumAccess<'de> for StringDeserializer<E>
where
@@ -748,6 +827,18 @@ where
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> IntoDeserializer<'de, E> for CowStrDeserializer<'a, E>
where
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> de::EnumAccess<'de> for CowStrDeserializer<'a, E>
where
@@ -825,6 +916,17 @@ where
}
}
impl<'de, 'a, E> IntoDeserializer<'de, E> for BytesDeserializer<'a, E>
where
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
impl<'a, E> Debug for BytesDeserializer<'a, E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
@@ -873,6 +975,17 @@ where
}
}
impl<'de, E> IntoDeserializer<'de, E> for BorrowedBytesDeserializer<'de, E>
where
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
impl<'de, E> Debug for BorrowedBytesDeserializer<'de, E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
@@ -952,6 +1065,19 @@ where
}
}
impl<'de, I, T, E> IntoDeserializer<'de, E> for SeqDeserializer<I, E>
where
I: Iterator<Item = T>,
T: IntoDeserializer<'de, E>,
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
impl<'de, I, T, E> de::SeqAccess<'de> for SeqDeserializer<I, E>
where
I: Iterator<Item = T>,
@@ -1083,6 +1209,17 @@ where
}
}
impl<'de, A> IntoDeserializer<'de, A::Error> for SeqAccessDeserializer<A>
where
A: de::SeqAccess<'de>,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer that iterates over a map.
@@ -1197,6 +1334,21 @@ where
}
}
impl<'de, I, E> IntoDeserializer<'de, E> for MapDeserializer<'de, I, E>
where
I: Iterator,
I::Item: private::Pair,
First<I::Item>: IntoDeserializer<'de, E>,
Second<I::Item>: IntoDeserializer<'de, E>,
E: de::Error,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
impl<'de, I, E> de::MapAccess<'de> for MapDeserializer<'de, I, E>
where
I: Iterator,
@@ -1498,6 +1650,17 @@ where
}
}
impl<'de, A> IntoDeserializer<'de, A::Error> for MapAccessDeserializer<A>
where
A: de::MapAccess<'de>,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
impl<'de, A> de::EnumAccess<'de> for MapAccessDeserializer<A>
where
A: de::MapAccess<'de>,
@@ -1551,6 +1714,17 @@ where
}
}
impl<'de, A> IntoDeserializer<'de, A::Error> for EnumAccessDeserializer<A>
where
A: de::EnumAccess<'de>,
{
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
////////////////////////////////////////////////////////////////////////////////
mod private {
+11 -3
View File
@@ -95,7 +95,7 @@
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.209")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.215")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Show which crate feature enables conditionally compiled APIs in documentation.
@@ -144,6 +144,7 @@
clippy::too_many_lines,
// preference
clippy::doc_markdown,
clippy::needless_lifetimes,
clippy::unseparated_literal_suffix,
// false positive
clippy::needless_doctest_main,
@@ -238,8 +239,13 @@ mod lib {
#[cfg(feature = "std")]
pub use std::ffi::CString;
#[cfg(all(not(no_core_net), not(feature = "std")))]
pub use self::core::net;
#[cfg(feature = "std")]
pub use std::{error, net};
pub use std::net;
#[cfg(feature = "std")]
pub use std::error;
#[cfg(feature = "std")]
pub use std::collections::{HashMap, HashSet};
@@ -305,6 +311,8 @@ mod integer128;
pub mod de;
pub mod ser;
mod format;
#[doc(inline)]
pub use crate::de::{Deserialize, Deserializer};
#[doc(inline)]
@@ -318,7 +326,7 @@ pub mod __private;
#[path = "de/seed.rs"]
mod seed;
#[cfg(not(any(feature = "std", feature = "unstable")))]
#[cfg(all(not(feature = "std"), no_core_error))]
mod std_error;
// Re-export #[derive(Serialize, Deserialize)].
+25 -16
View File
@@ -313,6 +313,17 @@ mod content {
}
}
impl<'a, 'de, E> de::IntoDeserializer<'de, E> for &'a Content<'de>
where
E: de::Error,
{
type Deserializer = ContentRefDeserializer<'a, 'de, E>;
fn into_deserializer(self) -> Self::Deserializer {
ContentRefDeserializer::new(self)
}
}
/// Used to capture data in [`Content`] from other deserializers.
/// Cannot capture externally tagged enums, `i128` and `u128`.
struct ContentVisitor<'de> {
@@ -476,14 +487,16 @@ mod content {
where
D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(|v| Content::Some(Box::new(v)))
let v = tri!(Deserialize::deserialize(deserializer));
Ok(Content::Some(Box::new(v)))
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(|v| Content::Newtype(Box::new(v)))
let v = tri!(Deserialize::deserialize(deserializer));
Ok(Content::Newtype(Box::new(v)))
}
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
@@ -1098,8 +1111,7 @@ mod content {
V: Visitor<'de>,
E: de::Error,
{
let seq = content.into_iter().map(ContentDeserializer::new);
let mut seq_visitor = SeqDeserializer::new(seq);
let mut seq_visitor = SeqDeserializer::new(content.into_iter());
let value = tri!(visitor.visit_seq(&mut seq_visitor));
tri!(seq_visitor.end());
Ok(value)
@@ -1113,10 +1125,7 @@ mod content {
V: Visitor<'de>,
E: de::Error,
{
let map = content
.into_iter()
.map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v)));
let mut map_visitor = MapDeserializer::new(map);
let mut map_visitor = MapDeserializer::new(content.into_iter());
let value = tri!(visitor.visit_map(&mut map_visitor));
tri!(map_visitor.end());
Ok(value)
@@ -1694,8 +1703,7 @@ mod content {
V: Visitor<'de>,
E: de::Error,
{
let seq = content.iter().map(ContentRefDeserializer::new);
let mut seq_visitor = SeqDeserializer::new(seq);
let mut seq_visitor = SeqDeserializer::new(content.iter());
let value = tri!(visitor.visit_seq(&mut seq_visitor));
tri!(seq_visitor.end());
Ok(value)
@@ -1709,12 +1717,13 @@ mod content {
V: Visitor<'de>,
E: de::Error,
{
let map = content.iter().map(|(k, v)| {
(
ContentRefDeserializer::new(k),
ContentRefDeserializer::new(v),
)
});
fn content_ref_deserializer_pair<'a, 'de>(
(k, v): &'a (Content<'de>, Content<'de>),
) -> (&'a Content<'de>, &'a Content<'de>) {
(k, v)
}
let map = content.iter().map(content_ref_deserializer_pair);
let mut map_visitor = MapDeserializer::new(map);
let value = tri!(visitor.visit_map(&mut map_visitor));
tri!(map_visitor.end());
+1 -1
View File
@@ -35,7 +35,7 @@ macro_rules! fmt_primitives {
/// }
/// }
/// ```
impl<'a, 'b> Serializer for &'a mut fmt::Formatter<'b> {
impl<'a> Serializer for &mut fmt::Formatter<'a> {
type Ok = ();
type Error = fmt::Error;
type SerializeSeq = Impossible<(), fmt::Error>;
+13 -29
View File
@@ -773,28 +773,17 @@ impl Serialize for SystemTime {
/// statically known to never have more than a constant `MAX_LEN` bytes.
///
/// Panics if the `Display` impl tries to write more than `MAX_LEN` bytes.
#[cfg(feature = "std")]
#[cfg(any(feature = "std", not(no_core_net)))]
macro_rules! serialize_display_bounded_length {
($value:expr, $max:expr, $serializer:expr) => {{
let mut buffer = [0u8; $max];
let remaining_len = {
let mut remaining = &mut buffer[..];
write!(remaining, "{}", $value).unwrap();
remaining.len()
};
let written_len = buffer.len() - remaining_len;
let written = &buffer[..written_len];
// write! only provides fmt::Formatter to Display implementations, which
// has methods write_str and write_char but no method to write arbitrary
// bytes. Therefore `written` must be valid UTF-8.
let written_str = str::from_utf8(written).expect("must be valid UTF-8");
$serializer.serialize_str(written_str)
let mut writer = crate::format::Buf::new(&mut buffer);
write!(&mut writer, "{}", $value).unwrap();
$serializer.serialize_str(writer.as_str())
}};
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[cfg(any(feature = "std", not(no_core_net)))]
impl Serialize for net::IpAddr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -818,7 +807,7 @@ impl Serialize for net::IpAddr {
}
}
#[cfg(feature = "std")]
#[cfg(any(feature = "std", not(no_core_net)))]
const DEC_DIGITS_LUT: &[u8] = b"\
0001020304050607080910111213141516171819\
2021222324252627282930313233343536373839\
@@ -826,7 +815,7 @@ const DEC_DIGITS_LUT: &[u8] = b"\
6061626364656667686970717273747576777879\
8081828384858687888990919293949596979899";
#[cfg(feature = "std")]
#[cfg(any(feature = "std", not(no_core_net)))]
#[inline]
fn format_u8(mut n: u8, out: &mut [u8]) -> usize {
if n >= 100 {
@@ -847,7 +836,7 @@ fn format_u8(mut n: u8, out: &mut [u8]) -> usize {
}
}
#[cfg(feature = "std")]
#[cfg(any(feature = "std", not(no_core_net)))]
#[test]
fn test_format_u8() {
let mut i = 0u8;
@@ -864,8 +853,7 @@ fn test_format_u8() {
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[cfg(any(feature = "std", not(no_core_net)))]
impl Serialize for net::Ipv4Addr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -889,8 +877,7 @@ impl Serialize for net::Ipv4Addr {
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[cfg(any(feature = "std", not(no_core_net)))]
impl Serialize for net::Ipv6Addr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -906,8 +893,7 @@ impl Serialize for net::Ipv6Addr {
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[cfg(any(feature = "std", not(no_core_net)))]
impl Serialize for net::SocketAddr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -931,8 +917,7 @@ impl Serialize for net::SocketAddr {
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[cfg(any(feature = "std", not(no_core_net)))]
impl Serialize for net::SocketAddrV4 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -948,8 +933,7 @@ impl Serialize for net::SocketAddrV4 {
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[cfg(any(feature = "std", not(no_core_net)))]
impl Serialize for net::SocketAddrV6 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
+2 -2
View File
@@ -115,10 +115,10 @@ mod impossible;
pub use self::impossible::Impossible;
#[cfg(not(any(feature = "std", feature = "unstable")))]
#[cfg(all(not(feature = "std"), no_core_error))]
#[doc(no_inline)]
pub use crate::std_error::Error as StdError;
#[cfg(all(feature = "unstable", not(feature = "std")))]
#[cfg(not(any(feature = "std", no_core_error)))]
#[doc(no_inline)]
pub use core::error::Error as StdError;
#[cfg(feature = "std")]
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.209"
version = "1.0.215"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
categories = ["no-std", "no-std::no-alloc"]
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -12,7 +12,7 @@ keywords = ["serde", "serialization", "no_std", "derive"]
license = "MIT OR Apache-2.0"
readme = "crates-io.md"
repository = "https://github.com/serde-rs/serde"
rust-version = "1.56"
rust-version = "1.61"
[features]
default = []
+3 -1
View File
@@ -227,7 +227,9 @@ pub fn with_bound(
match bound {
#![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
syn::TypeParamBound::Trait(bound) => self.visit_path(&bound.path),
syn::TypeParamBound::Lifetime(_) | syn::TypeParamBound::Verbatim(_) => {}
syn::TypeParamBound::Lifetime(_)
| syn::TypeParamBound::PreciseCapture(_)
| syn::TypeParamBound::Verbatim(_) => {}
_ => {}
}
}
+134 -81
View File
@@ -1,5 +1,6 @@
use crate::fragment::{Expr, Fragment, Match, Stmts};
use crate::internals::ast::{Container, Data, Field, Style, Variant};
use crate::internals::name::Name;
use crate::internals::{attr, replace_receiver, ungroup, Ctxt, Derive};
use crate::{bound, dummy, pretend, this};
use proc_macro2::{Literal, Span, TokenStream};
@@ -371,7 +372,11 @@ fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
} else {
let value = match field.attrs.default() {
attr::Default::Default => quote!(_serde::__private::Default::default()),
attr::Default::Path(path) => quote!(#path()),
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
attr::Default::Path(path) => quote_spanned!(path.span()=> #path()),
attr::Default::None => quote!(_serde::__private::PhantomData),
};
quote!(#member: #value)
@@ -757,7 +762,11 @@ fn deserialize_seq(
attr::Default::Default => Some(quote!(
let __default: Self::Value = _serde::__private::Default::default();
)),
attr::Default::Path(path) => Some(quote!(
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
let __default: Self::Value = #path();
)),
attr::Default::None => {
@@ -839,7 +848,11 @@ fn deserialize_seq_in_place(
attr::Default::Default => Some(quote!(
let __default: #this_type #ty_generics = _serde::__private::Default::default();
)),
attr::Default::Path(path) => Some(quote!(
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
let __default: #this_type #ty_generics = #path();
)),
attr::Default::None => {
@@ -863,18 +876,23 @@ fn deserialize_newtype_struct(
) -> TokenStream {
let delife = params.borrowed.de_lifetime();
let field_ty = field.ty;
let deserializer_var = quote!(__e);
let value = match field.attrs.deserialize_with() {
None => {
let span = field.original.span();
let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
quote! {
#func(__e)?
#func(#deserializer_var)?
}
}
Some(path) => {
quote! {
#path(__e)?
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(with = "...")]
// ^^^^^
quote_spanned! {path.span()=>
#path(#deserializer_var)?
}
}
};
@@ -890,7 +908,7 @@ fn deserialize_newtype_struct(
quote! {
#[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result<Self::Value, __E::Error>
fn visit_newtype_struct<__E>(self, #deserializer_var: __E) -> _serde::__private::Result<Self::Value, __E::Error>
where
__E: _serde::Deserializer<#delife>,
{
@@ -950,23 +968,20 @@ fn deserialize_struct(
};
let expecting = cattrs.expecting().unwrap_or(&expecting);
let field_names_idents: Vec<_> = fields
let deserialized_fields: Vec<_> = fields
.iter()
.enumerate()
// Skip fields that shouldn't be deserialized or that were flattened,
// so they don't appear in the storage in their literal form
.filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
.map(|(i, field)| {
(
field.attrs.name().deserialize_name(),
field_i(i),
field.attrs.aliases(),
)
.map(|(i, field)| FieldWithAliases {
ident: field_i(i),
aliases: field.attrs.aliases(),
})
.collect();
let has_flatten = has_flatten(fields);
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs, has_flatten);
let field_visitor = deserialize_field_identifier(&deserialized_fields, cattrs, has_flatten);
// untagged struct variants do not get a visit_seq method. The same applies to
// structs that only have a map representation.
@@ -974,7 +989,7 @@ fn deserialize_struct(
StructForm::Untagged(..) => None,
_ if has_flatten => None,
_ => {
let mut_seq = if field_names_idents.is_empty() {
let mut_seq = if deserialized_fields.is_empty() {
quote!(_)
} else {
quote!(mut __seq)
@@ -1022,9 +1037,7 @@ fn deserialize_struct(
let fields_stmt = if has_flatten {
None
} else {
let field_names = field_names_idents
.iter()
.flat_map(|&(_, _, aliases)| aliases);
let field_names = deserialized_fields.iter().flat_map(|field| field.aliases);
Some(quote! {
#[doc(hidden)]
@@ -1117,31 +1130,26 @@ fn deserialize_struct_in_place(
let expecting = format!("struct {}", params.type_name());
let expecting = cattrs.expecting().unwrap_or(&expecting);
let field_names_idents: Vec<_> = fields
let deserialized_fields: Vec<_> = fields
.iter()
.enumerate()
.filter(|&(_, field)| !field.attrs.skip_deserializing())
.map(|(i, field)| {
(
field.attrs.name().deserialize_name(),
field_i(i),
field.attrs.aliases(),
)
.map(|(i, field)| FieldWithAliases {
ident: field_i(i),
aliases: field.attrs.aliases(),
})
.collect();
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs, false);
let field_visitor = deserialize_field_identifier(&deserialized_fields, cattrs, false);
let mut_seq = if field_names_idents.is_empty() {
let mut_seq = if deserialized_fields.is_empty() {
quote!(_)
} else {
quote!(mut __seq)
};
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting));
let visit_map = Stmts(deserialize_map_in_place(params, fields, cattrs));
let field_names = field_names_idents
.iter()
.flat_map(|&(_, _, aliases)| aliases);
let field_names = deserialized_fields.iter().flat_map(|field| field.aliases);
let type_name = cattrs.name().deserialize_name();
let in_place_impl_generics = de_impl_generics.in_place();
@@ -1225,39 +1233,38 @@ fn deserialize_homogeneous_enum(
}
fn prepare_enum_variant_enum(variants: &[Variant]) -> (TokenStream, Stmts) {
let mut deserialized_variants = variants
let deserialized_variants = variants
.iter()
.enumerate()
.filter(|&(_, variant)| !variant.attrs.skip_deserializing());
let variant_names_idents: Vec<_> = deserialized_variants
.clone()
.map(|(i, variant)| {
(
variant.attrs.name().deserialize_name(),
field_i(i),
variant.attrs.aliases(),
)
})
.collect();
.filter(|&(_i, variant)| !variant.attrs.skip_deserializing());
let fallthrough = deserialized_variants
.position(|(_, variant)| variant.attrs.other())
.map(|other_idx| {
let ignore_variant = variant_names_idents[other_idx].1.clone();
.clone()
.find(|(_i, variant)| variant.attrs.other())
.map(|(i, _variant)| {
let ignore_variant = field_i(i);
quote!(_serde::__private::Ok(__Field::#ignore_variant))
});
let variants_stmt = {
let variant_names = variant_names_idents.iter().map(|(name, _, _)| name);
let variant_names = deserialized_variants
.clone()
.flat_map(|(_i, variant)| variant.attrs.aliases());
quote! {
#[doc(hidden)]
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
}
};
let deserialized_variants: Vec<_> = deserialized_variants
.map(|(i, variant)| FieldWithAliases {
ident: field_i(i),
aliases: variant.attrs.aliases(),
})
.collect();
let variant_visitor = Stmts(deserialize_generated_identifier(
&variant_names_idents,
&deserialized_variants,
false, // variant identifiers do not depend on the presence of flatten fields
true,
None,
@@ -1994,19 +2001,27 @@ fn deserialize_untagged_newtype_variant(
}
}
struct FieldWithAliases<'a> {
ident: Ident,
aliases: &'a BTreeSet<Name>,
}
fn deserialize_generated_identifier(
fields: &[(&str, Ident, &BTreeSet<String>)],
deserialized_fields: &[FieldWithAliases],
has_flatten: bool,
is_variant: bool,
ignore_variant: Option<TokenStream>,
fallthrough: Option<TokenStream>,
) -> Fragment {
let this_value = quote!(__Field);
let field_idents: &Vec<_> = &fields.iter().map(|(_, ident, _)| ident).collect();
let field_idents: &Vec<_> = &deserialized_fields
.iter()
.map(|field| &field.ident)
.collect();
let visitor_impl = Stmts(deserialize_identifier(
&this_value,
fields,
deserialized_fields,
is_variant,
fallthrough,
None,
@@ -2052,7 +2067,7 @@ fn deserialize_generated_identifier(
/// Generates enum and its `Deserialize` implementation that represents each
/// non-skipped field of the struct
fn deserialize_field_identifier(
fields: &[(&str, Ident, &BTreeSet<String>)],
deserialized_fields: &[FieldWithAliases],
cattrs: &attr::Container,
has_flatten: bool,
) -> Stmts {
@@ -2069,7 +2084,7 @@ fn deserialize_field_identifier(
};
Stmts(deserialize_generated_identifier(
fields,
deserialized_fields,
has_flatten,
false,
ignore_variant,
@@ -2127,18 +2142,15 @@ fn deserialize_custom_identifier(
(variants, None, None)
};
let names_idents: Vec<_> = ordinary
let idents_aliases: Vec<_> = ordinary
.iter()
.map(|variant| {
(
variant.attrs.name().deserialize_name(),
variant.ident.clone(),
variant.attrs.aliases(),
)
.map(|variant| FieldWithAliases {
ident: variant.ident.clone(),
aliases: variant.attrs.aliases(),
})
.collect();
let names = names_idents.iter().flat_map(|&(_, _, aliases)| aliases);
let names = idents_aliases.iter().flat_map(|variant| variant.aliases);
let names_const = if fallthrough.is_some() {
None
@@ -2161,7 +2173,7 @@ fn deserialize_custom_identifier(
let delife = params.borrowed.de_lifetime();
let visitor_impl = Stmts(deserialize_identifier(
&this_value,
&names_idents,
&idents_aliases,
is_variant,
fallthrough,
fallthrough_borrowed,
@@ -2194,23 +2206,35 @@ fn deserialize_custom_identifier(
fn deserialize_identifier(
this_value: &TokenStream,
fields: &[(&str, Ident, &BTreeSet<String>)],
deserialized_fields: &[FieldWithAliases],
is_variant: bool,
fallthrough: Option<TokenStream>,
fallthrough_borrowed: Option<TokenStream>,
collect_other_fields: bool,
expecting: Option<&str>,
) -> Fragment {
let str_mapping = fields.iter().map(|(_, ident, aliases)| {
let str_mapping = deserialized_fields.iter().map(|field| {
let ident = &field.ident;
let aliases = field.aliases;
// `aliases` also contains a main name
quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
quote! {
#(
#aliases => _serde::__private::Ok(#this_value::#ident),
)*
}
});
let bytes_mapping = fields.iter().map(|(_, ident, aliases)| {
let bytes_mapping = deserialized_fields.iter().map(|field| {
let ident = &field.ident;
// `aliases` also contains a main name
let aliases = aliases
let aliases = field
.aliases
.iter()
.map(|alias| Literal::byte_string(alias.as_bytes()));
quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
.map(|alias| Literal::byte_string(alias.value.as_bytes()));
quote! {
#(
#aliases => _serde::__private::Ok(#this_value::#ident),
)*
}
});
let expecting = expecting.unwrap_or(if is_variant {
@@ -2360,8 +2384,9 @@ fn deserialize_identifier(
}
}
} else {
let u64_mapping = fields.iter().enumerate().map(|(i, (_, ident, _))| {
let u64_mapping = deserialized_fields.iter().enumerate().map(|(i, field)| {
let i = i as u64;
let ident = &field.ident;
quote!(#i => _serde::__private::Ok(#this_value::#ident))
});
@@ -2370,7 +2395,11 @@ fn deserialize_identifier(
fallthrough
} else {
let index_expecting = if is_variant { "variant" } else { "field" };
let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
let fallthrough_msg = format!(
"{} index 0 <= i < {}",
index_expecting,
deserialized_fields.len(),
);
u64_fallthrough_arm_tokens = quote! {
_serde::__private::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
@@ -2403,7 +2432,7 @@ fn deserialize_identifier(
__E: _serde::de::Error,
{
match __value {
#(#str_mapping,)*
#(#str_mapping)*
_ => {
#value_as_borrowed_str_content
#fallthrough_borrowed_arm
@@ -2416,7 +2445,7 @@ fn deserialize_identifier(
__E: _serde::de::Error,
{
match __value {
#(#bytes_mapping,)*
#(#bytes_mapping)*
_ => {
#bytes_to_str
#value_as_borrowed_bytes_content
@@ -2441,7 +2470,7 @@ fn deserialize_identifier(
__E: _serde::de::Error,
{
match __value {
#(#str_mapping,)*
#(#str_mapping)*
_ => {
#value_as_str_content
#fallthrough_arm
@@ -2454,7 +2483,7 @@ fn deserialize_identifier(
__E: _serde::de::Error,
{
match __value {
#(#bytes_mapping,)*
#(#bytes_mapping)*
_ => {
#bytes_to_str
#value_as_bytes_content
@@ -2647,7 +2676,11 @@ fn deserialize_map(
attr::Default::Default => Some(quote!(
let __default: Self::Value = _serde::__private::Default::default();
)),
attr::Default::Path(path) => Some(quote!(
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
let __default: Self::Value = #path();
)),
attr::Default::None => {
@@ -2817,7 +2850,11 @@ fn deserialize_map_in_place(
attr::Default::Default => Some(quote!(
let __default: #this_type #ty_generics = _serde::__private::Default::default();
)),
attr::Default::Path(path) => Some(quote!(
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
let __default: #this_type #ty_generics = #path();
)),
attr::Default::None => {
@@ -2855,7 +2892,15 @@ fn wrap_deserialize_with(
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
split_with_de_lifetime(params);
let delife = params.borrowed.de_lifetime();
let deserializer_var = quote!(__deserializer);
// If #deserialize_with returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(with = "...")]
// ^^^^^
let value = quote_spanned! {deserialize_with.span()=>
#deserialize_with(#deserializer_var)?
};
let wrapper = quote! {
#[doc(hidden)]
struct __DeserializeWith #de_impl_generics #where_clause {
@@ -2865,12 +2910,12 @@ fn wrap_deserialize_with(
}
impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause {
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
fn deserialize<__D>(#deserializer_var: __D) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<#delife>,
{
_serde::__private::Ok(__DeserializeWith {
value: #deserialize_with(__deserializer)?,
value: #value,
phantom: _serde::__private::PhantomData,
lifetime: _serde::__private::PhantomData,
})
@@ -2961,7 +3006,11 @@ fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
return quote_expr!(#func());
}
attr::Default::Path(path) => {
return quote_expr!(#path());
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
return Fragment::Expr(quote_spanned!(path.span()=> #path()));
}
attr::Default::None => { /* below */ }
}
@@ -3004,6 +3053,10 @@ fn expr_is_missing_seq(
return quote_spanned!(span=> #assign_to _serde::__private::Default::default());
}
attr::Default::Path(path) => {
// If #path returns wrong type, error will be reported here (^^^^^).
// We attach span of the path to the function so it will be reported
// on the #[serde(default = "...")]
// ^^^^^
return quote_spanned!(path.span()=> #assign_to #path());
}
attr::Default::None => { /* below */ }
+53 -88
View File
@@ -1,3 +1,4 @@
use crate::internals::name::{MultiName, Name};
use crate::internals::symbol::*;
use crate::internals::{ungroup, Ctxt};
use proc_macro2::{Spacing, Span, TokenStream, TokenTree};
@@ -8,6 +9,7 @@ use std::iter::FromIterator;
use syn::meta::ParseNestedMeta;
use syn::parse::ParseStream;
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{parse_quote, token, Ident, Lifetime, Token};
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
@@ -20,7 +22,7 @@ use syn::{parse_quote, token, Ident, Lifetime, Token};
pub use crate::internals::case::RenameRule;
struct Attr<'c, T> {
pub(crate) struct Attr<'c, T> {
cx: &'c Ctxt,
name: Symbol,
tokens: TokenStream,
@@ -61,7 +63,7 @@ impl<'c, T> Attr<'c, T> {
}
}
fn get(self) -> Option<T> {
pub(crate) fn get(self) -> Option<T> {
self.value
}
@@ -89,7 +91,7 @@ impl<'c> BoolAttr<'c> {
}
}
struct VecAttr<'c, T> {
pub(crate) struct VecAttr<'c, T> {
cx: &'c Ctxt,
name: Symbol,
first_dup_tokens: TokenStream,
@@ -124,63 +126,13 @@ impl<'c, T> VecAttr<'c, T> {
}
}
fn get(self) -> Vec<T> {
pub(crate) fn get(self) -> Vec<T> {
self.values
}
}
pub struct Name {
serialize: String,
serialize_renamed: bool,
deserialize: String,
deserialize_renamed: bool,
deserialize_aliases: BTreeSet<String>,
}
fn unraw(ident: &Ident) -> String {
ident.to_string().trim_start_matches("r#").to_owned()
}
impl Name {
fn from_attrs(
source_name: String,
ser_name: Attr<String>,
de_name: Attr<String>,
de_aliases: Option<VecAttr<String>>,
) -> Name {
let mut alias_set = BTreeSet::new();
if let Some(de_aliases) = de_aliases {
for alias_name in de_aliases.get() {
alias_set.insert(alias_name);
}
}
let ser_name = ser_name.get();
let ser_renamed = ser_name.is_some();
let de_name = de_name.get();
let de_renamed = de_name.is_some();
Name {
serialize: ser_name.unwrap_or_else(|| source_name.clone()),
serialize_renamed: ser_renamed,
deserialize: de_name.unwrap_or(source_name),
deserialize_renamed: de_renamed,
deserialize_aliases: alias_set,
}
}
/// Return the container name for the container when serializing.
pub fn serialize_name(&self) -> &str {
&self.serialize
}
/// Return the container name for the container when deserializing.
pub fn deserialize_name(&self) -> &str {
&self.deserialize
}
fn deserialize_aliases(&self) -> &BTreeSet<String> {
&self.deserialize_aliases
}
fn unraw(ident: &Ident) -> Ident {
Ident::new(ident.to_string().trim_start_matches("r#"), ident.span())
}
#[derive(Copy, Clone)]
@@ -202,7 +154,7 @@ impl RenameAllRules {
/// Represents struct or enum attribute information.
pub struct Container {
name: Name,
name: MultiName,
transparent: bool,
deny_unknown_fields: bool,
default: Default,
@@ -326,8 +278,8 @@ impl Container {
// #[serde(rename = "foo")]
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
let (ser, de) = get_renames(cx, RENAME, &meta)?;
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
de_name.set_opt(&meta.path, de.as_ref().map(syn::LitStr::value));
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
de_name.set_opt(&meta.path, de.as_ref().map(Name::from));
} else if meta.path == RENAME_ALL {
// #[serde(rename_all = "foo")]
// #[serde(rename_all(serialize = "foo", deserialize = "bar"))]
@@ -566,7 +518,7 @@ impl Container {
}
Container {
name: Name::from_attrs(unraw(&item.ident), ser_name, de_name, None),
name: MultiName::from_attrs(Name::from(&unraw(&item.ident)), ser_name, de_name, None),
transparent: transparent.get(),
deny_unknown_fields: deny_unknown_fields.get(),
default: default.get().unwrap_or(Default::None),
@@ -593,7 +545,7 @@ impl Container {
}
}
pub fn name(&self) -> &Name {
pub fn name(&self) -> &MultiName {
&self.name
}
@@ -780,7 +732,7 @@ fn decide_identifier(
/// Represents variant attribute information
pub struct Variant {
name: Name,
name: MultiName,
rename_all_rules: RenameAllRules,
ser_bound: Option<Vec<syn::WherePredicate>>,
de_bound: Option<Vec<syn::WherePredicate>>,
@@ -831,15 +783,15 @@ impl Variant {
// #[serde(rename = "foo")]
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
let (ser, de) = get_multiple_renames(cx, &meta)?;
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
for de_value in de {
de_name.set_if_none(de_value.value());
de_aliases.insert(&meta.path, de_value.value());
de_name.set_if_none(Name::from(&de_value));
de_aliases.insert(&meta.path, Name::from(&de_value));
}
} else if meta.path == ALIAS {
// #[serde(alias = "foo")]
if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
de_aliases.insert(&meta.path, s.value());
de_aliases.insert(&meta.path, Name::from(&s));
}
} else if meta.path == RENAME_ALL {
// #[serde(rename_all = "foo")]
@@ -888,13 +840,13 @@ impl Variant {
ser_path
.path
.segments
.push(Ident::new("serialize", Span::call_site()).into());
.push(Ident::new("serialize", ser_path.span()).into());
serialize_with.set(&meta.path, ser_path);
let mut de_path = path;
de_path
.path
.segments
.push(Ident::new("deserialize", Span::call_site()).into());
.push(Ident::new("deserialize", de_path.span()).into());
deserialize_with.set(&meta.path, de_path);
}
} else if meta.path == SERIALIZE_WITH {
@@ -946,7 +898,12 @@ impl Variant {
}
Variant {
name: Name::from_attrs(unraw(&variant.ident), ser_name, de_name, Some(de_aliases)),
name: MultiName::from_attrs(
Name::from(&unraw(&variant.ident)),
ser_name,
de_name,
Some(de_aliases),
),
rename_all_rules: RenameAllRules {
serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
@@ -963,20 +920,23 @@ impl Variant {
}
}
pub fn name(&self) -> &Name {
pub fn name(&self) -> &MultiName {
&self.name
}
pub fn aliases(&self) -> &BTreeSet<String> {
pub fn aliases(&self) -> &BTreeSet<Name> {
self.name.deserialize_aliases()
}
pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
if !self.name.serialize_renamed {
self.name.serialize = rules.serialize.apply_to_variant(&self.name.serialize);
self.name.serialize.value =
rules.serialize.apply_to_variant(&self.name.serialize.value);
}
if !self.name.deserialize_renamed {
self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
self.name.deserialize.value = rules
.deserialize
.apply_to_variant(&self.name.deserialize.value);
}
self.name
.deserialize_aliases
@@ -1022,7 +982,7 @@ impl Variant {
/// Represents field attribute information
pub struct Field {
name: Name,
name: MultiName,
skip_serializing: bool,
skip_deserializing: bool,
skip_serializing_if: Option<syn::ExprPath>,
@@ -1081,8 +1041,11 @@ impl Field {
let mut flatten = BoolAttr::none(cx, FLATTEN);
let ident = match &field.ident {
Some(ident) => unraw(ident),
None => index.to_string(),
Some(ident) => Name::from(&unraw(ident)),
None => Name {
value: index.to_string(),
span: Span::call_site(),
},
};
if let Some(borrow_attribute) = attrs.and_then(|variant| variant.borrow.as_ref()) {
@@ -1118,15 +1081,15 @@ impl Field {
// #[serde(rename = "foo")]
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
let (ser, de) = get_multiple_renames(cx, &meta)?;
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
for de_value in de {
de_name.set_if_none(de_value.value());
de_aliases.insert(&meta.path, de_value.value());
de_name.set_if_none(Name::from(&de_value));
de_aliases.insert(&meta.path, Name::from(&de_value));
}
} else if meta.path == ALIAS {
// #[serde(alias = "foo")]
if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
de_aliases.insert(&meta.path, s.value());
de_aliases.insert(&meta.path, Name::from(&s));
}
} else if meta.path == DEFAULT {
if meta.input.peek(Token![=]) {
@@ -1170,13 +1133,13 @@ impl Field {
ser_path
.path
.segments
.push(Ident::new("serialize", Span::call_site()).into());
.push(Ident::new("serialize", ser_path.span()).into());
serialize_with.set(&meta.path, ser_path);
let mut de_path = path;
de_path
.path
.segments
.push(Ident::new("deserialize", Span::call_site()).into());
.push(Ident::new("deserialize", de_path.span()).into());
deserialize_with.set(&meta.path, de_path);
}
} else if meta.path == BOUND {
@@ -1289,7 +1252,7 @@ impl Field {
}
Field {
name: Name::from_attrs(ident, ser_name, de_name, Some(de_aliases)),
name: MultiName::from_attrs(ident, ser_name, de_name, Some(de_aliases)),
skip_serializing: skip_serializing.get(),
skip_deserializing: skip_deserializing.get(),
skip_serializing_if: skip_serializing_if.get(),
@@ -1305,20 +1268,22 @@ impl Field {
}
}
pub fn name(&self) -> &Name {
pub fn name(&self) -> &MultiName {
&self.name
}
pub fn aliases(&self) -> &BTreeSet<String> {
pub fn aliases(&self) -> &BTreeSet<Name> {
self.name.deserialize_aliases()
}
pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
if !self.name.serialize_renamed {
self.name.serialize = rules.serialize.apply_to_field(&self.name.serialize);
self.name.serialize.value = rules.serialize.apply_to_field(&self.name.serialize.value);
}
if !self.name.deserialize_renamed {
self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize);
self.name.deserialize.value = rules
.deserialize
.apply_to_field(&self.name.deserialize.value);
}
self.name
.deserialize_aliases
@@ -1768,7 +1733,7 @@ fn is_primitive_path(path: &syn::Path, primitive: &str) -> bool {
// attribute on the field so there must be at least one borrowable lifetime.
fn borrowable_lifetimes(
cx: &Ctxt,
name: &str,
name: &Name,
field: &syn::Field,
) -> Result<BTreeSet<syn::Lifetime>, ()> {
let mut lifetimes = BTreeSet::new();
+2 -2
View File
@@ -329,13 +329,13 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
let name = field.attrs.name();
let ser_name = name.serialize_name();
if check_ser && ser_name == tag {
if check_ser && ser_name.value == tag {
diagnose_conflict();
return;
}
for de_name in field.attrs.aliases() {
if check_de && de_name == tag {
if check_de && de_name.value == tag {
diagnose_conflict();
return;
}
+1
View File
@@ -1,5 +1,6 @@
pub mod ast;
pub mod attr;
pub mod name;
mod case;
mod check;
+113
View File
@@ -0,0 +1,113 @@
use crate::internals::attr::{Attr, VecAttr};
use proc_macro2::{Ident, Span, TokenStream};
use quote::ToTokens;
use std::cmp::Ordering;
use std::collections::BTreeSet;
use std::fmt::{self, Display};
use syn::LitStr;
pub struct MultiName {
pub(crate) serialize: Name,
pub(crate) serialize_renamed: bool,
pub(crate) deserialize: Name,
pub(crate) deserialize_renamed: bool,
pub(crate) deserialize_aliases: BTreeSet<Name>,
}
impl MultiName {
pub(crate) fn from_attrs(
source_name: Name,
ser_name: Attr<Name>,
de_name: Attr<Name>,
de_aliases: Option<VecAttr<Name>>,
) -> Self {
let mut alias_set = BTreeSet::new();
if let Some(de_aliases) = de_aliases {
for alias_name in de_aliases.get() {
alias_set.insert(alias_name);
}
}
let ser_name = ser_name.get();
let ser_renamed = ser_name.is_some();
let de_name = de_name.get();
let de_renamed = de_name.is_some();
MultiName {
serialize: ser_name.unwrap_or_else(|| source_name.clone()),
serialize_renamed: ser_renamed,
deserialize: de_name.unwrap_or(source_name),
deserialize_renamed: de_renamed,
deserialize_aliases: alias_set,
}
}
/// Return the container name for the container when serializing.
pub fn serialize_name(&self) -> &Name {
&self.serialize
}
/// Return the container name for the container when deserializing.
pub fn deserialize_name(&self) -> &Name {
&self.deserialize
}
pub(crate) fn deserialize_aliases(&self) -> &BTreeSet<Name> {
&self.deserialize_aliases
}
}
#[derive(Clone)]
pub struct Name {
pub value: String,
pub span: Span,
}
impl ToTokens for Name {
fn to_tokens(&self, tokens: &mut TokenStream) {
LitStr::new(&self.value, self.span).to_tokens(tokens);
}
}
impl Ord for Name {
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(&self.value, &other.value)
}
}
impl PartialOrd for Name {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(Ord::cmp(self, other))
}
}
impl Eq for Name {}
impl PartialEq for Name {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl From<&Ident> for Name {
fn from(ident: &Ident) -> Self {
Name {
value: ident.to_string(),
span: ident.span(),
}
}
}
impl From<&LitStr> for Name {
fn from(lit: &LitStr) -> Self {
Name {
value: lit.value(),
span: lit.span(),
}
}
}
impl Display for Name {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.value, formatter)
}
}
+3 -1
View File
@@ -209,7 +209,9 @@ impl ReplaceReceiver<'_> {
match bound {
#![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
TypeParamBound::Trait(bound) => self.visit_path_mut(&mut bound.path),
TypeParamBound::Lifetime(_) | TypeParamBound::Verbatim(_) => {}
TypeParamBound::Lifetime(_)
| TypeParamBound::PreciseCapture(_)
| TypeParamBound::Verbatim(_) => {}
_ => {}
}
}
+2 -2
View File
@@ -46,7 +46,7 @@ impl PartialEq<Symbol> for Ident {
}
}
impl<'a> PartialEq<Symbol> for &'a Ident {
impl PartialEq<Symbol> for &Ident {
fn eq(&self, word: &Symbol) -> bool {
*self == word.0
}
@@ -58,7 +58,7 @@ impl PartialEq<Symbol> for Path {
}
}
impl<'a> PartialEq<Symbol> for &'a Path {
impl PartialEq<Symbol> for &Path {
fn eq(&self, word: &Symbol) -> bool {
self.is_ident(word.0)
}
+3 -1
View File
@@ -13,7 +13,7 @@
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.209")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.215")]
#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
// Ignored clippy lints
#![allow(
@@ -27,6 +27,7 @@
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6797
clippy::manual_map,
clippy::match_like_matches_macro,
clippy::needless_lifetimes,
clippy::needless_pass_by_value,
clippy::too_many_arguments,
clippy::trivially_copy_pass_by_ref,
@@ -55,6 +56,7 @@
clippy::single_match_else,
clippy::struct_excessive_bools,
clippy::too_many_lines,
clippy::uninlined_format_args,
clippy::unseparated_literal_suffix,
clippy::unused_self,
clippy::use_self,
+20 -8
View File
@@ -1,5 +1,6 @@
use crate::fragment::{Fragment, Match, Stmts};
use crate::internals::ast::{Container, Data, Field, Style, Variant};
use crate::internals::name::Name;
use crate::internals::{attr, replace_receiver, Ctxt, Derive};
use crate::{bound, dummy, pretend, this};
use proc_macro2::{Span, TokenStream};
@@ -798,9 +799,9 @@ fn serialize_untagged_variant(
enum TupleVariant<'a> {
ExternallyTagged {
type_name: &'a str,
type_name: &'a Name,
variant_index: u32,
variant_name: &'a str,
variant_name: &'a Name,
},
Untagged,
}
@@ -867,11 +868,11 @@ fn serialize_tuple_variant(
enum StructVariant<'a> {
ExternallyTagged {
variant_index: u32,
variant_name: &'a str,
variant_name: &'a Name,
},
InternallyTagged {
tag: &'a str,
variant_name: &'a str,
variant_name: &'a Name,
},
Untagged,
}
@@ -880,7 +881,7 @@ fn serialize_struct_variant(
context: StructVariant,
params: &Parameters,
fields: &[Field],
name: &str,
name: &Name,
) -> Fragment {
if fields.iter().any(|field| field.attrs.flatten()) {
return serialize_struct_variant_with_flatten(context, params, fields, name);
@@ -964,7 +965,7 @@ fn serialize_struct_variant_with_flatten(
context: StructVariant,
params: &Parameters,
fields: &[Field],
name: &str,
name: &Name,
) -> Fragment {
let struct_trait = StructTrait::SerializeMap;
let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);
@@ -1220,6 +1221,17 @@ fn wrap_serialize_with(
})
});
let self_var = quote!(self);
let serializer_var = quote!(__s);
// If #serialize_with returns wrong type, error will be reported on here.
// We attach span of the path to this piece so error will be reported
// on the #[serde(with = "...")]
// ^^^^^
let wrapper_serialize = quote_spanned! {serialize_with.span()=>
#serialize_with(#(#self_var.values.#field_access, )* #serializer_var)
};
quote!({
#[doc(hidden)]
struct __SerializeWith #wrapper_impl_generics #where_clause {
@@ -1228,11 +1240,11 @@ fn wrap_serialize_with(
}
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
fn serialize<__S>(&self, __s: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
fn serialize<__S>(&#self_var, #serializer_var: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
where
__S: _serde::Serializer,
{
#serialize_with(#(self.values.#field_access, )* __s)
#wrapper_serialize
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ homepage = "https://serde.rs"
keywords = ["serde", "serialization"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/serde-rs/serde"
rust-version = "1.56"
rust-version = "1.61"
[lib]
path = "lib.rs"
+2
View File
@@ -9,6 +9,7 @@
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6797
clippy::manual_map,
clippy::missing_panics_doc,
clippy::needless_lifetimes,
clippy::redundant_field_names,
clippy::result_unit_err,
clippy::should_implement_trait,
@@ -35,6 +36,7 @@
clippy::single_match_else,
clippy::struct_excessive_bools,
clippy::too_many_lines,
clippy::uninlined_format_args,
clippy::unused_self,
clippy::wildcard_imports
)]
+12 -5
View File
@@ -1,4 +1,4 @@
use serde_derive::{Serialize, Deserialize};
use serde_derive::{Deserialize, Serialize};
use serde_test::{assert_tokens, Token};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
@@ -18,11 +18,15 @@ fn simple_variant() {
assert_tokens(
&Enum::Simple { a: 42 },
&[
Token::StructVariant { name: "Enum", variant: "Simple", len: 1 },
Token::StructVariant {
name: "Enum",
variant: "Simple",
len: 1,
},
Token::Str("a"),
Token::I32(42),
Token::StructVariantEnd,
]
],
);
}
@@ -31,11 +35,14 @@ fn flatten_variant() {
assert_tokens(
&Enum::Flatten { flatten: (), a: 42 },
&[
Token::NewtypeVariant { name: "Enum", variant: "Flatten" },
Token::NewtypeVariant {
name: "Enum",
variant: "Flatten",
},
Token::Map { len: None },
Token::Str("a"),
Token::I32(42),
Token::MapEnd,
]
],
);
}
+33
View File
@@ -0,0 +1,33 @@
#![allow(clippy::trivially_copy_pass_by_ref)]
use serde_derive::{Deserialize, Serialize};
macro_rules! declare_in_macro {
($with:literal) => {
#[derive(Serialize, Deserialize)]
pub struct S {
#[serde(with = $with)]
f: i32,
}
};
}
declare_in_macro!("with");
mod with {
use serde::{Deserializer, Serializer};
pub fn serialize<S>(_: &i32, _: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
unimplemented!()
}
pub fn deserialize<'de, D>(_: D) -> Result<i32, D::Error>
where
D: Deserializer<'de>,
{
unimplemented!()
}
}
+27
View File
@@ -0,0 +1,27 @@
#![allow(clippy::trivially_copy_pass_by_ref)]
use serde_derive::Deserialize;
macro_rules! declare_in_macro {
($with:literal) => {
#[derive(Deserialize)]
pub struct S(
#[serde(with = $with)]
#[allow(dead_code)]
i32,
);
};
}
declare_in_macro!("with");
mod with {
use serde::Deserializer;
pub fn deserialize<'de, D>(_: D) -> Result<i32, D::Error>
where
D: Deserializer<'de>,
{
unimplemented!()
}
}
+1 -1
View File
@@ -782,7 +782,7 @@ fn test_unknown_field_rename_enum() {
variant: "SailorMoon",
len: 3,
}],
"unknown variant `SailorMoon`, expected `sailor_moon`",
"unknown variant `SailorMoon`, expected `sailor_moon` or `usagi_tsukino`",
);
assert_de_tokens_error::<AliasEnum>(
+1
View File
@@ -1,5 +1,6 @@
#![allow(
clippy::extra_unused_type_parameters,
clippy::needless_lifetimes,
clippy::type_repetition_in_bounds
)]
@@ -0,0 +1,75 @@
#![allow(non_camel_case_types)]
use serde_derive::Deserialize;
#[derive(Deserialize)]
enum E {
S1 {
#[serde(alias = "a", alias = "b", alias = "c")]
a: (),
// Warning on "c" and "b"
#[serde(alias = "c")]
b: (),
#[serde(skip_deserializing)]
c: (),
},
S2 {
#[serde(alias = "b", alias = "c")]
a: (),
// Warning on "c"
#[serde(rename = "c")]
b: (),
},
#[serde(rename_all = "UPPERCASE")]
S3 {
#[serde(alias = "B", alias = "c")]
a: (),
// Warning on "b" because this collides with the "B" above after
// applying rename rules
b: (),
},
}
#[derive(Deserialize)]
enum E1 {
#[serde(alias = "a", alias = "b", alias = "c")]
a,
// Warning on "c" and "b"
#[serde(alias = "c")]
b,
#[serde(skip_deserializing)]
c,
}
#[derive(Deserialize)]
enum E2 {
#[serde(alias = "b", alias = "c")]
a,
// Warning on "c"
#[serde(rename = "c")]
b,
}
#[derive(Deserialize)]
#[serde(rename_all = "UPPERCASE")]
enum E3 {
#[serde(alias = "B", alias = "c")]
a,
// Warning on "b" because this collides with the "B" above after applying
// rename rules
b,
}
fn main() {
__FAIL__;
}
@@ -0,0 +1,79 @@
error[E0425]: cannot find value `__FAIL__` in this scope
--> tests/ui/conflict/alias-enum.rs:74:5
|
74 | __FAIL__;
| ^^^^^^^^ not found in this scope
warning: unreachable pattern
--> tests/ui/conflict/alias-enum.rs:13:9
|
8 | #[serde(alias = "a", alias = "b", alias = "c")]
| --- matches all the relevant values
...
13 | b: (),
| ^ no value can reach this
|
= note: `#[warn(unreachable_patterns)]` on by default
warning: unreachable pattern
--> tests/ui/conflict/alias-enum.rs:12:25
|
8 | #[serde(alias = "a", alias = "b", alias = "c")]
| --- matches all the relevant values
...
12 | #[serde(alias = "c")]
| ^^^ no value can reach this
warning: unreachable pattern
--> tests/ui/conflict/alias-enum.rs:24:26
|
20 | #[serde(alias = "b", alias = "c")]
| --- matches all the relevant values
...
24 | #[serde(rename = "c")]
| ^^^ no value can reach this
warning: unreachable pattern
--> tests/ui/conflict/alias-enum.rs:35:9
|
30 | #[serde(alias = "B", alias = "c")]
| --- matches all the relevant values
...
35 | b: (),
| ^ no value can reach this
warning: unreachable pattern
--> tests/ui/conflict/alias-enum.rs:46:5
|
41 | #[serde(alias = "a", alias = "b", alias = "c")]
| --- matches all the relevant values
...
46 | b,
| ^ no value can reach this
warning: unreachable pattern
--> tests/ui/conflict/alias-enum.rs:45:21
|
41 | #[serde(alias = "a", alias = "b", alias = "c")]
| --- matches all the relevant values
...
45 | #[serde(alias = "c")]
| ^^^ no value can reach this
warning: unreachable pattern
--> tests/ui/conflict/alias-enum.rs:58:22
|
54 | #[serde(alias = "b", alias = "c")]
| --- matches all the relevant values
...
58 | #[serde(rename = "c")]
| ^^^ no value can reach this
warning: unreachable pattern
--> tests/ui/conflict/alias-enum.rs:70:5
|
65 | #[serde(alias = "B", alias = "c")]
| --- matches all the relevant values
...
70 | b,
| ^ no value can reach this
+39
View File
@@ -0,0 +1,39 @@
use serde_derive::Deserialize;
#[derive(Deserialize)]
struct S1 {
#[serde(alias = "a", alias = "b", alias = "c")]
a: (),
// Warning on "c" and "b"
#[serde(alias = "c")]
b: (),
#[serde(skip_deserializing)]
c: (),
}
#[derive(Deserialize)]
struct S2 {
#[serde(alias = "b", alias = "c")]
a: (),
// Warning on "c"
#[serde(rename = "c")]
b: (),
}
#[derive(Deserialize)]
#[serde(rename_all = "UPPERCASE")]
struct S3 {
#[serde(alias = "B", alias = "c")]
a: (),
// Warning on "b" because this collides with the "B" above after applying
// rename rules
b: (),
}
fn main() {
__FAIL__;
}
+43
View File
@@ -0,0 +1,43 @@
error[E0425]: cannot find value `__FAIL__` in this scope
--> tests/ui/conflict/alias.rs:38:5
|
38 | __FAIL__;
| ^^^^^^^^ not found in this scope
warning: unreachable pattern
--> tests/ui/conflict/alias.rs:10:5
|
5 | #[serde(alias = "a", alias = "b", alias = "c")]
| --- matches all the relevant values
...
10 | b: (),
| ^ no value can reach this
|
= note: `#[warn(unreachable_patterns)]` on by default
warning: unreachable pattern
--> tests/ui/conflict/alias.rs:9:21
|
5 | #[serde(alias = "a", alias = "b", alias = "c")]
| --- matches all the relevant values
...
9 | #[serde(alias = "c")]
| ^^^ no value can reach this
warning: unreachable pattern
--> tests/ui/conflict/alias.rs:22:22
|
18 | #[serde(alias = "b", alias = "c")]
| --- matches all the relevant values
...
22 | #[serde(rename = "c")]
| ^^^ no value can reach this
warning: unreachable pattern
--> tests/ui/conflict/alias.rs:34:5
|
29 | #[serde(alias = "B", alias = "c")]
| --- matches all the relevant values
...
34 | b: (),
| ^ no value can reach this
@@ -0,0 +1,20 @@
// Tests that type error points to the path in attribute
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(tag = "tag", content = "content")]
enum Enum {
// Newtype variants do not use the provided path, so it is forbidden here
// Newtype(#[serde(default = "main")] u8),
Tuple(u8, #[serde(default = "main")] i8),
Struct {
#[serde(default = "main")]
f1: u8,
f2: u8,
#[serde(default = "main")]
f3: i8,
},
}
fn main() {}
@@ -0,0 +1,35 @@
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_adjacently_tagged.rs:10:33
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
| `match` arms have incompatible types
...
10 | Tuple(u8, #[serde(default = "main")] i8),
| ^^^^^^ expected `i8`, found `()`
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_adjacently_tagged.rs:12:27
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `u8`
| `match` arms have incompatible types
...
12 | #[serde(default = "main")]
| ^^^^^^ expected `u8`, found `()`
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_adjacently_tagged.rs:15:27
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
| `match` arms have incompatible types
...
15 | #[serde(default = "main")]
| ^^^^^^ expected `i8`, found `()`
@@ -0,0 +1,19 @@
// Tests that type error points to the path in attribute
use serde_derive::Deserialize;
#[derive(Deserialize)]
enum Enum {
// Newtype variants do not use the provided path, so it is forbidden here
// Newtype(#[serde(default = "main")] u8),
Tuple(u8, #[serde(default = "main")] i8),
Struct {
#[serde(default = "main")]
f1: u8,
f2: u8,
#[serde(default = "main")]
f3: i8,
},
}
fn main() {}
@@ -0,0 +1,35 @@
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_externally_tagged.rs:9:33
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
| `match` arms have incompatible types
...
9 | Tuple(u8, #[serde(default = "main")] i8),
| ^^^^^^ expected `i8`, found `()`
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_externally_tagged.rs:11:27
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `u8`
| `match` arms have incompatible types
...
11 | #[serde(default = "main")]
| ^^^^^^ expected `u8`, found `()`
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_externally_tagged.rs:14:27
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
| `match` arms have incompatible types
...
14 | #[serde(default = "main")]
| ^^^^^^ expected `i8`, found `()`
@@ -0,0 +1,20 @@
// Tests that type error points to the path in attribute
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(tag = "tag")]
enum Enum {
// Newtype variants do not use the provided path, so it is forbidden here
// Newtype(#[serde(default = "main")] u8),
// Tuple variants are not supported in internally tagged enums
Struct {
#[serde(default = "main")]
f1: u8,
f2: u8,
#[serde(default = "main")]
f3: i8,
},
}
fn main() {}
@@ -0,0 +1,23 @@
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_internally_tagged.rs:12:27
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `u8`
| `match` arms have incompatible types
...
12 | #[serde(default = "main")]
| ^^^^^^ expected `u8`, found `()`
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_internally_tagged.rs:15:27
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
| `match` arms have incompatible types
...
15 | #[serde(default = "main")]
| ^^^^^^ expected `i8`, found `()`
@@ -0,0 +1,20 @@
// Tests that type error points to the path in attribute
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(untagged)]
enum Enum {
// Newtype variants do not use the provided path, so it is forbidden here
// Newtype(#[serde(default = "main")] u8),
Tuple(u8, #[serde(default = "main")] i8),
Struct {
#[serde(default = "main")]
f1: u8,
f2: u8,
#[serde(default = "main")]
f3: i8,
},
}
fn main() {}
@@ -0,0 +1,35 @@
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_untagged.rs:10:33
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
| `match` arms have incompatible types
...
10 | Tuple(u8, #[serde(default = "main")] i8),
| ^^^^^^ expected `i8`, found `()`
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_untagged.rs:12:27
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `u8`
| `match` arms have incompatible types
...
12 | #[serde(default = "main")]
| ^^^^^^ expected `u8`, found `()`
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_untagged.rs:15:27
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
| `match` arms have incompatible types
...
15 | #[serde(default = "main")]
| ^^^^^^ expected `i8`, found `()`
@@ -0,0 +1,9 @@
// Tests that type error points to the path in attribute
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(default = "main")]
struct Newtype(#[serde(default = "main")] u8);
fn main() {}
@@ -0,0 +1,37 @@
error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_newtype.rs:6:19
|
6 | #[serde(default = "main")]
| ^^^^^^
| |
| expected `Newtype`, found `()`
| expected due to this
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_newtype.rs:7:34
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `u8`
| `match` arms have incompatible types
6 | #[serde(default = "main")]
7 | struct Newtype(#[serde(default = "main")] u8);
| ^^^^^^ expected `u8`, found `()`
error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_newtype.rs:6:19
|
6 | #[serde(default = "main")]
| ^^^^^^ expected `Newtype`, found `()`
7 | struct Newtype(#[serde(default = "main")] u8);
| ------- expected due to this
error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_newtype.rs:7:34
|
5 | #[derive(Deserialize)]
| ----------- expected due to the type of this binding
6 | #[serde(default = "main")]
7 | struct Newtype(#[serde(default = "main")] u8);
| ^^^^^^ expected `u8`, found `()`
@@ -0,0 +1,15 @@
// Tests that type error points to the path in attribute
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(default = "main")]
struct Struct {
#[serde(default = "main")]
f1: u8,
f2: u8,
#[serde(default = "main")]
f3: i8,
}
fn main() {}
@@ -0,0 +1,58 @@
error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_struct.rs:6:19
|
6 | #[serde(default = "main")]
| ^^^^^^
| |
| expected `Struct`, found `()`
| expected due to this
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_struct.rs:8:23
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `u8`
| `match` arms have incompatible types
...
8 | #[serde(default = "main")]
| ^^^^^^ expected `u8`, found `()`
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_struct.rs:11:23
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
| `match` arms have incompatible types
...
11 | #[serde(default = "main")]
| ^^^^^^ expected `i8`, found `()`
error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_struct.rs:6:19
|
6 | #[serde(default = "main")]
| ^^^^^^ expected `Struct`, found `()`
7 | struct Struct {
| ------ expected due to this
error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_struct.rs:8:23
|
5 | #[derive(Deserialize)]
| ----------- expected due to the type of this binding
...
8 | #[serde(default = "main")]
| ^^^^^^ expected `u8`, found `()`
error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_struct.rs:11:23
|
5 | #[derive(Deserialize)]
| ----------- expected due to the type of this binding
...
11 | #[serde(default = "main")]
| ^^^^^^ expected `i8`, found `()`
@@ -0,0 +1,9 @@
// Tests that type error points to the path in attribute
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(default = "main")]
struct Tuple(u8, #[serde(default = "main")] i8);
fn main() {}
@@ -0,0 +1,37 @@
error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_tuple.rs:6:19
|
6 | #[serde(default = "main")]
| ^^^^^^
| |
| expected `Tuple`, found `()`
| expected due to this
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_tuple.rs:7:36
|
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
| `match` arms have incompatible types
6 | #[serde(default = "main")]
7 | struct Tuple(u8, #[serde(default = "main")] i8);
| ^^^^^^ expected `i8`, found `()`
error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_tuple.rs:6:19
|
6 | #[serde(default = "main")]
| ^^^^^^ expected `Tuple`, found `()`
7 | struct Tuple(u8, #[serde(default = "main")] i8);
| ----- expected due to this
error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_tuple.rs:7:36
|
5 | #[derive(Deserialize)]
| ----------- expected due to the type of this binding
6 | #[serde(default = "main")]
7 | struct Tuple(u8, #[serde(default = "main")] i8);
| ^^^^^^ expected `i8`, found `()`
@@ -0,0 +1,9 @@
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(default)]
union Union {
f: u8,
}
fn main() {}
@@ -0,0 +1,14 @@
error: #[serde(default)] can only be used on structs
--> tests/ui/default-attribute/union.rs:4:9
|
4 | #[serde(default)]
| ^^^^^^^
error: Serde does not support derive for unions
--> tests/ui/default-attribute/union.rs:4:1
|
4 | / #[serde(default)]
5 | | union Union {
6 | | f: u8,
7 | | }
| |_^
@@ -0,0 +1,9 @@
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(default = "default_u")]
union Union {
f: u8,
}
fn main() {}
@@ -0,0 +1,14 @@
error: #[serde(default = "...")] can only be used on structs
--> tests/ui/default-attribute/union_path.rs:4:9
|
4 | #[serde(default = "default_u")]
| ^^^^^^^^^^^^^^^^^^^^^
error: Serde does not support derive for unions
--> tests/ui/default-attribute/union_path.rs:4:1
|
4 | / #[serde(default = "default_u")]
5 | | union Union {
6 | | f: u8,
7 | | }
| |_^
@@ -0,0 +1,7 @@
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(default)]
struct Unit;
fn main() {}
@@ -0,0 +1,7 @@
error: #[serde(default)] can only be used on structs that have fields
--> tests/ui/default-attribute/unit.rs:3:10
|
3 | #[derive(Deserialize)]
| ^^^^^^^^^^^
|
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -0,0 +1,7 @@
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(default = "default_u")]
struct Unit;
fn main() {}
@@ -0,0 +1,5 @@
error: #[serde(default = "...")] can only be used on structs that have fields
--> tests/ui/default-attribute/unit_path.rs:4:9
|
4 | #[serde(default = "default_u")]
| ^^^^^^^^^^^^^^^^^^^^^
@@ -0,0 +1,23 @@
use serde_derive::{Deserialize, Serialize};
mod w {
use serde::{Deserializer, Serializer};
pub fn deserialize<'de, D: Deserializer<'de>>(_: D) -> Result<(), D::Error> {
unimplemented!()
}
pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
unimplemented!()
}
}
#[derive(Serialize, Deserialize)]
struct W(#[serde(with = "w")] u8, u8);
#[derive(Serialize, Deserialize)]
struct S(#[serde(serialize_with = "w::serialize")] u8, u8);
#[derive(Serialize, Deserialize)]
struct D(#[serde(deserialize_with = "w::deserialize")] u8, u8);
fn main() {}
@@ -0,0 +1,101 @@
error[E0277]: the trait bound `&u8: Serializer` is not satisfied
--> tests/ui/with/incorrect_type.rs:14:10
|
14 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^ the trait `Serializer` is not implemented for `&u8`
15 | struct W(#[serde(with = "w")] u8, u8);
| --- required by a bound introduced by this call
|
= help: the following other types implement trait `Serializer`:
&mut Formatter<'a>
FlatMapSerializer<'a, M>
_::_serde::__private::ser::content::ContentSerializer<E>
note: required by a bound in `w::serialize`
--> tests/ui/with/incorrect_type.rs:9:28
|
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
| ^^^^^^^^^^ required by this bound in `serialize`
error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> tests/ui/with/incorrect_type.rs:15:25
|
14 | #[derive(Serialize, Deserialize)]
| --------- unexpected argument #2 of type `__S`
15 | struct W(#[serde(with = "w")] u8, u8);
| ^^^
|
note: function defined here
--> tests/ui/with/incorrect_type.rs:9:12
|
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
| ^^^^^^^^^ ----
error[E0277]: the trait bound `&u8: Serializer` is not satisfied
--> tests/ui/with/incorrect_type.rs:15:25
|
15 | struct W(#[serde(with = "w")] u8, u8);
| ^^^ the trait `Serializer` is not implemented for `&u8`
|
= help: the following other types implement trait `Serializer`:
&mut Formatter<'a>
FlatMapSerializer<'a, M>
_::_serde::__private::ser::content::ContentSerializer<E>
error[E0308]: `?` operator has incompatible types
--> tests/ui/with/incorrect_type.rs:15:25
|
15 | struct W(#[serde(with = "w")] u8, u8);
| ^^^ expected `u8`, found `()`
|
= note: `?` operator cannot convert from `()` to `u8`
error[E0277]: the trait bound `&u8: Serializer` is not satisfied
--> tests/ui/with/incorrect_type.rs:17:10
|
17 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^ the trait `Serializer` is not implemented for `&u8`
18 | struct S(#[serde(serialize_with = "w::serialize")] u8, u8);
| -------------- required by a bound introduced by this call
|
= help: the following other types implement trait `Serializer`:
&mut Formatter<'a>
FlatMapSerializer<'a, M>
_::_serde::__private::ser::content::ContentSerializer<E>
note: required by a bound in `w::serialize`
--> tests/ui/with/incorrect_type.rs:9:28
|
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
| ^^^^^^^^^^ required by this bound in `serialize`
error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> tests/ui/with/incorrect_type.rs:18:35
|
17 | #[derive(Serialize, Deserialize)]
| --------- unexpected argument #2 of type `__S`
18 | struct S(#[serde(serialize_with = "w::serialize")] u8, u8);
| ^^^^^^^^^^^^^^
|
note: function defined here
--> tests/ui/with/incorrect_type.rs:9:12
|
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
| ^^^^^^^^^ ----
error[E0277]: the trait bound `&u8: Serializer` is not satisfied
--> tests/ui/with/incorrect_type.rs:18:35
|
18 | struct S(#[serde(serialize_with = "w::serialize")] u8, u8);
| ^^^^^^^^^^^^^^ the trait `Serializer` is not implemented for `&u8`
|
= help: the following other types implement trait `Serializer`:
&mut Formatter<'a>
FlatMapSerializer<'a, M>
_::_serde::__private::ser::content::ContentSerializer<E>
error[E0308]: `?` operator has incompatible types
--> tests/ui/with/incorrect_type.rs:21:37
|
21 | struct D(#[serde(deserialize_with = "w::deserialize")] u8, u8);
| ^^^^^^^^^^^^^^^^ expected `u8`, found `()`
|
= note: `?` operator cannot convert from `()` to `u8`