diff --git a/Cargo.lock b/Cargo.lock index a99484b..1245d3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,6 +93,7 @@ dependencies = [ "pin-init-internal", "prettyplease", "rustc_version", + "test_dummy_only", "trybuild", ] @@ -221,6 +222,10 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "test_dummy_only" +version = "0.0.1" + [[package]] name = "toml" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index bf53ab2..2b5e37d 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"] } +test_dummy_only = { path = "./test_dummy_only" } [lints.rust] non_ascii_idents = "deny" diff --git a/internal/src/pin_data.rs b/internal/src/pin_data.rs index 83785cb..4ef4f62 100644 --- a/internal/src/pin_data.rs +++ b/internal/src/pin_data.rs @@ -162,7 +162,7 @@ fn generate_unpin_impl( .cloned() .collect::>(); for field in &mut pinned_fields { - field.attrs.retain(|a| !a.path().is_ident("pin")); + field.attrs.retain(keep_attr); } quote! { // This struct will be used for the unpin analysis. It is needed, because only structurally @@ -267,7 +267,7 @@ fn generate_projections( .. }| { let mut attrs = attrs.clone(); - attrs.retain(|a| !a.path().is_ident("pin")); + attrs.retain(keep_attr); let mut no_doc_attrs = attrs.clone(); no_doc_attrs.retain(|a| !a.path().is_ident("doc")); let ident = ident @@ -348,6 +348,16 @@ fn generate_projections( } } +fn keep_attr(attr: &syn::Attribute) -> bool { + let path = attr.path(); + + if path.is_ident("pin") { + return false; + } + + path.is_ident("doc") || path.is_ident("cfg") +} + fn generate_the_pin_data( ItemStruct { generics, @@ -376,7 +386,7 @@ fn generate_the_pin_data( pinned: bool, ) -> TokenStream { let mut attrs = attrs.clone(); - attrs.retain(|a| !a.path().is_ident("pin")); + attrs.retain(keep_attr); let ident = ident .as_ref() .expect("only structs with named fields are supported"); diff --git a/test_dummy_only/Cargo.lock b/test_dummy_only/Cargo.lock new file mode 100644 index 0000000..fa62fcd --- /dev/null +++ b/test_dummy_only/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/test_dummy_only/Cargo.toml b/test_dummy_only/Cargo.toml new file mode 100644 index 0000000..ada847f --- /dev/null +++ b/test_dummy_only/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "test_dummy_only" +version = "0.0.1" +edition = "2021" + +authors = ["y86-dev"] +license = "MIT OR Apache-2.0" +description = "Proc macro only for test reproduction." + +publish = false + +[lib] +proc-macro = true diff --git a/test_dummy_only/src/lib.rs b/test_dummy_only/src/lib.rs new file mode 100644 index 0000000..0ea0925 --- /dev/null +++ b/test_dummy_only/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 0000000..e0e3522 --- /dev/null +++ b/tests/extra_attrs.rs @@ -0,0 +1,23 @@ +#![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] + +use pin_init::*; +use test_dummy_only::Dummy; + +#[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); +}