diff --git a/Cargo.lock b/Cargo.lock index 1119162d..cb7da04e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,10 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" +[[package]] +name = "dummy" +version = "0.0.0" + [[package]] name = "equivalent" version = "1.0.1" @@ -87,6 +91,7 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" name = "pinned-init" version = "0.0.10" dependencies = [ + "dummy", "libc", "macrotest", "paste", diff --git a/Cargo.toml b/Cargo.toml index cfe8c414..0f4d3df1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ trybuild = { version = "1.0", features = ["diff"] } macrotest = "1.0" # needed for macrotest, have to enable verbatim feature to be able to format `&raw` expressions. prettyplease = { version = "0.2", features = ["verbatim"] } +dummy = { path = "tests/dummy" } [lints.rust] non_ascii_idents = "deny" diff --git a/src/macros.rs b/src/macros.rs index a3eda1e4..25204e73 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -779,8 +779,9 @@ macro_rules! __pin_data { @ty_generics($($ty_generics:tt)*), @decl_generics($($decl_generics:tt)*), @where($($whr:tt)*), - // Some other attribute, just put it into `$accum`. - @fields_munch(#[$($attr:tt)*] $($rest:tt)*), + // The #[cfg] attributes are kept for those members that are not + // removed, so we need to keep them. + @fields_munch(#[cfg $($attr:tt)*] $($rest:tt)*), @pinned($($pinned:tt)*), @not_pinned($($not_pinned:tt)*), @fields($($fields:tt)*), @@ -800,7 +801,41 @@ macro_rules! __pin_data { @pinned($($pinned)*), @not_pinned($($not_pinned)*), @fields($($fields)*), - @accum($($accum)* #[$($attr)*]), + @accum($($accum)* #[cfg $($attr)*]), + @is_pinned($($is_pinned)?), + @pinned_drop($($pinned_drop)?), + ); + }; + (find_pinned_fields: + @struct_attrs($($struct_attrs:tt)*), + @vis($vis:vis), + @name($name:ident), + @impl_generics($($impl_generics:tt)*), + @ty_generics($($ty_generics:tt)*), + @decl_generics($($decl_generics:tt)*), + @where($($whr:tt)*), + // Some other attribute, just put it into `$fields` + @fields_munch(#[$($attr:tt)*] $($rest:tt)*), + @pinned($($pinned:tt)*), + @not_pinned($($not_pinned:tt)*), + @fields($($fields:tt)*), + @accum($($accum:tt)*), + @is_pinned($($is_pinned:ident)?), + @pinned_drop($($pinned_drop:ident)?), + ) => { + $crate::__pin_data!(find_pinned_fields: + @struct_attrs($($struct_attrs)*), + @vis($vis), + @name($name), + @impl_generics($($impl_generics)*), + @ty_generics($($ty_generics)*), + @decl_generics($($decl_generics)*), + @where($($whr)*), + @fields_munch($($rest)*), + @pinned($($pinned)*), + @not_pinned($($not_pinned)*), + @fields($($fields)* #[$($attr)*]), + @accum($($accum)*), @is_pinned($($is_pinned)?), @pinned_drop($($pinned_drop)?), ); diff --git a/tests/dummy/Cargo.lock b/tests/dummy/Cargo.lock new file mode 100644 index 00000000..fa62fcd5 --- /dev/null +++ b/tests/dummy/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "test_only" +version = "0.0.1" diff --git a/tests/dummy/Cargo.toml b/tests/dummy/Cargo.toml new file mode 100644 index 00000000..366378e9 --- /dev/null +++ b/tests/dummy/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "dummy" +version = "0.0.0" +edition = "2024" + +license = "MIT OR Apache-2.0" +description = "Proc macro only for test reproduction." + +publish = false + +[lib] +proc-macro = true diff --git a/tests/dummy/src/lib.rs b/tests/dummy/src/lib.rs new file mode 100644 index 00000000..0ea09257 --- /dev/null +++ b/tests/dummy/src/lib.rs @@ -0,0 +1,4 @@ +#[proc_macro_derive(Dummy, attributes(dummy_attr))] +pub fn derive_device(_: proc_macro::TokenStream) -> proc_macro::TokenStream { + proc_macro::TokenStream::new() +} diff --git a/tests/extra_attrs.rs b/tests/extra_attrs.rs new file mode 100644 index 00000000..68cc91d3 --- /dev/null +++ b/tests/extra_attrs.rs @@ -0,0 +1,23 @@ +#![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] + +use dummy::Dummy; +use pinned_init::*; + +#[pin_data] +#[derive(Dummy)] +struct Pointless { + #[pin] + #[dummy_attr] + #[cfg(test)] + member: i8, + #[pin] + #[dummy_attr] + #[cfg(not(test))] + member: u8, +} + +#[test] +fn multiple_attributes() { + stack_pin_init!(let p = init!(Pointless { member: 0 })); + println!("{}", p.member); +}