diff --git a/CHANGELOG.md b/CHANGELOG.md index 94d1d06e..853bbe49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +- [#760]: `defmt-macros`: Upgrade to syn 2 - [#758]: `defmt-print`: Tidy up - [#757]: `defmt-print`: Allow reading from a tcp port - [#756]: `CI`: Switch from bors to merge queue - [#753]: `demft` Add `Format` impls for `core::ptr::NonNull` and `fn(Args...) -> Ret` (up to 12 arguments) +[#760]: https://github.com/knurling-rs/defmt/pull/760 [#758]: https://github.com/knurling-rs/defmt/pull/758 [#757]: https://github.com/knurling-rs/defmt/pull/757 [#756]: https://github.com/knurling-rs/defmt/pull/756 diff --git a/firmware/defmt-test/macros/Cargo.toml b/firmware/defmt-test/macros/Cargo.toml index 8cfc59c6..c65bb675 100644 --- a/firmware/defmt-test/macros/Cargo.toml +++ b/firmware/defmt-test/macros/Cargo.toml @@ -15,7 +15,7 @@ proc-macro = true [dependencies] proc-macro2 = "1" quote = "1" -syn = { version = "1", features = ["extra-traits", "full"] } +syn = { version = "2", features = ["extra-traits", "full"] } [dev-dependencies] trybuild = "1" diff --git a/firmware/defmt-test/macros/src/lib.rs b/firmware/defmt-test/macros/src/lib.rs index ef6226da..62166232 100644 --- a/firmware/defmt-test/macros/src/lib.rs +++ b/firmware/defmt-test/macros/src/lib.rs @@ -47,22 +47,22 @@ fn tests_impl(args: TokenStream, input: TokenStream) -> parse::Result Vec { let mut cfgs = vec![]; for attr in attrs { - if attr.path.is_ident("cfg") { + if attr.path().is_ident("cfg") { cfgs.push(attr.clone()); } } diff --git a/macros/Cargo.toml b/macros/Cargo.toml index be15d104..892c066c 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -21,8 +21,7 @@ defmt-parser = { version = "=0.3.3", path = "../parser", features = ["unstable"] proc-macro-error = "1" proc-macro2 = "1" quote = "1" -# we require at least 1.0.56; see https://github.com/knurling-rs/defmt/pull/684 -syn = { version = "1.0.101", features = ["full"] } +syn = { version = "2", features = ["full"] } [dev-dependencies] maplit = "1" diff --git a/macros/src/attributes/panic_handler.rs b/macros/src/attributes/panic_handler.rs index 3415a890..e5537f47 100644 --- a/macros/src/attributes/panic_handler.rs +++ b/macros/src/attributes/panic_handler.rs @@ -46,7 +46,7 @@ fn check_for_attribute_conflicts( reject_list: &[&str], ) { for attr in attrs_to_check { - if let Some(ident) = attr.path.get_ident() { + if let Some(ident) = attr.path().get_ident() { let ident = ident.to_string(); if reject_list.contains(&ident.as_str()) { diff --git a/macros/src/derives/format/codegen/fields.rs b/macros/src/derives/format/codegen/fields.rs index 1728d9dc..e133014f 100644 --- a/macros/src/derives/format/codegen/fields.rs +++ b/macros/src/derives/format/codegen/fields.rs @@ -2,7 +2,7 @@ use std::fmt::Write as _; use proc_macro2::TokenStream as TokenStream2; use quote::{format_ident, quote}; -use syn::{Field, Fields, Index, Meta, NestedMeta, Type}; +use syn::{Field, Fields, Index, Type}; use crate::consts; @@ -87,51 +87,47 @@ enum FormatOption { /// Returns `Err` if we can't parse a valid defmt attribute. /// Returns `Ok(None)` if there are no `defmt` attributes on the field. fn get_defmt_format_option(field: &Field) -> syn::Result> { - use syn::Error; - let attrs = field - .attrs - .iter() - .filter(|a| a.path.is_ident("defmt")) - .map(|a| a.parse_meta()) - .collect::>>()?; - if attrs.is_empty() { - return Ok(None); - } else if attrs.len() > 1 { - return Err(Error::new_spanned( - field, - "multiple `defmt` attributes not supported", - )); - } // else attrs.len() == 1 - let attr = &attrs[0]; - let args = match attr { - Meta::List(list) => &list.nested, - bad => return Err(syn::Error::new_spanned(bad, "unrecognized attribute")), - }; - if args.len() != 1 { - return Err(syn::Error::new_spanned( - attr, - "expected 1 attribute argument", - )); - } - let arg = match &args[0] { - NestedMeta::Meta(Meta::Path(arg)) => arg, - bad => { - return Err(syn::Error::new_spanned( - bad, - "expected `Debug2Format` or `Display2Format`", - )) + let mut format_option = None; + + for attr in &field.attrs { + if attr.path().is_ident("defmt") { + if format_option.is_some() { + return Err(syn::Error::new_spanned( + field, + "multiple `defmt` attributes not supported", + )); + } + + let mut parsed_format = None; + + attr.parse_nested_meta(|meta| { + // #[defmt(Debug2Format)] + if meta.path.is_ident("Debug2Format") { + parsed_format = Some(FormatOption::Debug2Format); + return Ok(()); + } + + // #[defmt(Display2Format)] + if meta.path.is_ident("Display2Format") { + parsed_format = Some(FormatOption::Display2Format); + return Ok(()); + } + + Err(meta.error("expected `Debug2Format` or `Display2Format`")) + })?; + + if parsed_format.is_none() { + return Err(syn::Error::new_spanned( + &attr.meta, + "expected 1 attribute argument", + )); + } + + format_option = parsed_format; } - }; - if arg.is_ident("Debug2Format") { - Ok(Some(FormatOption::Debug2Format)) - } else if arg.is_ident("Display2Format") { - Ok(Some(FormatOption::Display2Format)) - } else { - Err(syn::Error::new_spanned( - arg, - "expected `Debug2Format` or `Display2Format`", - )) } + + Ok(format_option) } /// Returns `Some` if `ty` refers to a builtin Rust type that has native support from defmt and does diff --git a/macros/src/items/bitflags/input.rs b/macros/src/items/bitflags/input.rs index 1cfa0c48..4831267e 100644 --- a/macros/src/items/bitflags/input.rs +++ b/macros/src/items/bitflags/input.rs @@ -84,7 +84,7 @@ fn extract_cfgs(attrs: &[Attribute]) -> Vec { let mut cfgs = vec![]; for attr in attrs { - if attr.path.is_ident("cfg") { + if attr.path().is_ident("cfg") { cfgs.push(attr.clone()); } }