Skip to content

Fix #1571: For rust-target >= 1.30, make {__BindgenBitfieldUnit,__BindgenUnionField,__IncompleteArrayField}::new const fn #1573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/codegen/bitfield_unit.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
storage: Storage,
align: [Align; 0],
}

impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn new(storage: Storage) -> Self {
pub const fn new(storage: Storage) -> Self {
Self {
storage,
align: [],
}
}
}

impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
Expand Down
36 changes: 31 additions & 5 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ impl CodeGenerator for Module {
utils::prepend_objc_header(ctx, &mut *result);
}
if result.saw_bitfield_unit {
utils::prepend_bitfield_unit_type(&mut *result);
utils::prepend_bitfield_unit_type(ctx, &mut *result);
}
}
};
Expand Down Expand Up @@ -3591,11 +3591,21 @@ mod utils {
use ir::item::{Item, ItemCanonicalPath};
use ir::ty::TypeKind;
use proc_macro2;
use std::borrow::Cow;
use std::mem;
use std::str::FromStr;

pub fn prepend_bitfield_unit_type(result: &mut Vec<proc_macro2::TokenStream>) {
let bitfield_unit_type = proc_macro2::TokenStream::from_str(include_str!("./bitfield_unit.rs")).unwrap();
pub fn prepend_bitfield_unit_type(
ctx: &BindgenContext,
result: &mut Vec<proc_macro2::TokenStream>
) {
let bitfield_unit_src = include_str!("./bitfield_unit.rs");
let bitfield_unit_src = if ctx.options().rust_features().min_const_fn {
Cow::Borrowed(bitfield_unit_src)
} else {
Cow::Owned(bitfield_unit_src.replace("const fn ", "fn "))
};
let bitfield_unit_type = proc_macro2::TokenStream::from_str(&bitfield_unit_src).unwrap();
let bitfield_unit_type = quote!(#bitfield_unit_type);

let items = vec![bitfield_unit_type];
Expand Down Expand Up @@ -3653,6 +3663,14 @@ mod utils {
) {
let prefix = ctx.trait_prefix();

// If the target supports `const fn`, declare eligible functions
// as `const fn` else just `fn`.
let const_fn = if ctx.options().rust_features().min_const_fn {
quote!{ const fn }
} else {
quote!{ fn }
};

// TODO(emilio): The fmt::Debug impl could be way nicer with
// std::intrinsics::type_name, but...
let union_field_decl = quote! {
Expand All @@ -3663,7 +3681,7 @@ mod utils {
let union_field_impl = quote! {
impl<T> __BindgenUnionField<T> {
#[inline]
pub fn new() -> Self {
pub #const_fn new() -> Self {
__BindgenUnionField(::#prefix::marker::PhantomData)
}

Expand Down Expand Up @@ -3752,6 +3770,14 @@ mod utils {
) {
let prefix = ctx.trait_prefix();

// If the target supports `const fn`, declare eligible functions
// as `const fn` else just `fn`.
let const_fn = if ctx.options().rust_features().min_const_fn {
quote!{ const fn }
} else {
quote!{ fn }
};

let incomplete_array_decl = quote! {
#[repr(C)]
#[derive(Default)]
Expand All @@ -3762,7 +3788,7 @@ mod utils {
let incomplete_array_impl = quote! {
impl<T> __IncompleteArrayField<T> {
#[inline]
pub fn new() -> Self {
pub #const_fn new() -> Self {
__IncompleteArrayField(::#prefix::marker::PhantomData, [])
}

Expand Down
7 changes: 7 additions & 0 deletions src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ macro_rules! rust_target_base {
=> Stable_1_27 => 1.27;
/// Rust stable 1.28
=> Stable_1_28 => 1.28;
/// Rust stable 1.30
=> Stable_1_30 => 1.30;
/// Rust stable 1.33
=> Stable_1_33 => 1.33;
/// Nightly rust
Expand Down Expand Up @@ -192,6 +194,11 @@ rust_feature_def!(
/// repr(transparent) ([PR](https://github.com/rust-lang/rust/pull/51562))
=> repr_transparent;
}
Stable_1_30 {
/// `const fn` support for limited cases
/// ([PR](https://github.com/rust-lang/rust/pull/54835/)
=> min_const_fn;
}
Stable_1_33 {
/// repr(packed(N)) ([PR](https://github.com/rust-lang/rust/pull/57049))
=> repr_packed_n;
Expand Down
15 changes: 7 additions & 8 deletions tests/expectations/tests/bitfield-32bit-overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
pub struct __BindgenBitfieldUnit<Storage, Align> {
storage: Storage,
align: [Align; 0],
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align> {
#[inline]
pub const fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
#[inline]
pub fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
Expand Down
15 changes: 7 additions & 8 deletions tests/expectations/tests/bitfield-large.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
pub struct __BindgenBitfieldUnit<Storage, Align> {
storage: Storage,
align: [Align; 0],
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align> {
#[inline]
pub const fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
#[inline]
pub fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
Expand Down
15 changes: 7 additions & 8 deletions tests/expectations/tests/bitfield-method-same-name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
pub struct __BindgenBitfieldUnit<Storage, Align> {
storage: Storage,
align: [Align; 0],
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align> {
#[inline]
pub const fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
#[inline]
pub fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
Expand Down
15 changes: 7 additions & 8 deletions tests/expectations/tests/bitfield_align.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
pub struct __BindgenBitfieldUnit<Storage, Align> {
storage: Storage,
align: [Align; 0],
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align> {
#[inline]
pub const fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
#[inline]
pub fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
Expand Down
15 changes: 7 additions & 8 deletions tests/expectations/tests/bitfield_align_2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
pub struct __BindgenBitfieldUnit<Storage, Align> {
storage: Storage,
align: [Align; 0],
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align> {
#[inline]
pub const fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
#[inline]
pub fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
Expand Down
15 changes: 7 additions & 8 deletions tests/expectations/tests/bitfield_method_mangling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
pub struct __BindgenBitfieldUnit<Storage, Align> {
storage: Storage,
align: [Align; 0],
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align> {
#[inline]
pub const fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
#[inline]
pub fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
Expand Down
2 changes: 1 addition & 1 deletion tests/expectations/tests/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
impl<T> __IncompleteArrayField<T> {
#[inline]
pub fn new() -> Self {
pub const fn new() -> Self {
__IncompleteArrayField(::std::marker::PhantomData, [])
}
#[inline]
Expand Down
15 changes: 7 additions & 8 deletions tests/expectations/tests/derive-bitfield-method-same-name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
pub struct __BindgenBitfieldUnit<Storage, Align> {
storage: Storage,
align: [Align; 0],
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align> {
#[inline]
pub const fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
#[inline]
pub fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
Expand Down
15 changes: 7 additions & 8 deletions tests/expectations/tests/derive-debug-bitfield-core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,20 @@ extern crate core;

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
pub struct __BindgenBitfieldUnit<Storage, Align> {
storage: Storage,
align: [Align; 0],
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align> {
#[inline]
pub const fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
}
impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
where
Storage: AsRef<[u8]> + AsMut<[u8]>,
{
#[inline]
pub fn new(storage: Storage) -> Self {
Self { storage, align: [] }
}
#[inline]
pub fn get_bit(&self, index: usize) -> bool {
debug_assert!(index / 8 < self.storage.as_ref().len());
Expand Down
Loading