Compare commits

...

5 Commits

Author SHA1 Message Date
David Tolnay e3058105f0 Release 1.0.158 2023-03-20 04:24:27 -07:00
David Tolnay dc200a6450 Reformat comments of non-public serde_derive internals
Fixes these being treated as "tests" by `cargo test` in serde_derive:

    running 3 tests
    test src/internals/check.rs - internals::check::check_remote_generic (line 23) ... FAILED
    test src/internals/check.rs - internals::check::check_remote_generic (line 29) ... FAILED
    test src/lib.rs - (line 3) ... ok

    failures:

    ---- src/internals/check.rs - internals::check::check_remote_generic (line 23) stdout ----
    error: unknown start of token: \u{2026}
     --> src/internals/check.rs:25:20
      |
    4 | struct Generic<T> {…}
      |                    ^

    error: cannot find attribute `serde` in this scope
     --> src/internals/check.rs:24:3
      |
    3 | #[serde(remote = "Generic")]
      |   ^^^^^
      |
      = note: `serde` is in scope, but it is a crate, not an attribute

    error[E0392]: parameter `T` is never used
     --> src/internals/check.rs:25:16
      |
    4 | struct Generic<T> {…}
      |                ^ unused parameter
      |
      = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
      = help: if you intended `T` to be a const parameter, use `const T: usize` instead

    ---- src/internals/check.rs - internals::check::check_remote_generic (line 29) stdout ----
    error: unknown start of token: \u{2026}
     --> src/internals/check.rs:31:21
      |
    4 | struct ConcreteDef {…}
      |                     ^

    error: cannot find attribute `serde` in this scope
     --> src/internals/check.rs:30:3
      |
    3 | #[serde(remote = "Generic<T>")]
      |   ^^^^^
      |
      = note: `serde` is in scope, but it is a crate, not an attribute
