Repository: jonasbb/serde_with
Pull request #578 (2023-03-18 17:00:32)

Prepare for syn v2
Update darling to v0.20 and syn to v2, require serde v1.0.157 (first using syn v2).
This moves all direct dependencies to crates using syn v2.

syn v2 has problems with the `#[serde_as(as = "..")]` style of attributes, since `as` is a keyword and keywords are not allowed in meta attributes. Instead pre-process the token stream to replace all `as` with `r#as` which can be parsed.

Bump thiserror and cxx in the lock file.
Not all crates are using syn v2 yet.

codecov[bot]: ## [Codecov](https://codecov.io/gh/jonasbb/serde_with/pull/578?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jonas+Bushart) Report
> Merging [#578](https://codecov.io/gh/jonasbb/serde_with/pull/578?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jonas+Bushart) (ebf201b) into [master](https://codecov.io/gh/jonasbb/serde_with/commit/90724166087beae4eb30d1f4236435f3f0cd3bad?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jonas+Bushart) (9072416) will **decrease** coverage by `0.21%`.
> The diff coverage is `0.00%`.

```diff
@@            Coverage Diff             @@
##           master     #578      +/-   ##
==========================================
- Coverage   44.41%   44.20%   -0.21%     
==========================================
  Files          40       40              
  Lines        3249     3264      +15     
==========================================
  Hits         1443     1443              
- Misses       1806     1821      +15     
```


| [Impacted Files](https://codecov.io/gh/jonasbb/serde_with/pull/578?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jonas+Bushart) | Coverage Δ | |
|---|---|---|
| [serde\_with\_macros/src/apply.rs](https://codecov.io/gh/jonasbb/serde_with/pull/578?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jonas+Bushart#diff-c2VyZGVfd2l0aF9tYWNyb3Mvc3JjL2FwcGx5LnJz) | `33.33% <ø> (ø)` | |
| [serde\_with\_macros/src/lib.rs](https://codecov.io/gh/jonasbb/serde_with/pull/578?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jonas+Bushart#diff-c2VyZGVfd2l0aF9tYWNyb3Mvc3JjL2xpYi5ycw==) | `0.00% <0.00%> (ø)` | |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jonas+Bushart)


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 49156f2..ac54f2c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -98,14 +98,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
 dependencies = [
  "quote",
- "syn",
+ "syn 1.0.107",
 ]
 
 [[package]]
 name = "cxx"
-version = "1.0.91"
+version = "1.0.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86d3488e7665a7a483b57e25bdd90d0aeb2bc7608c8d0346acf2ad3f1caf1d62"
+checksum = "a9c00419335c41018365ddf7e4d5f1c12ee3659ddcf3e01974650ba1de73d038"
 dependencies = [
  "cc",
  "cxxbridge-flags",
@@ -115,9 +115,9 @@ dependencies = [
 
 [[package]]
 name = "cxx-build"
-version = "1.0.91"
+version = "1.0.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48fcaf066a053a41a81dfb14d57d99738b767febb8b735c3016e469fac5da690"
+checksum = "fb8307ad413a98fff033c8545ecf133e3257747b3bae935e7602aab8aa92d4ca"
 dependencies = [
  "cc",
  "codespan-reporting",
@@ -125,31 +125,31 @@ dependencies = [
  "proc-macro2",
  "quote",
  "scratch",
- "syn",
+ "syn 2.0.15",
 ]
 
 [[package]]
 name = "cxxbridge-flags"
-version = "1.0.91"
+version = "1.0.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2ef98b8b717a829ca5603af80e1f9e2e48013ab227b68ef37872ef84ee479bf"
+checksum = "edc52e2eb08915cb12596d29d55f0b5384f00d697a646dbd269b6ecb0fbd9d31"
 
 [[package]]
 name = "cxxbridge-macro"
-version = "1.0.91"
+version = "1.0.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892"
+checksum = "631569015d0d8d54e6c241733f944042623ab6df7bc3be7466874b05fcdb1c5f"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.15",
 ]
 
 [[package]]
 name = "darling"
-version = "0.14.3"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8"
+checksum = "e7c99d16b88c92aef47e58dadd53e87b4bd234c29934947a6cec8b466300f99b"
 dependencies = [
  "darling_core",
  "darling_macro",
@@ -157,27 +157,27 @@ dependencies = [
 
 [[package]]
 name = "darling_core"
-version = "0.14.3"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb"
+checksum = "2ea05d2fcb27b53f7a98faddaf5f2914760330ab7703adfc9df13332b42189f9"
 dependencies = [
  "fnv",
  "ident_case",
  "proc-macro2",
  "quote",
  "strsim",
- "syn",
+ "syn 2.0.15",
 ]
 
 [[package]]
 name = "darling_macro"
-version = "0.14.3"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685"
+checksum = "7bfb82b62b1b8a2a9808fb4caf844ede819a76cfc23b2827d7f94eefb49551eb"
 dependencies = [
  "darling_core",
  "quote",
- "syn",
+ "syn 2.0.15",
 ]
 
 [[package]]
@@ -403,9 +403,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.51"
+version = "1.0.56"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
+checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
 dependencies = [
  "unicode-ident",
 ]
@@ -423,9 +423,9 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.23"
+version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
+checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
 dependencies = [
  "proc-macro2",
 ]
@@ -504,9 +504,9 @@ checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
 
 [[package]]
 name = "serde"
-version = "1.0.152"
+version = "1.0.157"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
+checksum = "707de5fcf5df2b5788fca98dd7eab490bc2fd9b7ef1404defc462833b83f25ca"
 dependencies = [
  "serde_derive",
 ]
@@ -525,13 +525,13 @@ dependencies = [
 
 [[package]]
 name = "serde_derive"
-version = "1.0.152"
+version = "1.0.157"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
+checksum = "78997f4555c22a7971214540c4a661291970619afd56de19f77e0de86296e1e5"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.15",
 ]
 
 [[package]]
@@ -595,7 +595,7 @@ dependencies = [
  "rustversion",
  "serde",
  "serde_json",
- "syn",
+ "syn 2.0.15",
  "trybuild",
  "version-sync",
 ]
@@ -639,6 +639,17 @@ dependencies = [
  "unicode-ident",
 ]
 
+[[package]]
+name = "syn"
+version = "2.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
 [[package]]
 name = "termcolor"
 version = "1.2.0"
@@ -650,22 +661,22 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "1.0.38"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
+checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.38"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
+checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.15",
 ]
 
 [[package]]
@@ -797,7 +808,7 @@ dependencies = [
  "pulldown-cmark",
  "regex",
  "semver",
- "syn",
+ "syn 1.0.107",
  "toml",
  "url",
 ]
@@ -829,7 +840,7 @@ dependencies = [
  "once_cell",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.107",
  "wasm-bindgen-shared",
 ]
 
@@ -851,7 +862,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.107",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
diff --git a/serde_with/CHANGELOG.md b/serde_with/CHANGELOG.md
index 99262ed..b291747 100644
--- a/serde_with/CHANGELOG.md
+++ b/serde_with/CHANGELOG.md
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 
 ## [Unreleased]
 
+### Changed
+
+* Update `syn` to v2 and `darling` to v0.20 (#578)
+    Update proc-macro dependencies.
+    This change should have no impact on users, but now uses the same dependency as `serde_derive`.
+
 ## [2.3.2] - 2023-04-05
 
 ### Changed
diff --git a/serde_with/Cargo.toml b/serde_with/Cargo.toml
index 5d6a54b..63111f0 100644
--- a/serde_with/Cargo.toml
+++ b/serde_with/Cargo.toml
@@ -67,7 +67,7 @@ hex = {version = "0.4.3", optional = true, default-features = false}
 indexmap_1 = {package = "indexmap", version = "1.8", optional = true, default-features = false, features = ["serde-1"]}
 # The derive feature is needed for the flattened_maybe macro.
 # https://github.com/jonasbb/serde_with/blob/eb1965a74a3be073ecd13ec05f02a01bc1c44309/serde_with/src/flatten_maybe.rs#L67
-serde = {version = "1.0.139", default-features = false, features = ["derive"] }
+serde = {version = "1.0.157", default-features = false, features = ["derive"] }
 serde_json = {version = "1.0.45", optional = true, default-features = false}
 serde_with_macros = {path = "../serde_with_macros", version = "=2.3.2", optional = true}
 time_0_3 = {package = "time", version = "~0.3.11", optional = true, default-features = false}
diff --git a/serde_with/src/flatten_maybe.rs b/serde_with/src/flatten_maybe.rs
index b5fc7e1..6dab161 100644
--- a/serde_with/src/flatten_maybe.rs
+++ b/serde_with/src/flatten_maybe.rs
@@ -50,7 +50,7 @@
 /// ```
 #[macro_export]
 macro_rules! flattened_maybe {
-    ($fn:ident, $field:literal) => {
+    ($fn:ident, $field:tt) => {
         fn $fn<'de, T, D>(deserializer: D) -> $crate::__private__::Result<T, D::Error>
         where
             T: $crate::serde::Deserialize<'de>,
diff --git a/serde_with_macros/CHANGELOG.md b/serde_with_macros/CHANGELOG.md
index 0f25654..c024332 100644
--- a/serde_with_macros/CHANGELOG.md
+++ b/serde_with_macros/CHANGELOG.md
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 
 ## [Unreleased]
 
+### Changed
+
+* Update `syn` to v2 and `darling` to v0.20 (#578)
+    Update proc-macro dependencies.
+    This change should have no impact on users, but now uses the same dependency as `serde_derive`.
+
 ## [2.3.2] - 2023-04-05
 
 No changes.
diff --git a/serde_with_macros/Cargo.toml b/serde_with_macros/Cargo.toml
index cbdb927..42d8603 100644
--- a/serde_with_macros/Cargo.toml
+++ b/serde_with_macros/Cargo.toml
@@ -30,7 +30,7 @@ proc-macro = true
 maintenance = {status = "actively-developed"}
 
 [dependencies]
-darling = "0.14.0"
+darling = "0.20.0"
 proc-macro2 = "1.0.1"
 quote = "1.0.0"
 
@@ -40,13 +40,13 @@ features = [
     "full",
     "parsing",
 ]
-version = "1.0.3"
+version = "2.0.0"
 
 [dev-dependencies]
 expect-test = "1.4.0"
 pretty_assertions = "1.0.0"
 rustversion = "1.0.0"
-serde = {version = "1.0.75", features = ["derive"]}
+serde = {version = "1.0.157", features = ["derive"]}
 serde_json = "1.0.25"
 trybuild = "1.0.80"
 version-sync = "0.9.1"
diff --git a/serde_with_macros/src/apply.rs b/serde_with_macros/src/apply.rs
index 2049686..9cab898 100644
--- a/serde_with_macros/src/apply.rs
+++ b/serde_with_macros/src/apply.rs
@@ -1,11 +1,11 @@
-use darling::{Error as DarlingError, FromMeta};
+use darling::{ast::NestedMeta, Error as DarlingError, FromMeta};
 use proc_macro::TokenStream;
 use quote::ToTokens as _;
 use syn::{
     parse::{Parse, ParseStream},
     punctuated::Punctuated,
-    Attribute, Error, Field, NestedMeta, Path, Token, Type, TypeArray, TypeGroup, TypeParen,
-    TypePath, TypePtr, TypeReference, TypeSlice, TypeTuple,
+    Attribute, Error, Field, Path, Token, Type, TypeArray, TypeGroup, TypeParen, TypePath, TypePtr,
+    TypeReference, TypeSlice, TypeTuple,
 };
 
 /// Parsed form of a single rule in the `#[apply(...)]` attribute.
@@ -53,7 +53,7 @@ impl Parse for ApplyInput {
         }
 
         let rules: Punctuated<AddAttributesRule, Token![,]> =
-            input.parse_terminated(AddAttributesRule::parse)?;
+            input.parse_terminated(AddAttributesRule::parse, Token![,])?;
         Ok(Self { metas, rules })
     }
 }
diff --git a/serde_with_macros/src/lib.rs b/serde_with_macros/src/lib.rs
index df03851..6ef732c 100644
--- a/serde_with_macros/src/lib.rs
+++ b/serde_with_macros/src/lib.rs
@@ -49,6 +49,7 @@ mod utils;
 
 use crate::utils::{split_with_de_lifetime, DeriveOptions, IteratorExt as _};
 use darling::{
+    ast::NestedMeta,
     util::{Flag, Override},
     Error as DarlingError, FromField, FromMeta,
 };
@@ -56,9 +57,12 @@ use proc_macro::TokenStream;
 use proc_macro2::{Span, TokenStream as TokenStream2};
 use quote::quote;
 use syn::{
-    parse_macro_input, parse_quote, punctuated::Pair, spanned::Spanned, AttributeArgs, DeriveInput,
-    Error, Field, Fields, GenericArgument, ItemEnum, ItemStruct, Meta, NestedMeta, Path,
-    PathArguments, ReturnType, Type,
+    parse::Parser,
+    parse_macro_input, parse_quote,
+    punctuated::{Pair, Punctuated},
+    spanned::Spanned,
+    DeriveInput, Error, Field, Fields, GenericArgument, ItemEnum, ItemStruct, Meta, Path,
+    PathArguments, ReturnType, Token, Type,
 };
 
 /// Apply function on every field of structs or enums
@@ -184,7 +188,7 @@ where
             .iter()
             .flat_map(|variant| {
                 variant.attrs.iter().filter_map(|attr| {
-                    if attr.path.is_ident("serde_as") {
+                    if attr.path().is_ident("serde_as") {
                         Some(
                             DarlingError::custom(
                                 "serde_as attribute is not allowed on enum variants",
@@ -331,7 +335,7 @@ fn skip_serializing_none_add_attr_to_field(field: &mut Field) -> Result<(), Stri
         // Remove the `serialize_always` attribute
         let mut has_always_attr = false;
         field.attrs.retain(|attr| {
-            let has_attr = attr.path.is_ident("serialize_always");
+            let has_attr = attr.path().is_ident("serialize_always");
             has_always_attr |= has_attr;
             !has_attr
         });
@@ -363,7 +367,7 @@ fn skip_serializing_none_add_attr_to_field(field: &mut Field) -> Result<(), Stri
         let has_attr = field
             .attrs
             .iter()
-            .any(|attr| attr.path.is_ident("serialize_always"));
+            .any(|attr| attr.path().is_ident("serialize_always"));
         if has_attr {
             return Err("`serialize_always` may only be used on fields of type `Option`.".into());
         }
@@ -424,19 +428,25 @@ fn is_std_option(type_: &Type) -> bool {
 /// * with the name being `skip_serializing_if`
 fn field_has_attribute(field: &Field, namespace: &str, name: &str) -> bool {
     for attr in &field.attrs {
-        if attr.path.is_ident(namespace) {
+        if attr.path().is_ident(namespace) {
             // Ignore non parsable attributes, as these are not important for us
-            if let Ok(Meta::List(expr)) = attr.parse_meta() {
-                for expr in expr.nested {
+            if let Meta::List(expr) = &attr.meta {
+                let nested = match Punctuated::<Meta, Token![,]>::parse_terminated
+                    .parse2(expr.tokens.clone())
+                {
+                    Ok(nested) => nested,
+                    Err(_) => continue,
+                };
+                for expr in nested {
                     match expr {
-                        NestedMeta::Meta(Meta::NameValue(expr)) => {
+                        Meta::NameValue(expr) => {
                             if let Some(ident) = expr.path.get_ident() {
                                 if *ident == name {
                                     return true;
                                 }
                             }
                         }
-                        NestedMeta::Meta(Meta::Path(expr)) => {
+                        Meta::Path(expr) => {
                             if let Some(ident) = expr.get_ident() {
                                 if *ident == name {
                                     return true;
@@ -590,28 +600,32 @@ pub fn serde_as(args: TokenStream, input: TokenStream) -> TokenStream {
         alt_crate_path: Option<Path>,
     }
 
-    let args: AttributeArgs = parse_macro_input!(args);
-    let container_options = match SerdeContainerOptions::from_list(&args) {
-        Ok(v) => v,
-        Err(e) => {
-            return TokenStream::from(e.write_errors());
-        }
-    };
+    match NestedMeta::parse_meta_list(args.into()) {
+        Ok(list) => {
+            let container_options = match SerdeContainerOptions::from_list(&list) {
+                Ok(v) => v,
+                Err(e) => {
+                    return TokenStream::from(e.write_errors());
+                }
+            };
 
-    let serde_with_crate_path = container_options
-        .alt_crate_path
-        .unwrap_or_else(|| syn::parse_quote!(::serde_with));
+            let serde_with_crate_path = container_options
+                .alt_crate_path
+                .unwrap_or_else(|| syn::parse_quote!(::serde_with));
 
-    // Convert any error message into a nice compiler error
-    let res = match apply_function_to_struct_and_enum_fields_darling(
-        input,
-        &serde_with_crate_path,
-        |field| serde_as_add_attr_to_field(field, &serde_with_crate_path),
-    ) {
-        Ok(res) => res,
-        Err(err) => err.write_errors(),
-    };
-    TokenStream::from(res)
+            // Convert any error message into a nice compiler error
+            let res = match apply_function_to_struct_and_enum_fields_darling(
+                input,
+                &serde_with_crate_path,
+                |field| serde_as_add_attr_to_field(field, &serde_with_crate_path),
+            ) {
+                Ok(res) => res,
+                Err(err) => err.write_errors(),
+            };
+            TokenStream::from(res)
+        }
+        Err(e) => TokenStream::from(DarlingError::from(e).write_errors()),
+    }
 }
 
 /// Inspect the field and convert the `serde_as` attribute into the classical `serde`
@@ -622,7 +636,6 @@ fn serde_as_add_attr_to_field(
     #[derive(FromField)]
     #[darling(attributes(serde_as))]
     struct SerdeAsOptions {
-        #[darling(rename = "as")]
         r#as: Option<Type>,
         deserialize_as: Option<Type>,
         serialize_as: Option<Type>,
@@ -679,12 +692,36 @@ fn serde_as_add_attr_to_field(
         }
     }
 
-    // Check if there even is any `serde_as` attribute and exit early if not.
-    if !field
-        .attrs
-        .iter()
-        .any(|attr| attr.path.is_ident("serde_as"))
-    {
+    // syn v2 no longer supports keywords in the path position of an attribute.
+    // That breaks #[serde_as(as = "FooBar")], since `as` is a keyword.
+    // For each attribute, that is named `serde_as`, we replace the `as` keyword with `r#as`.
+    let mut has_serde_as = false;
+    field.attrs.iter_mut().for_each(|attr| {
+        if attr.path().is_ident("serde_as") {
+            // We found a `serde_as` attribute.
+            // Remember that such that we can quick exit otherwise
+            has_serde_as = true;
+
+            if let Meta::List(metalist) = &mut attr.meta {
+                metalist.tokens = std::mem::take(&mut metalist.tokens)
+                    .into_iter()
+                    .map(|token| {
+                        use proc_macro2::{Ident, TokenTree};
+
+                        // Replace `as` with `r#as`.
+                        match token {
+                            TokenTree::Ident(ident) if ident == "as" => {
+                                TokenTree::Ident(Ident::new_raw("as", ident.span()))
+                            }
+                            _ => token,
+                        }
+                    })
+                    .collect();
+            }
+        }
+    });
+    // If there is no `serde_as` attribute, we can exit early.
+    if !has_serde_as {
         return Ok(());
     }
     let serde_as_options = SerdeAsOptions::from_field(field)?;


Test patch:
diff --git a/serde_with_macros/tests/compile-fail/serde_as.stderr b/serde_with_macros/tests/compile-fail/serde_as.stderr
index 5f1022b..d6f1e29 100644
--- a/serde_with_macros/tests/compile-fail/serde_as.stderr
+++ b/serde_with_macros/tests/compile-fail/serde_as.stderr
@@ -88,7 +88,13 @@ error: Unknown field: `unknw2`
 59 |     #[serde_as(unknwn1 = "Hello", unknw2 = "World")]
    |                                   ^^^^^^
 
-error: Unable to parse attribute: expected literal
+error: Unknown literal value `123`
+  --> tests/compile-fail/serde_as.rs:67:31
+   |
+67 |     #[serde_as(serialize_as = "123", deserialize_as = DisplayFromStr)]
+   |                               ^^^^^
+
+error: Unexpected literal type `path`
   --> tests/compile-fail/serde_as.rs:67:55
    |
 67 |     #[serde_as(serialize_as = "123", deserialize_as = DisplayFromStr)]