We are not using the ConstFieldOffset trait, so put it in a feature gate

This commit is contained in:
Olivier Goffart 2020-08-25 14:41:22 +02:00
parent 2c0fc29c5c
commit c299bd5483
5 changed files with 60 additions and 32 deletions

View file

@ -8,6 +8,8 @@ description = "Wrapper around field-offset crate and const-field-offset-macro"
repository = "https://github.com/sixtyfpsui/sixtyfps"
homepage = "https://sixtyfps.io"
[features]
field-offset-trait = ["const-field-offset-macro/field-offset-trait"]
[dependencies]
const-field-offset-macro = { version = "=0.1.0", path = "./macro" }

View file

@ -8,11 +8,13 @@ description = "Procedural macro to generate constant field offset from repr(c) s
repository = "https://github.com/sixtyfpsui/sixtyfps"
homepage = "https://sixtyfps.io"
[lib]
path = "macro.rs"
proc-macro = true
[features]
field-offset-trait = []
[dependencies]
syn = { version = "1.0", features = ["derive"] }
quote = "1.0"

View file

@ -18,7 +18,9 @@ extern crate proc_macro;
use proc_macro::TokenStream;
use quote::{format_ident, quote, quote_spanned};
use syn::{parse_macro_input, spanned::Spanned, DeriveInput, VisRestricted, Visibility};
use syn::{parse_macro_input, spanned::Spanned, DeriveInput};
#[cfg(feature = "field-offset-trait")]
use syn::{VisRestricted, Visibility};
/**
@ -42,7 +44,11 @@ assert_eq!(FOO, 4);
// const FOO : usize = memofsets::offsetof!(Foo, field_2);
```
In addition, the macro laso create a module `{ClassName}_field_offsets` which contains
*/
#[cfg_attr(
feature = "field-offset-trait",
doc = "
In addition, the macro also create a module `{ClassName}_field_offsets` which contains
zero-sized type that implement the `const_field_offset::ConstFieldOffset` trait
```rust
@ -57,6 +63,9 @@ struct Foo {
const FOO : FieldOffset<Foo, u32> = Foo_field_offsets::field_2::OFFSET;
assert_eq!(FOO.get_byte_offset(), 4);
```
"
)]
/**
## limitations
@ -180,8 +189,6 @@ pub fn const_field_offset(input: TokenStream) -> TokenStream {
let struct_name = input.ident;
let field_struct_name = quote::format_ident!("{}FieldsOffsets", struct_name);
let module_name = quote::format_ident!("{}_field_offsets", struct_name);
let (fields, types, vis) = if let syn::Data::Struct(s) = &input.data {
if let syn::Fields::Named(n) = &s.fields {
let (f, tv): (Vec<_>, Vec<_>) =
@ -195,19 +202,6 @@ pub fn const_field_offset(input: TokenStream) -> TokenStream {
return TokenStream::from(quote! {compile_error!("Only work for struct")});
};
let in_mod_vis = vis.iter().map(|vis| match vis {
Visibility::Public(_) => quote! {#vis},
Visibility::Crate(_) => quote! {#vis},
Visibility::Restricted(VisRestricted { pub_token, path, .. }) => {
if quote!(#path).to_string().starts_with("super") {
quote!(#pub_token(in super::#path))
} else {
quote!(#vis)
}
}
Visibility::Inherited => quote!(pub(super)),
});
let doc = format!(
"Helper struct containing the offsets of the fields of the struct `{}`",
struct_name
@ -287,7 +281,27 @@ pub fn const_field_offset(input: TokenStream) -> TokenStream {
}
#pinned_drop_impl
};
#[cfg(feature = "field-offset-trait")]
let module_name = quote::format_ident!("{}_field_offsets", struct_name);
#[cfg(feature = "field-offset-trait")]
let in_mod_vis = vis.iter().map(|vis| match vis {
Visibility::Public(_) => quote! {#vis},
Visibility::Crate(_) => quote! {#vis},
Visibility::Restricted(VisRestricted { pub_token, path, .. }) => {
if quote!(#path).to_string().starts_with("super") {
quote!(#pub_token(in super::#path))
} else {
quote!(#vis)
}
}
Visibility::Inherited => quote!(pub(super)),
});
#[cfg(feature = "field-offset-trait")]
let expanded = quote! { #expanded
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
#[allow(missing_docs)]

View file

@ -10,6 +10,20 @@ pub use const_field_offset_macro::FieldOffsets;
pub use field_offset::{AllowPin, FieldOffset, NotPinned};
/// This trait needs to be implemented if you use the `#[pin_drop]` attribute. It enables
/// you to implement Drop for your type safely.
pub trait PinnedDrop {
/// This is the equivalent to the regular Drop trait with the difference that self
/// is pinned.
fn drop(self: Pin<&mut Self>);
#[doc(hidden)]
fn do_safe_pinned_drop(&mut self) {
let p = unsafe { Pin::new_unchecked(self) };
p.drop()
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -91,6 +105,7 @@ mod tests {
}
#[doc(hidden)]
#[cfg(feature = "field-offset-trait")]
mod internal {
use super::*;
pub trait CombineFlag {
@ -110,6 +125,7 @@ mod internal {
}
}
#[cfg(feature = "field-offset-trait")]
pub trait ConstFieldOffset: Copy {
/// The type of the container
type Container;
@ -150,6 +166,7 @@ pub trait ConstFieldOffset: Copy {
/// This can be used to transmute a FieldOffset from a NotPinned to any pin flag.
/// This is only valid if we know that the offset is actually valid for this Flag.
#[cfg(feature = "field-offset-trait")]
union TransmutePinFlag<Container, Field, PinFlag> {
x: FieldOffset<Container, Field, PinFlag>,
y: FieldOffset<Container, Field>,
@ -157,8 +174,10 @@ union TransmutePinFlag<Container, Field, PinFlag> {
/// Helper class used as the result of the addition of two stype that implement the `ConstFieldOffset` trait
#[derive(Copy, Clone)]
#[cfg(feature = "field-offset-trait")]
pub struct ConstFieldOffsetSum<A: ConstFieldOffset, B: ConstFieldOffset>(pub A, pub B);
#[cfg(feature = "field-offset-trait")]
impl<A: ConstFieldOffset, B: ConstFieldOffset> ConstFieldOffset for ConstFieldOffsetSum<A, B>
where
A: ConstFieldOffset<Field = B::Container>,
@ -177,6 +196,7 @@ where
};
}
#[cfg(feature = "field-offset-trait")]
impl<A: ConstFieldOffset, B: ConstFieldOffset, Other> ::core::ops::Add<Other>
for ConstFieldOffsetSum<A, B>
where
@ -188,17 +208,3 @@ where
ConstFieldOffsetSum(self, other)
}
}
/// This trait needs to be implemented if you use the `#[pin_drop]` attribute. It enables
/// you to implement Drop for your type safely.
pub trait PinnedDrop {
/// This is the equivalent to the regular Drop trait with the difference that self
/// is pinned.
fn drop(self: Pin<&mut Self>);
#[doc(hidden)]
fn do_safe_pinned_drop(&mut self) {
let p = unsafe { Pin::new_unchecked(self) };
p.drop()
}
}

View file

@ -50,7 +50,11 @@ fn test() {
assert_eq!(XX_CONST, offset_of!(MyStruct2, xx));
assert_eq!(D_STATIC, offset_of!(MyStruct, d));
}
#[test]
#[cfg(feature = "field-offset-trait")]
fn test_module() {
assert_eq!(offset_of!(MyStruct, a), MyStruct_field_offsets::a.get_byte_offset());
assert_eq!(offset_of!(MyStruct, b), MyStruct_field_offsets::b.get_byte_offset());
assert_eq!(offset_of!(MyStruct, c), MyStruct_field_offsets::c.get_byte_offset());