2023-03-20 04:23:46 -07:00
David Tolnay 2c0999a0b9 Merge pull request #2410 from serde-rs/attrvalue
Check for None-delimited group in attribute value
2023-03-20 04:23:33 -07:00
David Tolnay dd460f82a1 Check for None-delimited group in attribute value 2023-03-20 04:16:52 -07:00
David Tolnay c3d637f397 Add regression test for issue 2409 2023-03-20 03:59:43 -07:00
9 changed files with 70 additions and 55 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.157" # remember to update html_root_url and serde_derive dependency version = "1.0.158" # remember to update html_root_url and serde_derive dependency
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs" build = "build.rs"
categories = ["encoding", "no-std"] categories = ["encoding", "no-std"]
@@ -15,7 +15,7 @@ repository = "https://github.com/serde-rs/serde"
rust-version = "1.19" rust-version = "1.19"
[dependencies] [dependencies]
serde_derive = { version = "=1.0.157", optional = true, path = "../serde_derive" } serde_derive = { version = "=1.0.158", optional = true, path = "../serde_derive" }
[dev-dependencies] [dev-dependencies]
serde_derive = { version = "1.0", path = "../serde_derive" } serde_derive = { version = "1.0", path = "../serde_derive" }
+1 -1
View File
@@ -93,7 +93,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here. // Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.157")] #![doc(html_root_url = "https://docs.rs/serde/1.0.158")]
// Support using Serde without the standard library! // Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and // Unstable functionality only if the user asks for it. For tracking and
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.157" # remember to update html_root_url version = "1.0.158" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
categories = ["no-std"] categories = ["no-std"]
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -24,7 +24,7 @@ proc-macro = true
[dependencies] [dependencies]
proc-macro2 = "1.0" proc-macro2 = "1.0"
quote = "1.0" quote = "1.0"
syn = "2.0" syn = "2.0.3"
[dev-dependencies] [dev-dependencies]
serde = { version = "1.0", path = "../serde" } serde = { version = "1.0", path = "../serde" }
+20 -15
View File
@@ -1381,21 +1381,26 @@ fn get_lit_str2(
meta_item_name: Symbol, meta_item_name: Symbol,
meta: &ParseNestedMeta, meta: &ParseNestedMeta,
) -> syn::Result<Option<syn::LitStr>> { ) -> syn::Result<Option<syn::LitStr>> {
match meta.value()?.parse()? { let expr: syn::Expr = meta.value()?.parse()?;
syn::Expr::Lit(syn::ExprLit { let mut value = &expr;
lit: syn::Lit::Str(lit), while let syn::Expr::Group(e) = value {
.. value = &e.expr;
}) => Ok(Some(lit)), }
expr => { if let syn::Expr::Lit(syn::ExprLit {
cx.error_spanned_by( lit: syn::Lit::Str(lit),
expr, ..
format!( }) = value
"expected serde {} attribute to be a string: `{} = \"...\"`", {
attr_name, meta_item_name Ok(Some(lit.clone()))
), } else {
); cx.error_spanned_by(
Ok(None) expr,
} format!(
"expected serde {} attribute to be a string: `{} = \"...\"`",
attr_name, meta_item_name
),
);
Ok(None)
} }
} }
+31 -32
View File
@@ -3,8 +3,8 @@ use internals::attr::{Identifier, TagType};
use internals::{ungroup, Ctxt, Derive}; use internals::{ungroup, Ctxt, Derive};
use syn::{Member, Type}; use syn::{Member, Type};
/// Cross-cutting checks that require looking at more than a single attrs // Cross-cutting checks that require looking at more than a single attrs object.
/// object. Simpler checks should happen when parsing and building the attrs. // Simpler checks should happen when parsing and building the attrs.
pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) { pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
check_remote_generic(cx, cont); check_remote_generic(cx, cont);
check_getter(cx, cont); check_getter(cx, cont);
@@ -17,18 +17,18 @@ pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
check_from_and_try_from(cx, cont); check_from_and_try_from(cx, cont);
} }
/// Remote derive definition type must have either all of the generics of the // Remote derive definition type must have either all of the generics of the
/// remote type: // remote type:
/// //
/// #[serde(remote = "Generic")] // #[serde(remote = "Generic")]
/// struct Generic<T> {…} // struct Generic<T> {…}
/// //
/// or none of them, i.e. defining impls for one concrete instantiation of the // or none of them, i.e. defining impls for one concrete instantiation of the
/// remote type only: // remote type only:
/// //
/// #[serde(remote = "Generic<T>")] // #[serde(remote = "Generic<T>")]
/// struct ConcreteDef {…} // struct ConcreteDef {…}
/// //
fn check_remote_generic(cx: &Ctxt, cont: &Container) { fn check_remote_generic(cx: &Ctxt, cont: &Container) {
if let Some(remote) = cont.attrs.remote() { if let Some(remote) = cont.attrs.remote() {
let local_has_generic = !cont.generics.params.is_empty(); let local_has_generic = !cont.generics.params.is_empty();
@@ -39,8 +39,8 @@ fn check_remote_generic(cx: &Ctxt, cont: &Container) {
} }
} }
/// Getters are only allowed inside structs (not enums) with the `remote` // Getters are only allowed inside structs (not enums) with the `remote`
/// attribute. // attribute.
fn check_getter(cx: &Ctxt, cont: &Container) { fn check_getter(cx: &Ctxt, cont: &Container) {
match cont.data { match cont.data {
Data::Enum(_) => { Data::Enum(_) => {
@@ -62,7 +62,7 @@ fn check_getter(cx: &Ctxt, cont: &Container) {
} }
} }
/// Flattening has some restrictions we can test. // Flattening has some restrictions we can test.
fn check_flatten(cx: &Ctxt, cont: &Container) { fn check_flatten(cx: &Ctxt, cont: &Container) {
match &cont.data { match &cont.data {
Data::Enum(variants) => { Data::Enum(variants) => {
@@ -101,12 +101,12 @@ fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
} }
} }
/// The `other` attribute must be used at most once and it must be the last // The `other` attribute must be used at most once and it must be the last
/// variant of an enum. // variant of an enum.
/// //
/// Inside a `variant_identifier` all variants must be unit variants. Inside a // Inside a `variant_identifier` all variants must be unit variants. Inside a
/// `field_identifier` all but possibly one variant must be unit variants. The // `field_identifier` all but possibly one variant must be unit variants. The
/// last variant may be a newtype variant which is an implicit "other" case. // last variant may be a newtype variant which is an implicit "other" case.
fn check_identifier(cx: &Ctxt, cont: &Container) { fn check_identifier(cx: &Ctxt, cont: &Container) {
let variants = match &cont.data { let variants = match &cont.data {
Data::Enum(variants) => variants, Data::Enum(variants) => variants,
@@ -189,8 +189,8 @@ fn check_identifier(cx: &Ctxt, cont: &Container) {
} }
} }
/// Skip-(de)serializing attributes are not allowed on variants marked // Skip-(de)serializing attributes are not allowed on variants marked
/// (de)serialize_with. // (de)serialize_with.
fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) { fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
let variants = match &cont.data { let variants = match &cont.data {
Data::Enum(variants) => variants, Data::Enum(variants) => variants,
@@ -264,10 +264,9 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
} }
} }
/// The tag of an internally-tagged struct variant must not be // The tag of an internally-tagged struct variant must not be the same as either
/// the same as either one of its fields, as this would result in // one of its fields, as this would result in duplicate keys in the serialized
/// duplicate keys in the serialized output and/or ambiguity in // output and/or ambiguity in the to-be-deserialized input.
/// the to-be-deserialized input.
fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) { fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
let variants = match &cont.data { let variants = match &cont.data {
Data::Enum(variants) => variants, Data::Enum(variants) => variants,
@@ -313,8 +312,8 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
} }
} }
/// In the case of adjacently-tagged enums, the type and the // In the case of adjacently-tagged enums, the type and the contents tag must
/// contents tag must differ, for the same reason. // differ, for the same reason.
fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) { fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
let (type_tag, content_tag) = match cont.attrs.tag() { let (type_tag, content_tag) = match cont.attrs.tag() {
TagType::Adjacent { tag, content } => (tag, content), TagType::Adjacent { tag, content } => (tag, content),
@@ -332,7 +331,7 @@ fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
} }
} }
/// Enums and unit structs cannot be transparent. // Enums and unit structs cannot be transparent.
fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) { fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
if !cont.attrs.transparent() { if !cont.attrs.transparent() {
return; return;
+1 -1
View File
@@ -13,7 +13,7 @@
//! //!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.157")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.158")]
#![allow(unknown_lints, bare_trait_objects)] #![allow(unknown_lints, bare_trait_objects)]
// Ignored clippy lints // Ignored clippy lints
#![allow( #![allow(
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "1.0.157" # remember to update html_root_url version = "1.0.158" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs" build = "build.rs"
categories = ["development-tools::testing"] categories = ["development-tools::testing"]
+1 -1
View File
@@ -140,7 +140,7 @@
//! # } //! # }
//! ``` //! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.157")] #![doc(html_root_url = "https://docs.rs/serde_test/1.0.158")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
// Ignored clippy lints // Ignored clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))] #![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))]
+11
View File
@@ -0,0 +1,11 @@
use serde::Deserialize;
macro_rules! bug {
($serde_path:literal) => {
#[derive(Deserialize)]
#[serde(crate = $serde_path)]
pub struct Struct;
};
}
bug!("serde");