Skip to content

Commit

Permalink
wip: fix issue 68
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Sep 5, 2019
1 parent 3a6ded0 commit abf3700
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 15 deletions.
2 changes: 1 addition & 1 deletion pin-project-internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ renamed = ["proc-macro-crate", "serde", "lazy_static"]
[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "1.0", features = ["full"] }
syn = { version = "1.0", features = ["full", "extra-traits"] }

proc-macro-crate = { version = "0.1.4", optional = true }
# Required until a new toml-rs release is made with https://github.com/alexcrichton/toml-rs/pull/311,
Expand Down
14 changes: 9 additions & 5 deletions pin-project-internal/src/pin_project/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use proc_macro2::TokenStream;
use quote::{format_ident, quote, ToTokens};
use syn::{parse::Nothing, Field, Fields, FieldsNamed, FieldsUnnamed, ItemEnum, Result, Variant};

use crate::utils::VecExt;
use crate::utils::{cfg_attrs, VecExt};

use super::{Context, PIN};

Expand Down Expand Up @@ -95,11 +95,13 @@ fn named(
let _: Nothing = syn::parse2(attr.tokens)?;
cx.push_unpin_bounds(ty.clone());
let lifetime = &cx.lifetime;
proj_fields.push(quote!(#ident: ::core::pin::Pin<&#lifetime mut #ty>));
let cfgs = cfg_attrs(attrs);
proj_fields.push(quote!(#(#cfgs)* #ident: ::core::pin::Pin<&#lifetime mut #ty>));
proj_body.push(quote!(#ident: ::core::pin::Pin::new_unchecked(#ident)));
} else {
let lifetime = &cx.lifetime;
proj_fields.push(quote!(#ident: &#lifetime mut #ty));
let cfgs = cfg_attrs(attrs);
proj_fields.push(quote!(#(#cfgs)* #ident: &#lifetime mut #ty));
proj_body.push(quote!(#ident));
}
proj_pat.push(ident);
Expand All @@ -124,11 +126,13 @@ fn unnamed(
let _: Nothing = syn::parse2(attr.tokens)?;
cx.push_unpin_bounds(ty.clone());
let lifetime = &cx.lifetime;
proj_fields.push(quote!(::core::pin::Pin<&#lifetime mut #ty>));
let cfgs = cfg_attrs(attrs);
proj_fields.push(quote!(#(#cfgs)* ::core::pin::Pin<&#lifetime mut #ty>));
proj_body.push(quote!(::core::pin::Pin::new_unchecked(#x)));
} else {
let lifetime = &cx.lifetime;
proj_fields.push(quote!(&#lifetime mut #ty));
let cfgs = cfg_attrs(attrs);
proj_fields.push(quote!(#(#cfgs)* &#lifetime mut #ty));
proj_body.push(quote!(#x));
}
proj_pat.push(x);
Expand Down
23 changes: 14 additions & 9 deletions pin-project-internal/src/pin_project/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use syn::{parse::Nothing, Field, Fields, FieldsNamed, FieldsUnnamed, Index, ItemStruct, Result};

use crate::utils::VecExt;
use crate::utils::{cfg_attrs, VecExt};

use super::{Context, PIN};

Expand Down Expand Up @@ -70,12 +70,15 @@ fn named(
let _: Nothing = syn::parse2(attr.tokens)?;
cx.push_unpin_bounds(ty.clone());
let lifetime = &cx.lifetime;
proj_fields.push(quote!(#ident: ::core::pin::Pin<&#lifetime mut #ty>));
proj_init.push(quote!(#ident: ::core::pin::Pin::new_unchecked(&mut this.#ident)));
let cfgs = cfg_attrs(attrs);
proj_fields.push(quote!(#(#cfgs)* #ident: ::core::pin::Pin<&#lifetime mut #ty>));
proj_init
.push(quote!(#(#cfgs)* #ident: ::core::pin::Pin::new_unchecked(&mut this.#ident)));
} else {
let lifetime = &cx.lifetime;
proj_fields.push(quote!(#ident: &#lifetime mut #ty));
proj_init.push(quote!(#ident: &mut this.#ident));
let cfgs = cfg_attrs(attrs);
proj_fields.push(quote!(#(#cfgs)* #ident: &#lifetime mut #ty));
proj_init.push(quote!(#(#cfgs)* #ident: &mut this.#ident));
}
}

Expand All @@ -96,12 +99,14 @@ fn unnamed(
let _: Nothing = syn::parse2(attr.tokens)?;
cx.push_unpin_bounds(ty.clone());
let lifetime = &cx.lifetime;
proj_fields.push(quote!(::core::pin::Pin<&#lifetime mut #ty>));
proj_init.push(quote!(::core::pin::Pin::new_unchecked(&mut this.#i)));
let cfgs = cfg_attrs(attrs);
proj_fields.push(quote!(#(#cfgs)* ::core::pin::Pin<&#lifetime mut #ty>));
proj_init.push(quote!(#(#cfgs)* { ::core::pin::Pin::new_unchecked(&mut this.#i) }));
} else {
let lifetime = &cx.lifetime;
proj_fields.push(quote!(&#lifetime mut #ty));
proj_init.push(quote!(&mut this.#i));
let cfgs = cfg_attrs(attrs);
proj_fields.push(quote!(#(#cfgs)* &#lifetime mut #ty));
proj_init.push(quote!(#(#cfgs)* { &mut this.#i }));
}
}

Expand Down
4 changes: 4 additions & 0 deletions pin-project-internal/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ pub(crate) fn proj_generics(generics: &mut Generics, lifetime: Lifetime) {
);
}

pub(crate) fn cfg_attrs(attrs: &[Attribute]) -> Vec<Attribute> {
attrs.iter().filter(|attr| attr.path.is_ident("cfg")).cloned().collect()
}

pub(crate) trait VecExt {
fn find_remove(&mut self, ident: &str) -> Option<Attribute>;
}
Expand Down
28 changes: 28 additions & 0 deletions tests/pin_project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,31 @@ fn lifetime_project() {
}
}
}

#[test]
fn cfgs() {
#[pin_project]
pub struct Simple {
#[cfg(target_os = "macos")]
#[pin]
inner: u8,
#[cfg(not(target_os = "macos"))]
#[pin]
inner: u16,
}

#[cfg(target_os = "macos")]
struct Foo;
#[cfg(not(target_os = "macos"))]
struct Bar;

#[pin_project]
pub struct DiffNames {
#[cfg(target_os = "macos")]
#[pin]
inner: Foo,
#[cfg(not(target_os = "macos"))]
#[pin]
inner: Bar,
}
}

0 comments on commit abf3700

Please sign in to comment.