From 81f71ea9b0052410681e6f7128d4da04240a337b Mon Sep 17 00:00:00 2001 From: Hugo van der Wijst Date: Tue, 18 Oct 2022 22:23:39 -0700 Subject: [PATCH] Constify bitfield constructor for Rust 1.57+ --- bindgen-integration/src/lib.rs | 31 ++ .../tests/bitfield-32bit-overflow.rs | 348 +++++++++------ .../expectations/tests/bitfield-large.rs | 84 +++- .../expectations/tests/bitfield-linux-32.rs | 69 ++- .../tests/bitfield-method-same-name.rs | 62 ++- .../expectations/tests/bitfield_align.rs | 317 ++++++++----- .../expectations/tests/bitfield_align_2.rs | 69 ++- .../tests/bitfield_method_mangling.rs | 69 ++- .../tests/bitfield_pragma_packed.rs | 96 +++- .../tests/derive-bitfield-method-same-name.rs | 2 +- .../tests/derive-debug-bitfield-core.rs | 2 +- .../tests/derive-debug-bitfield.rs | 2 +- .../tests/derive-partialeq-bitfield.rs | 2 +- .../tests/divide-by-zero-in-struct-layout.rs | 59 ++- .../tests/incomplete-array-padding.rs | 60 ++- .../tests/expectations/tests/issue-1034.rs | 51 ++- .../issue-1076-unnamed-bitfield-alignment.rs | 51 ++- .../tests/expectations/tests/issue-1947.rs | 145 ++++-- .../tests/issue-739-pointer-wide-bitfield.rs | 88 +++- .../tests/expectations/tests/issue-816.rs | 420 +++++++++++------- .../expectations/tests/jsval_layout_opaque.rs | 70 ++- .../tests/jsval_layout_opaque_1_0.rs | 2 +- .../tests/expectations/tests/layout_align.rs | 84 +++- .../expectations/tests/layout_eth_conf.rs | 4 +- .../expectations/tests/layout_eth_conf_1_0.rs | 4 +- .../tests/expectations/tests/layout_mbuf.rs | 183 +++++--- .../expectations/tests/layout_mbuf_1_0.rs | 4 +- .../libclang-9/incomplete-array-padding.rs | 60 ++- .../tests/libclang-9/layout_align.rs | 84 +++- .../expectations/tests/only_bitfields.rs | 69 ++- .../expectations/tests/packed-bitfield.rs | 78 +++- .../expectations/tests/private_fields.rs | 113 +++-- .../tests/struct_with_bitfields.rs | 109 +++-- .../tests/expectations/tests/timex.rs | 47 ++ .../expectations/tests/union_bitfield.rs | 82 +++- .../expectations/tests/union_bitfield_1_0.rs | 4 +- .../tests/union_with_anon_struct_bitfield.rs | 69 ++- .../union_with_anon_struct_bitfield_1_0.rs | 2 +- .../expectations/tests/weird_bitfields.rs | 130 ++++-- bindgen/codegen/bitfield_unit_const.rs | 52 +++ bindgen/codegen/helpers.rs | 19 + bindgen/codegen/mod.rs | 52 ++- bindgen/features.rs | 6 + 43 files changed, 2498 insertions(+), 856 deletions(-) create mode 100644 bindgen/codegen/bitfield_unit_const.rs diff --git a/bindgen-integration/src/lib.rs b/bindgen-integration/src/lib.rs index 43f71580d2..9f84c9c0d7 100755 --- a/bindgen-integration/src/lib.rs +++ b/bindgen-integration/src/lib.rs @@ -199,6 +199,37 @@ fn test_bitfield_constructors() { }); } +#[test] +fn test_bitfield_const_constructors() { + use std::mem; + const FIRST: bindings::bitfields::First = bindings::bitfields::First { + _bitfield_align_1: [], + _bitfield_1: bindings::bitfields::First::new_bitfield_1(1, 2, 3), + }; + let mut first = FIRST; + assert!(unsafe { first.assert(1, 2, 3) }); + + const SECOND: bindings::bitfields::Second = bindings::bitfields::Second { + _bitfield_align_1: [], + _bitfield_1: bindings::bitfields::Second::new_bitfield_1(1337, true), + }; + let mut second = SECOND; + assert!(unsafe { second.assert(1337, true) }); + + const THIRD: bindings::bitfields::Third = bindings::bitfields::Third { + _bitfield_align_1: [], + _bitfield_1: bindings::bitfields::Third::new_bitfield_1( + 42, + false, + bindings::bitfields::ItemKind::ITEM_KIND_TRES, + ), + }; + let mut third = THIRD; + assert!(unsafe { + third.assert(42, false, bindings::bitfields::ItemKind::ITEM_KIND_TRES) + }); +} + impl Drop for bindings::AutoRestoreBool { fn drop(&mut self) { unsafe { bindings::AutoRestoreBool::destruct(self) } diff --git a/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs b/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs index 680b25d8fd..0ff0b17f31 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct MuchBitfield { @@ -541,7 +588,7 @@ impl MuchBitfield { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( m0: ::std::os::raw::c_char, m1: ::std::os::raw::c_char, m2: ::std::os::raw::c_char, @@ -577,139 +624,172 @@ impl MuchBitfield { m32: ::std::os::raw::c_char, ) -> __BindgenBitfieldUnit<[u8; 5usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 5usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let m0: u8 = unsafe { ::std::mem::transmute(m0) }; - m0 as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let m1: u8 = unsafe { ::std::mem::transmute(m1) }; - m1 as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let m2: u8 = unsafe { ::std::mem::transmute(m2) }; - m2 as u64 - }); - __bindgen_bitfield_unit.set(3usize, 1u8, { - let m3: u8 = unsafe { ::std::mem::transmute(m3) }; - m3 as u64 - }); - __bindgen_bitfield_unit.set(4usize, 1u8, { - let m4: u8 = unsafe { ::std::mem::transmute(m4) }; - m4 as u64 - }); - __bindgen_bitfield_unit.set(5usize, 1u8, { - let m5: u8 = unsafe { ::std::mem::transmute(m5) }; - m5 as u64 - }); - __bindgen_bitfield_unit.set(6usize, 1u8, { - let m6: u8 = unsafe { ::std::mem::transmute(m6) }; - m6 as u64 - }); - __bindgen_bitfield_unit.set(7usize, 1u8, { - let m7: u8 = unsafe { ::std::mem::transmute(m7) }; - m7 as u64 - }); - __bindgen_bitfield_unit.set(8usize, 1u8, { - let m8: u8 = unsafe { ::std::mem::transmute(m8) }; - m8 as u64 - }); - __bindgen_bitfield_unit.set(9usize, 1u8, { - let m9: u8 = unsafe { ::std::mem::transmute(m9) }; - m9 as u64 - }); - __bindgen_bitfield_unit.set(10usize, 1u8, { - let m10: u8 = unsafe { ::std::mem::transmute(m10) }; - m10 as u64 - }); - __bindgen_bitfield_unit.set(11usize, 1u8, { - let m11: u8 = unsafe { ::std::mem::transmute(m11) }; - m11 as u64 - }); - __bindgen_bitfield_unit.set(12usize, 1u8, { - let m12: u8 = unsafe { ::std::mem::transmute(m12) }; - m12 as u64 - }); - __bindgen_bitfield_unit.set(13usize, 1u8, { - let m13: u8 = unsafe { ::std::mem::transmute(m13) }; - m13 as u64 - }); - __bindgen_bitfield_unit.set(14usize, 1u8, { - let m14: u8 = unsafe { ::std::mem::transmute(m14) }; - m14 as u64 - }); - __bindgen_bitfield_unit.set(15usize, 1u8, { - let m15: u8 = unsafe { ::std::mem::transmute(m15) }; - m15 as u64 - }); - __bindgen_bitfield_unit.set(16usize, 1u8, { - let m16: u8 = unsafe { ::std::mem::transmute(m16) }; - m16 as u64 - }); - __bindgen_bitfield_unit.set(17usize, 1u8, { - let m17: u8 = unsafe { ::std::mem::transmute(m17) }; - m17 as u64 - }); - __bindgen_bitfield_unit.set(18usize, 1u8, { - let m18: u8 = unsafe { ::std::mem::transmute(m18) }; - m18 as u64 - }); - __bindgen_bitfield_unit.set(19usize, 1u8, { - let m19: u8 = unsafe { ::std::mem::transmute(m19) }; - m19 as u64 - }); - __bindgen_bitfield_unit.set(20usize, 1u8, { - let m20: u8 = unsafe { ::std::mem::transmute(m20) }; - m20 as u64 - }); - __bindgen_bitfield_unit.set(21usize, 1u8, { - let m21: u8 = unsafe { ::std::mem::transmute(m21) }; - m21 as u64 - }); - __bindgen_bitfield_unit.set(22usize, 1u8, { - let m22: u8 = unsafe { ::std::mem::transmute(m22) }; - m22 as u64 - }); - __bindgen_bitfield_unit.set(23usize, 1u8, { - let m23: u8 = unsafe { ::std::mem::transmute(m23) }; - m23 as u64 - }); - __bindgen_bitfield_unit.set(24usize, 1u8, { - let m24: u8 = unsafe { ::std::mem::transmute(m24) }; - m24 as u64 - }); - __bindgen_bitfield_unit.set(25usize, 1u8, { - let m25: u8 = unsafe { ::std::mem::transmute(m25) }; - m25 as u64 - }); - __bindgen_bitfield_unit.set(26usize, 1u8, { - let m26: u8 = unsafe { ::std::mem::transmute(m26) }; - m26 as u64 - }); - __bindgen_bitfield_unit.set(27usize, 1u8, { - let m27: u8 = unsafe { ::std::mem::transmute(m27) }; - m27 as u64 - }); - __bindgen_bitfield_unit.set(28usize, 1u8, { - let m28: u8 = unsafe { ::std::mem::transmute(m28) }; - m28 as u64 - }); - __bindgen_bitfield_unit.set(29usize, 1u8, { - let m29: u8 = unsafe { ::std::mem::transmute(m29) }; - m29 as u64 - }); - __bindgen_bitfield_unit.set(30usize, 1u8, { - let m30: u8 = unsafe { ::std::mem::transmute(m30) }; - m30 as u64 - }); - __bindgen_bitfield_unit.set(31usize, 1u8, { - let m31: u8 = unsafe { ::std::mem::transmute(m31) }; - m31 as u64 - }); - __bindgen_bitfield_unit.set(32usize, 1u8, { - let m32: u8 = unsafe { ::std::mem::transmute(m32) }; - m32 as u64 - }); + __BindgenBitfieldUnit::new([0; 5usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let m0: u8 = unsafe { ::std::mem::transmute(m0) }; + m0 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(1usize, 1u8, { + let m1: u8 = unsafe { ::std::mem::transmute(m1) }; + m1 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(2usize, 1u8, { + let m2: u8 = unsafe { ::std::mem::transmute(m2) }; + m2 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(3usize, 1u8, { + let m3: u8 = unsafe { ::std::mem::transmute(m3) }; + m3 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(4usize, 1u8, { + let m4: u8 = unsafe { ::std::mem::transmute(m4) }; + m4 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(5usize, 1u8, { + let m5: u8 = unsafe { ::std::mem::transmute(m5) }; + m5 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(6usize, 1u8, { + let m6: u8 = unsafe { ::std::mem::transmute(m6) }; + m6 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(7usize, 1u8, { + let m7: u8 = unsafe { ::std::mem::transmute(m7) }; + m7 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(8usize, 1u8, { + let m8: u8 = unsafe { ::std::mem::transmute(m8) }; + m8 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(9usize, 1u8, { + let m9: u8 = unsafe { ::std::mem::transmute(m9) }; + m9 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(10usize, 1u8, { + let m10: u8 = unsafe { ::std::mem::transmute(m10) }; + m10 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(11usize, 1u8, { + let m11: u8 = unsafe { ::std::mem::transmute(m11) }; + m11 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(12usize, 1u8, { + let m12: u8 = unsafe { ::std::mem::transmute(m12) }; + m12 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(13usize, 1u8, { + let m13: u8 = unsafe { ::std::mem::transmute(m13) }; + m13 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(14usize, 1u8, { + let m14: u8 = unsafe { ::std::mem::transmute(m14) }; + m14 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(15usize, 1u8, { + let m15: u8 = unsafe { ::std::mem::transmute(m15) }; + m15 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(16usize, 1u8, { + let m16: u8 = unsafe { ::std::mem::transmute(m16) }; + m16 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(17usize, 1u8, { + let m17: u8 = unsafe { ::std::mem::transmute(m17) }; + m17 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(18usize, 1u8, { + let m18: u8 = unsafe { ::std::mem::transmute(m18) }; + m18 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(19usize, 1u8, { + let m19: u8 = unsafe { ::std::mem::transmute(m19) }; + m19 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(20usize, 1u8, { + let m20: u8 = unsafe { ::std::mem::transmute(m20) }; + m20 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(21usize, 1u8, { + let m21: u8 = unsafe { ::std::mem::transmute(m21) }; + m21 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(22usize, 1u8, { + let m22: u8 = unsafe { ::std::mem::transmute(m22) }; + m22 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(23usize, 1u8, { + let m23: u8 = unsafe { ::std::mem::transmute(m23) }; + m23 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(24usize, 1u8, { + let m24: u8 = unsafe { ::std::mem::transmute(m24) }; + m24 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(25usize, 1u8, { + let m25: u8 = unsafe { ::std::mem::transmute(m25) }; + m25 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(26usize, 1u8, { + let m26: u8 = unsafe { ::std::mem::transmute(m26) }; + m26 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(27usize, 1u8, { + let m27: u8 = unsafe { ::std::mem::transmute(m27) }; + m27 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(28usize, 1u8, { + let m28: u8 = unsafe { ::std::mem::transmute(m28) }; + m28 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(29usize, 1u8, { + let m29: u8 = unsafe { ::std::mem::transmute(m29) }; + m29 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(30usize, 1u8, { + let m30: u8 = unsafe { ::std::mem::transmute(m30) }; + m30 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(31usize, 1u8, { + let m31: u8 = unsafe { ::std::mem::transmute(m31) }; + m31 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(32usize, 1u8, { + let m32: u8 = unsafe { ::std::mem::transmute(m32) }; + m32 as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/bitfield-large.rs b/bindgen-tests/tests/expectations/tests/bitfield-large.rs index b2c353a221..37fb478c04 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-large.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-large.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[repr(align(16))] #[derive(Debug, Default, Copy, Clone)] @@ -126,13 +173,16 @@ impl HasBigBitfield { } } #[inline] - pub fn new_bitfield_1(x: i128) -> __BindgenBitfieldUnit<[u8; 16usize]> { + pub const fn new_bitfield_1( + x: i128, + ) -> __BindgenBitfieldUnit<[u8; 16usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 16usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 128u8, { - let x: u128 = unsafe { ::std::mem::transmute(x) }; - x as u64 - }); + __BindgenBitfieldUnit::new([0; 16usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 128u8, { + let x: u128 = unsafe { ::std::mem::transmute(x) }; + x as u64 + }); __bindgen_bitfield_unit } } @@ -184,20 +234,22 @@ impl HasTwoBigBitfields { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( x: i128, y: i128, ) -> __BindgenBitfieldUnit<[u8; 16usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 16usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 80u8, { - let x: u128 = unsafe { ::std::mem::transmute(x) }; - x as u64 - }); - __bindgen_bitfield_unit.set(80usize, 48u8, { - let y: u128 = unsafe { ::std::mem::transmute(y) }; - y as u64 - }); + __BindgenBitfieldUnit::new([0; 16usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 80u8, { + let x: u128 = unsafe { ::std::mem::transmute(x) }; + x as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(80usize, 48u8, { + let y: u128 = unsafe { ::std::mem::transmute(y) }; + y as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs b/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs index 44c686265f..73e157b073 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C, packed(4))] #[derive(Debug, Default, Copy, Clone)] pub struct Test { @@ -147,20 +194,22 @@ impl Test { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( x: u64, y: u64, ) -> __BindgenBitfieldUnit<[u8; 8usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 56u8, { - let x: u64 = unsafe { ::std::mem::transmute(x) }; - x as u64 - }); - __bindgen_bitfield_unit.set(56usize, 8u8, { - let y: u64 = unsafe { ::std::mem::transmute(y) }; - y as u64 - }); + __BindgenBitfieldUnit::new([0; 8usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 56u8, { + let x: u64 = unsafe { ::std::mem::transmute(x) }; + x as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(56usize, 8u8, { + let y: u64 = unsafe { ::std::mem::transmute(y) }; + y as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs b/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs index e9c1a76d1c..820c8573fe 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct Foo { @@ -137,16 +184,17 @@ impl Foo { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( type__bindgen_bitfield: ::std::os::raw::c_char, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 3u8, { - let type__bindgen_bitfield: u8 = - unsafe { ::std::mem::transmute(type__bindgen_bitfield) }; - type__bindgen_bitfield as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 3u8, { + let type__bindgen_bitfield: u8 = + unsafe { ::std::mem::transmute(type__bindgen_bitfield) }; + type__bindgen_bitfield as u64 + }); __bindgen_bitfield_unit } #[inline] diff --git a/bindgen-tests/tests/expectations/tests/bitfield_align.rs b/bindgen-tests/tests/expectations/tests/bitfield_align.rs index 4baca11214..b13ed46e41 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_align.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_align.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] @@ -258,7 +305,7 @@ impl A { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( b1: ::std::os::raw::c_uint, b2: ::std::os::raw::c_uint, b3: ::std::os::raw::c_uint, @@ -271,47 +318,57 @@ impl A { b10: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 2usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let b1: u32 = unsafe { ::std::mem::transmute(b1) }; - b1 as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let b2: u32 = unsafe { ::std::mem::transmute(b2) }; - b2 as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let b3: u32 = unsafe { ::std::mem::transmute(b3) }; - b3 as u64 - }); - __bindgen_bitfield_unit.set(3usize, 1u8, { - let b4: u32 = unsafe { ::std::mem::transmute(b4) }; - b4 as u64 - }); - __bindgen_bitfield_unit.set(4usize, 1u8, { - let b5: u32 = unsafe { ::std::mem::transmute(b5) }; - b5 as u64 - }); - __bindgen_bitfield_unit.set(5usize, 1u8, { - let b6: u32 = unsafe { ::std::mem::transmute(b6) }; - b6 as u64 - }); - __bindgen_bitfield_unit.set(6usize, 1u8, { - let b7: u32 = unsafe { ::std::mem::transmute(b7) }; - b7 as u64 - }); - __bindgen_bitfield_unit.set(7usize, 1u8, { - let b8: u32 = unsafe { ::std::mem::transmute(b8) }; - b8 as u64 - }); - __bindgen_bitfield_unit.set(8usize, 1u8, { - let b9: u32 = unsafe { ::std::mem::transmute(b9) }; - b9 as u64 - }); - __bindgen_bitfield_unit.set(9usize, 1u8, { - let b10: u32 = unsafe { ::std::mem::transmute(b10) }; - b10 as u64 - }); + __BindgenBitfieldUnit::new([0; 2usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let b1: u32 = unsafe { ::std::mem::transmute(b1) }; + b1 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(1usize, 1u8, { + let b2: u32 = unsafe { ::std::mem::transmute(b2) }; + b2 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(2usize, 1u8, { + let b3: u32 = unsafe { ::std::mem::transmute(b3) }; + b3 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(3usize, 1u8, { + let b4: u32 = unsafe { ::std::mem::transmute(b4) }; + b4 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(4usize, 1u8, { + let b5: u32 = unsafe { ::std::mem::transmute(b5) }; + b5 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(5usize, 1u8, { + let b6: u32 = unsafe { ::std::mem::transmute(b6) }; + b6 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(6usize, 1u8, { + let b7: u32 = unsafe { ::std::mem::transmute(b7) }; + b7 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(7usize, 1u8, { + let b8: u32 = unsafe { ::std::mem::transmute(b8) }; + b8 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(8usize, 1u8, { + let b9: u32 = unsafe { ::std::mem::transmute(b9) }; + b9 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(9usize, 1u8, { + let b10: u32 = unsafe { ::std::mem::transmute(b10) }; + b10 as u64 + }); __bindgen_bitfield_unit } } @@ -363,20 +420,22 @@ impl B { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( foo: ::std::os::raw::c_uint, bar: ::std::os::raw::c_uchar, ) -> __BindgenBitfieldUnit<[u8; 4usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 31u8, { - let foo: u32 = unsafe { ::std::mem::transmute(foo) }; - foo as u64 - }); - __bindgen_bitfield_unit.set(31usize, 1u8, { - let bar: u8 = unsafe { ::std::mem::transmute(bar) }; - bar as u64 - }); + __BindgenBitfieldUnit::new([0; 4usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 31u8, { + let foo: u32 = unsafe { ::std::mem::transmute(foo) }; + foo as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(31usize, 1u8, { + let bar: u8 = unsafe { ::std::mem::transmute(bar) }; + bar as u64 + }); __bindgen_bitfield_unit } } @@ -442,20 +501,22 @@ impl C { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( b1: ::std::os::raw::c_uint, b2: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let b1: u32 = unsafe { ::std::mem::transmute(b1) }; - b1 as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let b2: u32 = unsafe { ::std::mem::transmute(b2) }; - b2 as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let b1: u32 = unsafe { ::std::mem::transmute(b1) }; + b1 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(1usize, 1u8, { + let b2: u32 = unsafe { ::std::mem::transmute(b2) }; + b2 as u64 + }); __bindgen_bitfield_unit } } @@ -534,30 +595,35 @@ impl Date1 { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( nWeekDay: ::std::os::raw::c_ushort, nMonthDay: ::std::os::raw::c_ushort, nMonth: ::std::os::raw::c_ushort, nYear: ::std::os::raw::c_ushort, ) -> __BindgenBitfieldUnit<[u8; 3usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 3u8, { - let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; - nWeekDay as u64 - }); - __bindgen_bitfield_unit.set(3usize, 6u8, { - let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; - nMonthDay as u64 - }); - __bindgen_bitfield_unit.set(9usize, 5u8, { - let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; - nMonth as u64 - }); - __bindgen_bitfield_unit.set(16usize, 8u8, { - let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; - nYear as u64 - }); + __BindgenBitfieldUnit::new([0; 3usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 3u8, { + let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; + nWeekDay as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(3usize, 6u8, { + let nMonthDay: u16 = + unsafe { ::std::mem::transmute(nMonthDay) }; + nMonthDay as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(9usize, 5u8, { + let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; + nMonth as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(16usize, 8u8, { + let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; + nYear as u64 + }); __bindgen_bitfield_unit } } @@ -648,7 +714,7 @@ impl Date2 { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( nWeekDay: ::std::os::raw::c_ushort, nMonthDay: ::std::os::raw::c_ushort, nMonth: ::std::os::raw::c_ushort, @@ -656,27 +722,33 @@ impl Date2 { byte: ::std::os::raw::c_uchar, ) -> __BindgenBitfieldUnit<[u8; 4usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 3u8, { - let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; - nWeekDay as u64 - }); - __bindgen_bitfield_unit.set(3usize, 6u8, { - let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; - nMonthDay as u64 - }); - __bindgen_bitfield_unit.set(9usize, 5u8, { - let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; - nMonth as u64 - }); - __bindgen_bitfield_unit.set(16usize, 8u8, { - let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; - nYear as u64 - }); - __bindgen_bitfield_unit.set(24usize, 8u8, { - let byte: u8 = unsafe { ::std::mem::transmute(byte) }; - byte as u64 - }); + __BindgenBitfieldUnit::new([0; 4usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 3u8, { + let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; + nWeekDay as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(3usize, 6u8, { + let nMonthDay: u16 = + unsafe { ::std::mem::transmute(nMonthDay) }; + nMonthDay as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(9usize, 5u8, { + let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; + nMonth as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(16usize, 8u8, { + let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; + nYear as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(24usize, 8u8, { + let byte: u8 = unsafe { ::std::mem::transmute(byte) }; + byte as u64 + }); __bindgen_bitfield_unit } } @@ -768,30 +840,35 @@ impl Date3 { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( nWeekDay: ::std::os::raw::c_ushort, nMonthDay: ::std::os::raw::c_ushort, nMonth: ::std::os::raw::c_ushort, nYear: ::std::os::raw::c_ushort, ) -> __BindgenBitfieldUnit<[u8; 3usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 3u8, { - let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; - nWeekDay as u64 - }); - __bindgen_bitfield_unit.set(3usize, 6u8, { - let nMonthDay: u16 = unsafe { ::std::mem::transmute(nMonthDay) }; - nMonthDay as u64 - }); - __bindgen_bitfield_unit.set(9usize, 5u8, { - let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; - nMonth as u64 - }); - __bindgen_bitfield_unit.set(16usize, 8u8, { - let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; - nYear as u64 - }); + __BindgenBitfieldUnit::new([0; 3usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 3u8, { + let nWeekDay: u16 = unsafe { ::std::mem::transmute(nWeekDay) }; + nWeekDay as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(3usize, 6u8, { + let nMonthDay: u16 = + unsafe { ::std::mem::transmute(nMonthDay) }; + nMonthDay as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(9usize, 5u8, { + let nMonth: u16 = unsafe { ::std::mem::transmute(nMonth) }; + nMonth as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(16usize, 8u8, { + let nYear: u16 = unsafe { ::std::mem::transmute(nYear) }; + nYear as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs b/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs index aa11f80c51..5d5e4c0488 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs @@ -92,6 +92,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum MyEnum { @@ -157,20 +204,22 @@ impl TaggedPtr { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( tag: MyEnum, ptr: ::std::os::raw::c_long, ) -> __BindgenBitfieldUnit<[u8; 8usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 2u8, { - let tag: u32 = unsafe { ::std::mem::transmute(tag) }; - tag as u64 - }); - __bindgen_bitfield_unit.set(2usize, 62u8, { - let ptr: u64 = unsafe { ::std::mem::transmute(ptr) }; - ptr as u64 - }); + __BindgenBitfieldUnit::new([0; 8usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 2u8, { + let tag: u32 = unsafe { ::std::mem::transmute(tag) }; + tag as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(2usize, 62u8, { + let ptr: u64 = unsafe { ::std::mem::transmute(ptr) }; + ptr as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs b/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs index 42fa3c4cb4..a4ae3194d7 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] @@ -139,20 +186,22 @@ impl mach_msg_type_descriptor_t { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( pad3: ::std::os::raw::c_uint, type_: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 4usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 24u8, { - let pad3: u32 = unsafe { ::std::mem::transmute(pad3) }; - pad3 as u64 - }); - __bindgen_bitfield_unit.set(24usize, 8u8, { - let type_: u32 = unsafe { ::std::mem::transmute(type_) }; - type_ as u64 - }); + __BindgenBitfieldUnit::new([0; 4usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 24u8, { + let pad3: u32 = unsafe { ::std::mem::transmute(pad3) }; + pad3 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(24usize, 8u8, { + let type_: u32 = unsafe { ::std::mem::transmute(type_) }; + type_ as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs index 27cd90f140..db7d1e0171 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct Struct { @@ -177,7 +224,7 @@ impl Struct { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( a: ::std::os::raw::c_uchar, b: ::std::os::raw::c_uchar, c: ::std::os::raw::c_uchar, @@ -185,27 +232,32 @@ impl Struct { e: ::std::os::raw::c_uchar, ) -> __BindgenBitfieldUnit<[u8; 4usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let a: u8 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let b: u8 = unsafe { ::std::mem::transmute(b) }; - b as u64 - }); - __bindgen_bitfield_unit.set(2usize, 6u8, { - let c: u8 = unsafe { ::std::mem::transmute(c) }; - c as u64 - }); - __bindgen_bitfield_unit.set(8usize, 16u8, { - let d: u16 = unsafe { ::std::mem::transmute(d) }; - d as u64 - }); - __bindgen_bitfield_unit.set(24usize, 8u8, { - let e: u8 = unsafe { ::std::mem::transmute(e) }; - e as u64 - }); + __BindgenBitfieldUnit::new([0; 4usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let a: u8 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(1usize, 1u8, { + let b: u8 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(2usize, 6u8, { + let c: u8 = unsafe { ::std::mem::transmute(c) }; + c as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(8usize, 16u8, { + let d: u16 = unsafe { ::std::mem::transmute(d) }; + d as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(24usize, 8u8, { + let e: u8 = unsafe { ::std::mem::transmute(e) }; + e as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs b/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs index ea6621dd1c..725efab766 100644 --- a/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs +++ b/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs @@ -192,7 +192,7 @@ impl Foo { type__bindgen_bitfield: ::std::os::raw::c_char, ) -> __BindgenBitfieldUnit<[u8; 2usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 2usize]); __bindgen_bitfield_unit.set(0usize, 3u8, { let type__bindgen_bitfield: u8 = unsafe { ::std::mem::transmute(type__bindgen_bitfield) }; diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs index 2a78e93050..e36d9261b0 100644 --- a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs +++ b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs @@ -180,7 +180,7 @@ impl C { b: bool, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 1usize]); __bindgen_bitfield_unit.set(0usize, 1u8, { let a: u8 = unsafe { ::core::mem::transmute(a) }; a as u64 diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs index 0ae8f32968..2766b42e0a 100644 --- a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs @@ -187,7 +187,7 @@ impl C { b: bool, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 1usize]); __bindgen_bitfield_unit.set(0usize, 1u8, { let a: u8 = unsafe { ::std::mem::transmute(a) }; a as u64 diff --git a/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs index cb9781dea6..b3b1105839 100644 --- a/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs @@ -175,7 +175,7 @@ impl C { b: bool, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 1usize]); __bindgen_bitfield_unit.set(0usize, 1u8, { let a: u8 = unsafe { ::std::mem::transmute(a) }; a as u64 diff --git a/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs b/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs index 721d71e259..1c57640791 100644 --- a/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs +++ b/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct WithBitfield { @@ -100,9 +147,9 @@ pub struct WithBitfield { } impl WithBitfield { #[inline] - pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { + pub const fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 1usize]); __bindgen_bitfield_unit } } @@ -115,9 +162,9 @@ pub struct WithBitfieldAndAttrPacked { } impl WithBitfieldAndAttrPacked { #[inline] - pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { + pub const fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 1usize]); __bindgen_bitfield_unit } } @@ -130,9 +177,9 @@ pub struct WithBitfieldAndPacked { } impl WithBitfieldAndPacked { #[inline] - pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { + pub const fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 1usize]); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs b/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs index 18061ea12a..5f66dc47b3 100644 --- a/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs +++ b/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[derive(Default)] pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); @@ -165,15 +212,16 @@ impl foo { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( a: ::std::os::raw::c_char, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let a: u8 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let a: u8 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/issue-1034.rs b/bindgen-tests/tests/expectations/tests/issue-1034.rs index 32f4310e49..3cfdda52cd 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1034.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1034.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct S2 { @@ -112,9 +159,9 @@ fn bindgen_test_layout_S2() { } impl S2 { #[inline] - pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 2usize]> { + pub const fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 2usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 2usize]); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs b/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs index d91dd8fa5c..859f7b1fc3 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct S1 { @@ -112,9 +159,9 @@ fn bindgen_test_layout_S1() { } impl S1 { #[inline] - pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 3usize]> { + pub const fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 3usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 3usize]); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/issue-1947.rs b/bindgen-tests/tests/expectations/tests/issue-1947.rs index e133ed85ba..98afb33759 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1947.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1947.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} pub type U8 = ::std::os::raw::c_uchar; pub type U16 = ::std::os::raw::c_ushort; #[repr(C)] @@ -205,30 +252,34 @@ impl V56AMDY { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( MADZ: U16, MAI0: U16, MAI1: U16, MAI2: U16, ) -> __BindgenBitfieldUnit<[u8; 2usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 10u8, { - let MADZ: u16 = unsafe { ::std::mem::transmute(MADZ) }; - MADZ as u64 - }); - __bindgen_bitfield_unit.set(10usize, 2u8, { - let MAI0: u16 = unsafe { ::std::mem::transmute(MAI0) }; - MAI0 as u64 - }); - __bindgen_bitfield_unit.set(12usize, 2u8, { - let MAI1: u16 = unsafe { ::std::mem::transmute(MAI1) }; - MAI1 as u64 - }); - __bindgen_bitfield_unit.set(14usize, 2u8, { - let MAI2: u16 = unsafe { ::std::mem::transmute(MAI2) }; - MAI2 as u64 - }); + __BindgenBitfieldUnit::new([0; 2usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 10u8, { + let MADZ: u16 = unsafe { ::std::mem::transmute(MADZ) }; + MADZ as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(10usize, 2u8, { + let MAI0: u16 = unsafe { ::std::mem::transmute(MAI0) }; + MAI0 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(12usize, 2u8, { + let MAI1: u16 = unsafe { ::std::mem::transmute(MAI1) }; + MAI1 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(14usize, 2u8, { + let MAI2: u16 = unsafe { ::std::mem::transmute(MAI2) }; + MAI2 as u64 + }); __bindgen_bitfield_unit } #[inline] @@ -310,7 +361,7 @@ impl V56AMDY { } } #[inline] - pub fn new_bitfield_2( + pub const fn new_bitfield_2( MATH: U16, MATE: U16, MATW: U16, @@ -319,31 +370,37 @@ impl V56AMDY { MAXN: U8, ) -> __BindgenBitfieldUnit<[u8; 3usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 10u8, { - let MATH: u16 = unsafe { ::std::mem::transmute(MATH) }; - MATH as u64 - }); - __bindgen_bitfield_unit.set(10usize, 4u8, { - let MATE: u16 = unsafe { ::std::mem::transmute(MATE) }; - MATE as u64 - }); - __bindgen_bitfield_unit.set(14usize, 2u8, { - let MATW: u16 = unsafe { ::std::mem::transmute(MATW) }; - MATW as u64 - }); - __bindgen_bitfield_unit.set(16usize, 4u8, { - let MASW: u8 = unsafe { ::std::mem::transmute(MASW) }; - MASW as u64 - }); - __bindgen_bitfield_unit.set(20usize, 3u8, { - let MABW: u8 = unsafe { ::std::mem::transmute(MABW) }; - MABW as u64 - }); - __bindgen_bitfield_unit.set(23usize, 1u8, { - let MAXN: u8 = unsafe { ::std::mem::transmute(MAXN) }; - MAXN as u64 - }); + __BindgenBitfieldUnit::new([0; 3usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 10u8, { + let MATH: u16 = unsafe { ::std::mem::transmute(MATH) }; + MATH as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(10usize, 4u8, { + let MATE: u16 = unsafe { ::std::mem::transmute(MATE) }; + MATE as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(14usize, 2u8, { + let MATW: u16 = unsafe { ::std::mem::transmute(MATW) }; + MATW as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(16usize, 4u8, { + let MASW: u8 = unsafe { ::std::mem::transmute(MASW) }; + MASW as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(20usize, 3u8, { + let MABW: u8 = unsafe { ::std::mem::transmute(MABW) }; + MABW as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(23usize, 1u8, { + let MAXN: u8 = unsafe { ::std::mem::transmute(MAXN) }; + MAXN as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs b/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs index 1a633844f2..0edb299306 100644 --- a/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs @@ -92,6 +92,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[repr(align(8))] #[derive(Debug, Default, Copy, Clone)] @@ -166,30 +213,35 @@ impl Foo { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( m_bitfield: ::std::os::raw::c_ulong, m_bar: ::std::os::raw::c_ulong, foo: ::std::os::raw::c_ulong, bar: ::std::os::raw::c_ulong, ) -> __BindgenBitfieldUnit<[u8; 32usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 32usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 64u8, { - let m_bitfield: u64 = unsafe { ::std::mem::transmute(m_bitfield) }; - m_bitfield as u64 - }); - __bindgen_bitfield_unit.set(64usize, 64u8, { - let m_bar: u64 = unsafe { ::std::mem::transmute(m_bar) }; - m_bar as u64 - }); - __bindgen_bitfield_unit.set(128usize, 1u8, { - let foo: u64 = unsafe { ::std::mem::transmute(foo) }; - foo as u64 - }); - __bindgen_bitfield_unit.set(192usize, 64u8, { - let bar: u64 = unsafe { ::std::mem::transmute(bar) }; - bar as u64 - }); + __BindgenBitfieldUnit::new([0; 32usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 64u8, { + let m_bitfield: u64 = + unsafe { ::std::mem::transmute(m_bitfield) }; + m_bitfield as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(64usize, 64u8, { + let m_bar: u64 = unsafe { ::std::mem::transmute(m_bar) }; + m_bar as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(128usize, 1u8, { + let foo: u64 = unsafe { ::std::mem::transmute(foo) }; + foo as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(192usize, 64u8, { + let bar: u64 = unsafe { ::std::mem::transmute(bar) }; + bar as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/issue-816.rs b/bindgen-tests/tests/expectations/tests/issue-816.rs index c7f94106f4..1881e9899a 100644 --- a/bindgen-tests/tests/expectations/tests/issue-816.rs +++ b/bindgen-tests/tests/expectations/tests/issue-816.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] @@ -646,7 +693,7 @@ impl capabilities { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( bit_1: ::std::os::raw::c_uint, bit_2: ::std::os::raw::c_uint, bit_3: ::std::os::raw::c_uint, @@ -690,171 +737,212 @@ impl capabilities { bit_41: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 16usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 16usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let bit_1: u32 = unsafe { ::std::mem::transmute(bit_1) }; - bit_1 as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let bit_2: u32 = unsafe { ::std::mem::transmute(bit_2) }; - bit_2 as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let bit_3: u32 = unsafe { ::std::mem::transmute(bit_3) }; - bit_3 as u64 - }); - __bindgen_bitfield_unit.set(3usize, 1u8, { - let bit_4: u32 = unsafe { ::std::mem::transmute(bit_4) }; - bit_4 as u64 - }); - __bindgen_bitfield_unit.set(4usize, 1u8, { - let bit_5: u32 = unsafe { ::std::mem::transmute(bit_5) }; - bit_5 as u64 - }); - __bindgen_bitfield_unit.set(5usize, 1u8, { - let bit_6: u32 = unsafe { ::std::mem::transmute(bit_6) }; - bit_6 as u64 - }); - __bindgen_bitfield_unit.set(6usize, 1u8, { - let bit_7: u32 = unsafe { ::std::mem::transmute(bit_7) }; - bit_7 as u64 - }); - __bindgen_bitfield_unit.set(7usize, 1u8, { - let bit_8: u32 = unsafe { ::std::mem::transmute(bit_8) }; - bit_8 as u64 - }); - __bindgen_bitfield_unit.set(8usize, 1u8, { - let bit_9: u32 = unsafe { ::std::mem::transmute(bit_9) }; - bit_9 as u64 - }); - __bindgen_bitfield_unit.set(9usize, 1u8, { - let bit_10: u32 = unsafe { ::std::mem::transmute(bit_10) }; - bit_10 as u64 - }); - __bindgen_bitfield_unit.set(10usize, 1u8, { - let bit_11: u32 = unsafe { ::std::mem::transmute(bit_11) }; - bit_11 as u64 - }); - __bindgen_bitfield_unit.set(11usize, 1u8, { - let bit_12: u32 = unsafe { ::std::mem::transmute(bit_12) }; - bit_12 as u64 - }); - __bindgen_bitfield_unit.set(12usize, 1u8, { - let bit_13: u32 = unsafe { ::std::mem::transmute(bit_13) }; - bit_13 as u64 - }); - __bindgen_bitfield_unit.set(13usize, 1u8, { - let bit_14: u32 = unsafe { ::std::mem::transmute(bit_14) }; - bit_14 as u64 - }); - __bindgen_bitfield_unit.set(14usize, 1u8, { - let bit_15: u32 = unsafe { ::std::mem::transmute(bit_15) }; - bit_15 as u64 - }); - __bindgen_bitfield_unit.set(15usize, 1u8, { - let bit_16: u32 = unsafe { ::std::mem::transmute(bit_16) }; - bit_16 as u64 - }); - __bindgen_bitfield_unit.set(16usize, 1u8, { - let bit_17: u32 = unsafe { ::std::mem::transmute(bit_17) }; - bit_17 as u64 - }); - __bindgen_bitfield_unit.set(17usize, 1u8, { - let bit_18: u32 = unsafe { ::std::mem::transmute(bit_18) }; - bit_18 as u64 - }); - __bindgen_bitfield_unit.set(18usize, 1u8, { - let bit_19: u32 = unsafe { ::std::mem::transmute(bit_19) }; - bit_19 as u64 - }); - __bindgen_bitfield_unit.set(19usize, 1u8, { - let bit_20: u32 = unsafe { ::std::mem::transmute(bit_20) }; - bit_20 as u64 - }); - __bindgen_bitfield_unit.set(20usize, 1u8, { - let bit_21: u32 = unsafe { ::std::mem::transmute(bit_21) }; - bit_21 as u64 - }); - __bindgen_bitfield_unit.set(21usize, 1u8, { - let bit_22: u32 = unsafe { ::std::mem::transmute(bit_22) }; - bit_22 as u64 - }); - __bindgen_bitfield_unit.set(22usize, 1u8, { - let bit_23: u32 = unsafe { ::std::mem::transmute(bit_23) }; - bit_23 as u64 - }); - __bindgen_bitfield_unit.set(23usize, 1u8, { - let bit_24: u32 = unsafe { ::std::mem::transmute(bit_24) }; - bit_24 as u64 - }); - __bindgen_bitfield_unit.set(24usize, 1u8, { - let bit_25: u32 = unsafe { ::std::mem::transmute(bit_25) }; - bit_25 as u64 - }); - __bindgen_bitfield_unit.set(25usize, 1u8, { - let bit_26: u32 = unsafe { ::std::mem::transmute(bit_26) }; - bit_26 as u64 - }); - __bindgen_bitfield_unit.set(26usize, 1u8, { - let bit_27: u32 = unsafe { ::std::mem::transmute(bit_27) }; - bit_27 as u64 - }); - __bindgen_bitfield_unit.set(27usize, 1u8, { - let bit_28: u32 = unsafe { ::std::mem::transmute(bit_28) }; - bit_28 as u64 - }); - __bindgen_bitfield_unit.set(28usize, 1u8, { - let bit_29: u32 = unsafe { ::std::mem::transmute(bit_29) }; - bit_29 as u64 - }); - __bindgen_bitfield_unit.set(29usize, 1u8, { - let bit_30: u32 = unsafe { ::std::mem::transmute(bit_30) }; - bit_30 as u64 - }); - __bindgen_bitfield_unit.set(30usize, 1u8, { - let bit_31: u32 = unsafe { ::std::mem::transmute(bit_31) }; - bit_31 as u64 - }); - __bindgen_bitfield_unit.set(31usize, 1u8, { - let bit_32: u32 = unsafe { ::std::mem::transmute(bit_32) }; - bit_32 as u64 - }); - __bindgen_bitfield_unit.set(32usize, 1u8, { - let bit_33: u32 = unsafe { ::std::mem::transmute(bit_33) }; - bit_33 as u64 - }); - __bindgen_bitfield_unit.set(33usize, 1u8, { - let bit_34: u32 = unsafe { ::std::mem::transmute(bit_34) }; - bit_34 as u64 - }); - __bindgen_bitfield_unit.set(34usize, 1u8, { - let bit_35: u32 = unsafe { ::std::mem::transmute(bit_35) }; - bit_35 as u64 - }); - __bindgen_bitfield_unit.set(35usize, 1u8, { - let bit_36: u32 = unsafe { ::std::mem::transmute(bit_36) }; - bit_36 as u64 - }); - __bindgen_bitfield_unit.set(36usize, 1u8, { - let bit_37: u32 = unsafe { ::std::mem::transmute(bit_37) }; - bit_37 as u64 - }); - __bindgen_bitfield_unit.set(37usize, 1u8, { - let bit_38: u32 = unsafe { ::std::mem::transmute(bit_38) }; - bit_38 as u64 - }); - __bindgen_bitfield_unit.set(38usize, 1u8, { - let bit_39: u32 = unsafe { ::std::mem::transmute(bit_39) }; - bit_39 as u64 - }); - __bindgen_bitfield_unit.set(39usize, 1u8, { - let bit_40: u32 = unsafe { ::std::mem::transmute(bit_40) }; - bit_40 as u64 - }); - __bindgen_bitfield_unit.set(40usize, 1u8, { - let bit_41: u32 = unsafe { ::std::mem::transmute(bit_41) }; - bit_41 as u64 - }); + __BindgenBitfieldUnit::new([0; 16usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let bit_1: u32 = unsafe { ::std::mem::transmute(bit_1) }; + bit_1 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(1usize, 1u8, { + let bit_2: u32 = unsafe { ::std::mem::transmute(bit_2) }; + bit_2 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(2usize, 1u8, { + let bit_3: u32 = unsafe { ::std::mem::transmute(bit_3) }; + bit_3 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(3usize, 1u8, { + let bit_4: u32 = unsafe { ::std::mem::transmute(bit_4) }; + bit_4 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(4usize, 1u8, { + let bit_5: u32 = unsafe { ::std::mem::transmute(bit_5) }; + bit_5 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(5usize, 1u8, { + let bit_6: u32 = unsafe { ::std::mem::transmute(bit_6) }; + bit_6 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(6usize, 1u8, { + let bit_7: u32 = unsafe { ::std::mem::transmute(bit_7) }; + bit_7 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(7usize, 1u8, { + let bit_8: u32 = unsafe { ::std::mem::transmute(bit_8) }; + bit_8 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(8usize, 1u8, { + let bit_9: u32 = unsafe { ::std::mem::transmute(bit_9) }; + bit_9 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(9usize, 1u8, { + let bit_10: u32 = unsafe { ::std::mem::transmute(bit_10) }; + bit_10 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(10usize, 1u8, { + let bit_11: u32 = unsafe { ::std::mem::transmute(bit_11) }; + bit_11 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(11usize, 1u8, { + let bit_12: u32 = unsafe { ::std::mem::transmute(bit_12) }; + bit_12 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(12usize, 1u8, { + let bit_13: u32 = unsafe { ::std::mem::transmute(bit_13) }; + bit_13 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(13usize, 1u8, { + let bit_14: u32 = unsafe { ::std::mem::transmute(bit_14) }; + bit_14 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(14usize, 1u8, { + let bit_15: u32 = unsafe { ::std::mem::transmute(bit_15) }; + bit_15 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(15usize, 1u8, { + let bit_16: u32 = unsafe { ::std::mem::transmute(bit_16) }; + bit_16 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(16usize, 1u8, { + let bit_17: u32 = unsafe { ::std::mem::transmute(bit_17) }; + bit_17 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(17usize, 1u8, { + let bit_18: u32 = unsafe { ::std::mem::transmute(bit_18) }; + bit_18 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(18usize, 1u8, { + let bit_19: u32 = unsafe { ::std::mem::transmute(bit_19) }; + bit_19 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(19usize, 1u8, { + let bit_20: u32 = unsafe { ::std::mem::transmute(bit_20) }; + bit_20 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(20usize, 1u8, { + let bit_21: u32 = unsafe { ::std::mem::transmute(bit_21) }; + bit_21 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(21usize, 1u8, { + let bit_22: u32 = unsafe { ::std::mem::transmute(bit_22) }; + bit_22 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(22usize, 1u8, { + let bit_23: u32 = unsafe { ::std::mem::transmute(bit_23) }; + bit_23 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(23usize, 1u8, { + let bit_24: u32 = unsafe { ::std::mem::transmute(bit_24) }; + bit_24 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(24usize, 1u8, { + let bit_25: u32 = unsafe { ::std::mem::transmute(bit_25) }; + bit_25 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(25usize, 1u8, { + let bit_26: u32 = unsafe { ::std::mem::transmute(bit_26) }; + bit_26 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(26usize, 1u8, { + let bit_27: u32 = unsafe { ::std::mem::transmute(bit_27) }; + bit_27 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(27usize, 1u8, { + let bit_28: u32 = unsafe { ::std::mem::transmute(bit_28) }; + bit_28 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(28usize, 1u8, { + let bit_29: u32 = unsafe { ::std::mem::transmute(bit_29) }; + bit_29 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(29usize, 1u8, { + let bit_30: u32 = unsafe { ::std::mem::transmute(bit_30) }; + bit_30 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(30usize, 1u8, { + let bit_31: u32 = unsafe { ::std::mem::transmute(bit_31) }; + bit_31 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(31usize, 1u8, { + let bit_32: u32 = unsafe { ::std::mem::transmute(bit_32) }; + bit_32 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(32usize, 1u8, { + let bit_33: u32 = unsafe { ::std::mem::transmute(bit_33) }; + bit_33 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(33usize, 1u8, { + let bit_34: u32 = unsafe { ::std::mem::transmute(bit_34) }; + bit_34 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(34usize, 1u8, { + let bit_35: u32 = unsafe { ::std::mem::transmute(bit_35) }; + bit_35 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(35usize, 1u8, { + let bit_36: u32 = unsafe { ::std::mem::transmute(bit_36) }; + bit_36 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(36usize, 1u8, { + let bit_37: u32 = unsafe { ::std::mem::transmute(bit_37) }; + bit_37 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(37usize, 1u8, { + let bit_38: u32 = unsafe { ::std::mem::transmute(bit_38) }; + bit_38 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(38usize, 1u8, { + let bit_39: u32 = unsafe { ::std::mem::transmute(bit_39) }; + bit_39 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(39usize, 1u8, { + let bit_40: u32 = unsafe { ::std::mem::transmute(bit_40) }; + bit_40 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(40usize, 1u8, { + let bit_41: u32 = unsafe { ::std::mem::transmute(bit_41) }; + bit_41 as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs index a812e90560..64b83b7618 100644 --- a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs +++ b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} pub const JSVAL_TAG_SHIFT: u32 = 47; pub const JSVAL_PAYLOAD_MASK: u64 = 140737488355327; pub const JSVAL_TAG_MASK: i64 = -140737488355328; @@ -245,20 +292,23 @@ impl jsval_layout__bindgen_ty_1 { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( payload47: u64, tag: JSValueTag, ) -> __BindgenBitfieldUnit<[u8; 8usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 47u8, { - let payload47: u64 = unsafe { ::std::mem::transmute(payload47) }; - payload47 as u64 - }); - __bindgen_bitfield_unit.set(47usize, 17u8, { - let tag: u32 = unsafe { ::std::mem::transmute(tag) }; - tag as u64 - }); + __BindgenBitfieldUnit::new([0; 8usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 47u8, { + let payload47: u64 = + unsafe { ::std::mem::transmute(payload47) }; + payload47 as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(47usize, 17u8, { + let tag: u32 = unsafe { ::std::mem::transmute(tag) }; + tag as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs index b439499355..8b7a0549a7 100644 --- a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs +++ b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs @@ -299,7 +299,7 @@ impl jsval_layout__bindgen_ty_1 { tag: JSValueTag, ) -> __BindgenBitfieldUnit<[u8; 8usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 8usize]); __bindgen_bitfield_unit.set(0usize, 47u8, { let payload47: u64 = unsafe { ::std::mem::transmute(payload47) }; payload47 as u64 diff --git a/bindgen-tests/tests/expectations/tests/layout_align.rs b/bindgen-tests/tests/expectations/tests/layout_align.rs index 466e76862c..67c904892a 100644 --- a/bindgen-tests/tests/expectations/tests/layout_align.rs +++ b/bindgen-tests/tests/expectations/tests/layout_align.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[derive(Default)] pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); @@ -236,28 +283,31 @@ impl rte_eth_link { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( link_duplex: u16, link_autoneg: u16, link_status: u16, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let link_duplex: u16 = - unsafe { ::std::mem::transmute(link_duplex) }; - link_duplex as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let link_autoneg: u16 = - unsafe { ::std::mem::transmute(link_autoneg) }; - link_autoneg as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let link_status: u16 = - unsafe { ::std::mem::transmute(link_status) }; - link_status as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let link_duplex: u16 = + unsafe { ::std::mem::transmute(link_duplex) }; + link_duplex as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(1usize, 1u8, { + let link_autoneg: u16 = + unsafe { ::std::mem::transmute(link_autoneg) }; + link_autoneg as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(2usize, 1u8, { + let link_status: u16 = + unsafe { ::std::mem::transmute(link_status) }; + link_status as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs b/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs index 62b99e9041..44e14e36d4 100644 --- a/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs +++ b/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs @@ -348,7 +348,7 @@ impl rte_eth_rxmode { enable_lro: u16, ) -> __BindgenBitfieldUnit<[u8; 2usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 2usize]); __bindgen_bitfield_unit.set(0usize, 1u8, { let header_split: u16 = unsafe { ::std::mem::transmute(header_split) }; @@ -513,7 +513,7 @@ impl rte_eth_txmode { hw_vlan_insert_pvid: u8, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 1usize]); __bindgen_bitfield_unit.set(0usize, 1u8, { let hw_vlan_reject_tagged: u8 = unsafe { ::std::mem::transmute(hw_vlan_reject_tagged) }; diff --git a/bindgen-tests/tests/expectations/tests/layout_eth_conf_1_0.rs b/bindgen-tests/tests/expectations/tests/layout_eth_conf_1_0.rs index d7fa0a634a..3970e03610 100644 --- a/bindgen-tests/tests/expectations/tests/layout_eth_conf_1_0.rs +++ b/bindgen-tests/tests/expectations/tests/layout_eth_conf_1_0.rs @@ -396,7 +396,7 @@ impl rte_eth_rxmode { enable_lro: u16, ) -> __BindgenBitfieldUnit<[u8; 2usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 2usize]); __bindgen_bitfield_unit.set(0usize, 1u8, { let header_split: u16 = unsafe { ::std::mem::transmute(header_split) }; @@ -566,7 +566,7 @@ impl rte_eth_txmode { hw_vlan_insert_pvid: u8, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 1usize]); __bindgen_bitfield_unit.set(0usize, 1u8, { let hw_vlan_reject_tagged: u8 = unsafe { ::std::mem::transmute(hw_vlan_reject_tagged) }; diff --git a/bindgen-tests/tests/expectations/tests/layout_mbuf.rs b/bindgen-tests/tests/expectations/tests/layout_mbuf.rs index 800a303be1..0123c24776 100644 --- a/bindgen-tests/tests/expectations/tests/layout_mbuf.rs +++ b/bindgen-tests/tests/expectations/tests/layout_mbuf.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} pub const RTE_CACHE_LINE_MIN_SIZE: u32 = 64; pub const RTE_CACHE_LINE_SIZE: u32 = 64; pub type phys_addr_t = u64; @@ -364,7 +411,7 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( l2_type: u32, l3_type: u32, l4_type: u32, @@ -374,38 +421,45 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { inner_l4_type: u32, ) -> __BindgenBitfieldUnit<[u8; 4usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 4u8, { - let l2_type: u32 = unsafe { ::std::mem::transmute(l2_type) }; - l2_type as u64 - }); - __bindgen_bitfield_unit.set(4usize, 4u8, { - let l3_type: u32 = unsafe { ::std::mem::transmute(l3_type) }; - l3_type as u64 - }); - __bindgen_bitfield_unit.set(8usize, 4u8, { - let l4_type: u32 = unsafe { ::std::mem::transmute(l4_type) }; - l4_type as u64 - }); - __bindgen_bitfield_unit.set(12usize, 4u8, { - let tun_type: u32 = unsafe { ::std::mem::transmute(tun_type) }; - tun_type as u64 - }); - __bindgen_bitfield_unit.set(16usize, 4u8, { - let inner_l2_type: u32 = - unsafe { ::std::mem::transmute(inner_l2_type) }; - inner_l2_type as u64 - }); - __bindgen_bitfield_unit.set(20usize, 4u8, { - let inner_l3_type: u32 = - unsafe { ::std::mem::transmute(inner_l3_type) }; - inner_l3_type as u64 - }); - __bindgen_bitfield_unit.set(24usize, 4u8, { - let inner_l4_type: u32 = - unsafe { ::std::mem::transmute(inner_l4_type) }; - inner_l4_type as u64 - }); + __BindgenBitfieldUnit::new([0; 4usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 4u8, { + let l2_type: u32 = unsafe { ::std::mem::transmute(l2_type) }; + l2_type as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(4usize, 4u8, { + let l3_type: u32 = unsafe { ::std::mem::transmute(l3_type) }; + l3_type as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(8usize, 4u8, { + let l4_type: u32 = unsafe { ::std::mem::transmute(l4_type) }; + l4_type as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(12usize, 4u8, { + let tun_type: u32 = unsafe { ::std::mem::transmute(tun_type) }; + tun_type as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(16usize, 4u8, { + let inner_l2_type: u32 = + unsafe { ::std::mem::transmute(inner_l2_type) }; + inner_l2_type as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(20usize, 4u8, { + let inner_l3_type: u32 = + unsafe { ::std::mem::transmute(inner_l3_type) }; + inner_l3_type as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(24usize, 4u8, { + let inner_l4_type: u32 = + unsafe { ::std::mem::transmute(inner_l4_type) }; + inner_l4_type as u64 + }); __bindgen_bitfield_unit } } @@ -858,7 +912,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( l2_len: u64, l3_len: u64, l4_len: u64, @@ -867,33 +921,40 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { outer_l2_len: u64, ) -> __BindgenBitfieldUnit<[u8; 7usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 7usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 7u8, { - let l2_len: u64 = unsafe { ::std::mem::transmute(l2_len) }; - l2_len as u64 - }); - __bindgen_bitfield_unit.set(7usize, 9u8, { - let l3_len: u64 = unsafe { ::std::mem::transmute(l3_len) }; - l3_len as u64 - }); - __bindgen_bitfield_unit.set(16usize, 8u8, { - let l4_len: u64 = unsafe { ::std::mem::transmute(l4_len) }; - l4_len as u64 - }); - __bindgen_bitfield_unit.set(24usize, 16u8, { - let tso_segsz: u64 = unsafe { ::std::mem::transmute(tso_segsz) }; - tso_segsz as u64 - }); - __bindgen_bitfield_unit.set(40usize, 9u8, { - let outer_l3_len: u64 = - unsafe { ::std::mem::transmute(outer_l3_len) }; - outer_l3_len as u64 - }); - __bindgen_bitfield_unit.set(49usize, 7u8, { - let outer_l2_len: u64 = - unsafe { ::std::mem::transmute(outer_l2_len) }; - outer_l2_len as u64 - }); + __BindgenBitfieldUnit::new([0; 7usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 7u8, { + let l2_len: u64 = unsafe { ::std::mem::transmute(l2_len) }; + l2_len as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(7usize, 9u8, { + let l3_len: u64 = unsafe { ::std::mem::transmute(l3_len) }; + l3_len as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(16usize, 8u8, { + let l4_len: u64 = unsafe { ::std::mem::transmute(l4_len) }; + l4_len as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(24usize, 16u8, { + let tso_segsz: u64 = + unsafe { ::std::mem::transmute(tso_segsz) }; + tso_segsz as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(40usize, 9u8, { + let outer_l3_len: u64 = + unsafe { ::std::mem::transmute(outer_l3_len) }; + outer_l3_len as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(49usize, 7u8, { + let outer_l2_len: u64 = + unsafe { ::std::mem::transmute(outer_l2_len) }; + outer_l2_len as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/layout_mbuf_1_0.rs b/bindgen-tests/tests/expectations/tests/layout_mbuf_1_0.rs index 90f7ed09b2..f78fa07072 100644 --- a/bindgen-tests/tests/expectations/tests/layout_mbuf_1_0.rs +++ b/bindgen-tests/tests/expectations/tests/layout_mbuf_1_0.rs @@ -426,7 +426,7 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { inner_l4_type: u32, ) -> __BindgenBitfieldUnit<[u8; 4usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 4usize]); __bindgen_bitfield_unit.set(0usize, 4u8, { let l2_type: u32 = unsafe { ::std::mem::transmute(l2_type) }; l2_type as u64 @@ -922,7 +922,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { outer_l2_len: u64, ) -> __BindgenBitfieldUnit<[u8; 7usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 7usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 7usize]); __bindgen_bitfield_unit.set(0usize, 7u8, { let l2_len: u64 = unsafe { ::std::mem::transmute(l2_len) }; l2_len as u64 diff --git a/bindgen-tests/tests/expectations/tests/libclang-9/incomplete-array-padding.rs b/bindgen-tests/tests/expectations/tests/libclang-9/incomplete-array-padding.rs index 1de963bf0f..ccbd59b673 100644 --- a/bindgen-tests/tests/expectations/tests/libclang-9/incomplete-array-padding.rs +++ b/bindgen-tests/tests/expectations/tests/libclang-9/incomplete-array-padding.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[derive(Default)] pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); @@ -173,15 +220,16 @@ impl foo { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( a: ::std::os::raw::c_char, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let a: u8 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let a: u8 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/libclang-9/layout_align.rs b/bindgen-tests/tests/expectations/tests/libclang-9/layout_align.rs index f6a32704f1..acfe9f9709 100644 --- a/bindgen-tests/tests/expectations/tests/libclang-9/layout_align.rs +++ b/bindgen-tests/tests/expectations/tests/libclang-9/layout_align.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[derive(Default)] pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); @@ -291,28 +338,31 @@ impl rte_eth_link { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( link_duplex: u16, link_autoneg: u16, link_status: u16, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let link_duplex: u16 = - unsafe { ::std::mem::transmute(link_duplex) }; - link_duplex as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let link_autoneg: u16 = - unsafe { ::std::mem::transmute(link_autoneg) }; - link_autoneg as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let link_status: u16 = - unsafe { ::std::mem::transmute(link_status) }; - link_status as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let link_duplex: u16 = + unsafe { ::std::mem::transmute(link_duplex) }; + link_duplex as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(1usize, 1u8, { + let link_autoneg: u16 = + unsafe { ::std::mem::transmute(link_autoneg) }; + link_autoneg as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(2usize, 1u8, { + let link_status: u16 = + unsafe { ::std::mem::transmute(link_status) }; + link_status as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/only_bitfields.rs b/bindgen-tests/tests/expectations/tests/only_bitfields.rs index 2f063b5b38..1fd9daf792 100644 --- a/bindgen-tests/tests/expectations/tests/only_bitfields.rs +++ b/bindgen-tests/tests/expectations/tests/only_bitfields.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct C { @@ -138,20 +185,22 @@ impl C { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( a: bool, b: bool, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let a: u8 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(1usize, 7u8, { - let b: u8 = unsafe { ::std::mem::transmute(b) }; - b as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let a: u8 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(1usize, 7u8, { + let b: u8 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/packed-bitfield.rs b/bindgen-tests/tests/expectations/tests/packed-bitfield.rs index f90edb930b..79b030d2e8 100644 --- a/bindgen-tests/tests/expectations/tests/packed-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/packed-bitfield.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct Date { @@ -151,25 +198,28 @@ impl Date { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( day: ::std::os::raw::c_uchar, month: ::std::os::raw::c_uchar, year: ::std::os::raw::c_short, ) -> __BindgenBitfieldUnit<[u8; 3usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 5u8, { - let day: u8 = unsafe { ::std::mem::transmute(day) }; - day as u64 - }); - __bindgen_bitfield_unit.set(5usize, 4u8, { - let month: u8 = unsafe { ::std::mem::transmute(month) }; - month as u64 - }); - __bindgen_bitfield_unit.set(9usize, 15u8, { - let year: u16 = unsafe { ::std::mem::transmute(year) }; - year as u64 - }); + __BindgenBitfieldUnit::new([0; 3usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 5u8, { + let day: u8 = unsafe { ::std::mem::transmute(day) }; + day as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(5usize, 4u8, { + let month: u8 = unsafe { ::std::mem::transmute(month) }; + month as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(9usize, 15u8, { + let year: u16 = unsafe { ::std::mem::transmute(year) }; + year as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/private_fields.rs b/bindgen-tests/tests/expectations/tests/private_fields.rs index 8db332a5f3..9d44df8ec5 100644 --- a/bindgen-tests/tests/expectations/tests/private_fields.rs +++ b/bindgen-tests/tests/expectations/tests/private_fields.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct PubPriv { @@ -182,20 +229,22 @@ impl PrivateBitFields { } } #[inline] - fn new_bitfield_1( + const fn new_bitfield_1( a: ::std::os::raw::c_uint, b: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 4u8, { - let a: u32 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(4usize, 4u8, { - let b: u32 = unsafe { ::std::mem::transmute(b) }; - b as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 4u8, { + let a: u32 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(4usize, 4u8, { + let b: u32 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); __bindgen_bitfield_unit } } @@ -248,20 +297,22 @@ impl PublicBitFields { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( a: ::std::os::raw::c_uint, b: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 4u8, { - let a: u32 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(4usize, 4u8, { - let b: u32 = unsafe { ::std::mem::transmute(b) }; - b as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 4u8, { + let a: u32 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(4usize, 4u8, { + let b: u32 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); __bindgen_bitfield_unit } } @@ -314,20 +365,22 @@ impl MixedBitFields { } } #[inline] - fn new_bitfield_1( + const fn new_bitfield_1( a: ::std::os::raw::c_uint, d: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 4u8, { - let a: u32 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(4usize, 4u8, { - let d: u32 = unsafe { ::std::mem::transmute(d) }; - d as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 4u8, { + let a: u32 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(4usize, 4u8, { + let d: u32 = unsafe { ::std::mem::transmute(d) }; + d as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs b/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs index a9be30069e..be08e0bdec 100644 --- a/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs +++ b/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct bitfield { @@ -180,30 +227,34 @@ impl bitfield { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( a: ::std::os::raw::c_ushort, b: ::std::os::raw::c_ushort, c: ::std::os::raw::c_ushort, d: ::std::os::raw::c_ushort, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let a: u16 = unsafe { ::std::mem::transmute(a) }; - a as u64 - }); - __bindgen_bitfield_unit.set(1usize, 1u8, { - let b: u16 = unsafe { ::std::mem::transmute(b) }; - b as u64 - }); - __bindgen_bitfield_unit.set(2usize, 1u8, { - let c: u16 = unsafe { ::std::mem::transmute(c) }; - c as u64 - }); - __bindgen_bitfield_unit.set(6usize, 2u8, { - let d: u16 = unsafe { ::std::mem::transmute(d) }; - d as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let a: u16 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(1usize, 1u8, { + let b: u16 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(2usize, 1u8, { + let c: u16 = unsafe { ::std::mem::transmute(c) }; + c as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(6usize, 2u8, { + let d: u16 = unsafe { ::std::mem::transmute(d) }; + d as u64 + }); __bindgen_bitfield_unit } #[inline] @@ -233,20 +284,22 @@ impl bitfield { } } #[inline] - pub fn new_bitfield_2( + pub const fn new_bitfield_2( f: ::std::os::raw::c_uint, g: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 8usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 2u8, { - let f: u32 = unsafe { ::std::mem::transmute(f) }; - f as u64 - }); - __bindgen_bitfield_unit.set(32usize, 32u8, { - let g: u32 = unsafe { ::std::mem::transmute(g) }; - g as u64 - }); + __BindgenBitfieldUnit::new([0; 8usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 2u8, { + let f: u32 = unsafe { ::std::mem::transmute(f) }; + f as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(32usize, 32u8, { + let g: u32 = unsafe { ::std::mem::transmute(g) }; + g as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/timex.rs b/bindgen-tests/tests/expectations/tests/timex.rs index dfcebdd29c..c39546b0f2 100644 --- a/bindgen-tests/tests/expectations/tests/timex.rs +++ b/bindgen-tests/tests/expectations/tests/timex.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct timex { diff --git a/bindgen-tests/tests/expectations/tests/union_bitfield.rs b/bindgen-tests/tests/expectations/tests/union_bitfield.rs index 9e07a1dfcd..d6734e63d3 100644 --- a/bindgen-tests/tests/expectations/tests/union_bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/union_bitfield.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[repr(align(4))] #[derive(Copy, Clone)] @@ -135,15 +182,16 @@ impl U4 { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( derp: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 1u8, { - let derp: u32 = unsafe { ::std::mem::transmute(derp) }; - derp as u64 - }); + __BindgenBitfieldUnit::new([0; 1usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 1u8, { + let derp: u32 = unsafe { ::std::mem::transmute(derp) }; + derp as u64 + }); __bindgen_bitfield_unit } } @@ -204,20 +252,22 @@ impl B { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( foo: ::std::os::raw::c_uint, bar: ::std::os::raw::c_uchar, ) -> __BindgenBitfieldUnit<[u8; 4usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 31u8, { - let foo: u32 = unsafe { ::std::mem::transmute(foo) }; - foo as u64 - }); - __bindgen_bitfield_unit.set(31usize, 1u8, { - let bar: u8 = unsafe { ::std::mem::transmute(bar) }; - bar as u64 - }); + __BindgenBitfieldUnit::new([0; 4usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 31u8, { + let foo: u32 = unsafe { ::std::mem::transmute(foo) }; + foo as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(31usize, 1u8, { + let bar: u8 = unsafe { ::std::mem::transmute(bar) }; + bar as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/union_bitfield_1_0.rs b/bindgen-tests/tests/expectations/tests/union_bitfield_1_0.rs index 2227746849..ae0081615b 100644 --- a/bindgen-tests/tests/expectations/tests/union_bitfield_1_0.rs +++ b/bindgen-tests/tests/expectations/tests/union_bitfield_1_0.rs @@ -180,7 +180,7 @@ impl U4 { derp: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 1usize]); __bindgen_bitfield_unit.set(0usize, 1u8, { let derp: u32 = unsafe { ::std::mem::transmute(derp) }; derp as u64 @@ -250,7 +250,7 @@ impl B { bar: ::std::os::raw::c_uchar, ) -> __BindgenBitfieldUnit<[u8; 4usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 4usize]); __bindgen_bitfield_unit.set(0usize, 31u8, { let foo: u32 = unsafe { ::std::mem::transmute(foo) }; foo as u64 diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs index e81b3bef50..b4a45b16a3 100644 --- a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(C)] #[derive(Copy, Clone)] pub union foo { @@ -145,20 +192,22 @@ impl foo__bindgen_ty_1 { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( b: ::std::os::raw::c_int, c: ::std::os::raw::c_int, ) -> __BindgenBitfieldUnit<[u8; 4usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 7u8, { - let b: u32 = unsafe { ::std::mem::transmute(b) }; - b as u64 - }); - __bindgen_bitfield_unit.set(7usize, 25u8, { - let c: u32 = unsafe { ::std::mem::transmute(c) }; - c as u64 - }); + __BindgenBitfieldUnit::new([0; 4usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 7u8, { + let b: u32 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(7usize, 25u8, { + let c: u32 = unsafe { ::std::mem::transmute(c) }; + c as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs index 6ce6ed2282..eeca07e0cc 100644 --- a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs +++ b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs @@ -199,7 +199,7 @@ impl foo__bindgen_ty_1 { c: ::std::os::raw::c_int, ) -> __BindgenBitfieldUnit<[u8; 4usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); + __BindgenBitfieldUnit::new([0; 4usize]); __bindgen_bitfield_unit.set(0usize, 7u8, { let b: u32 = unsafe { ::std::mem::transmute(b) }; b as u64 diff --git a/bindgen-tests/tests/expectations/tests/weird_bitfields.rs b/bindgen-tests/tests/expectations/tests/weird_bitfields.rs index 9383bada44..3f7783f99f 100644 --- a/bindgen-tests/tests/expectations/tests/weird_bitfields.rs +++ b/bindgen-tests/tests/expectations/tests/weird_bitfields.rs @@ -91,6 +91,53 @@ where } } } +impl __BindgenBitfieldUnit<[u8; N]> { + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + let byte_index = index / 8; + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + self + } + #[inline] + #[must_use] + pub const fn set_const( + mut self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.len() + ); + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + i += 1; + } + self + } +} #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum nsStyleSVGOpacitySource { @@ -319,20 +366,22 @@ impl Weird { } } #[inline] - pub fn new_bitfield_1( + pub const fn new_bitfield_1( bitTest: ::std::os::raw::c_uint, bitTest2: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 4usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 16u8, { - let bitTest: u32 = unsafe { ::std::mem::transmute(bitTest) }; - bitTest as u64 - }); - __bindgen_bitfield_unit.set(16usize, 15u8, { - let bitTest2: u32 = unsafe { ::std::mem::transmute(bitTest2) }; - bitTest2 as u64 - }); + __BindgenBitfieldUnit::new([0; 4usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 16u8, { + let bitTest: u32 = unsafe { ::std::mem::transmute(bitTest) }; + bitTest as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(16usize, 15u8, { + let bitTest2: u32 = unsafe { ::std::mem::transmute(bitTest2) }; + bitTest2 as u64 + }); __bindgen_bitfield_unit } #[inline] @@ -401,7 +450,7 @@ impl Weird { } } #[inline] - pub fn new_bitfield_2( + pub const fn new_bitfield_2( mFillOpacitySource: nsStyleSVGOpacitySource, mStrokeOpacitySource: nsStyleSVGOpacitySource, mStrokeDasharrayFromObject: bool, @@ -409,32 +458,39 @@ impl Weird { mStrokeWidthFromObject: bool, ) -> __BindgenBitfieldUnit<[u8; 2usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = - Default::default(); - __bindgen_bitfield_unit.set(0usize, 3u8, { - let mFillOpacitySource: u32 = - unsafe { ::std::mem::transmute(mFillOpacitySource) }; - mFillOpacitySource as u64 - }); - __bindgen_bitfield_unit.set(3usize, 3u8, { - let mStrokeOpacitySource: u32 = - unsafe { ::std::mem::transmute(mStrokeOpacitySource) }; - mStrokeOpacitySource as u64 - }); - __bindgen_bitfield_unit.set(6usize, 1u8, { - let mStrokeDasharrayFromObject: u8 = - unsafe { ::std::mem::transmute(mStrokeDasharrayFromObject) }; - mStrokeDasharrayFromObject as u64 - }); - __bindgen_bitfield_unit.set(7usize, 1u8, { - let mStrokeDashoffsetFromObject: u8 = - unsafe { ::std::mem::transmute(mStrokeDashoffsetFromObject) }; - mStrokeDashoffsetFromObject as u64 - }); - __bindgen_bitfield_unit.set(8usize, 1u8, { - let mStrokeWidthFromObject: u8 = - unsafe { ::std::mem::transmute(mStrokeWidthFromObject) }; - mStrokeWidthFromObject as u64 - }); + __BindgenBitfieldUnit::new([0; 2usize]); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(0usize, 3u8, { + let mFillOpacitySource: u32 = + unsafe { ::std::mem::transmute(mFillOpacitySource) }; + mFillOpacitySource as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(3usize, 3u8, { + let mStrokeOpacitySource: u32 = + unsafe { ::std::mem::transmute(mStrokeOpacitySource) }; + mStrokeOpacitySource as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(6usize, 1u8, { + let mStrokeDasharrayFromObject: u8 = unsafe { + ::std::mem::transmute(mStrokeDasharrayFromObject) + }; + mStrokeDasharrayFromObject as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(7usize, 1u8, { + let mStrokeDashoffsetFromObject: u8 = unsafe { + ::std::mem::transmute(mStrokeDashoffsetFromObject) + }; + mStrokeDashoffsetFromObject as u64 + }); + let __bindgen_bitfield_unit = + __bindgen_bitfield_unit.set_const(8usize, 1u8, { + let mStrokeWidthFromObject: u8 = + unsafe { ::std::mem::transmute(mStrokeWidthFromObject) }; + mStrokeWidthFromObject as u64 + }); __bindgen_bitfield_unit } } diff --git a/bindgen/codegen/bitfield_unit_const.rs b/bindgen/codegen/bitfield_unit_const.rs new file mode 100644 index 0000000000..9f415c47e4 --- /dev/null +++ b/bindgen/codegen/bitfield_unit_const.rs @@ -0,0 +1,52 @@ +impl __BindgenBitfieldUnit<[u8; N]> +{ + #[inline] + #[must_use] + pub const fn set_bit_const(mut self, index: usize, val: bool) -> Self { + debug_assert!(index / 8 < self.storage.len()); + + let byte_index = index / 8; + + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + + let mask = 1 << bit_index; + if val { + self.storage[byte_index] |= mask; + } else { + self.storage[byte_index] &= !mask; + } + + self + } + + #[inline] + #[must_use] + pub const fn set_const(mut self, bit_offset: usize, bit_width: u8, val: u64) -> Self { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= + self.storage.len() + ); + + let mut i = 0; + while i < bit_width as usize { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self = self.set_bit_const(index + bit_offset, val_bit_is_set); + + i += 1; + } + + self + } +} diff --git a/bindgen/codegen/helpers.rs b/bindgen/codegen/helpers.rs index 5bf36acb42..c56d2b3606 100644 --- a/bindgen/codegen/helpers.rs +++ b/bindgen/codegen/helpers.rs @@ -128,6 +128,25 @@ pub fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> TokenStream { tokens } +/// Generates default initialization value for a bitfield allocation unit type for a type with the given `Layout`. +pub fn bitfield_init_value( + ctx: &BindgenContext, + layout: Layout, +) -> TokenStream { + let mut tokens = quote! {}; + + if ctx.options().enable_cxx_namespaces { + tokens.append_all(quote! { root:: }); + } + + let size = layout.size; + tokens.append_all(quote! { + __BindgenBitfieldUnit::new([0; #size]) + }); + + tokens +} + pub mod ast_ty { use crate::ir::context::BindgenContext; use crate::ir::function::FunctionSig; diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index 7e0d7aa0c9..e8e5974f01 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -1516,17 +1516,25 @@ impl Bitfield { let width = self.width() as u8; let prefix = ctx.trait_prefix(); - ctor_impl.append_all(quote! { - __bindgen_bitfield_unit.set( - #offset, - #width, - { - let #param_name: #bitfield_int_ty = unsafe { - ::#prefix::mem::transmute(#param_name) - }; - #param_name as u64 - } - ); + let bifield_set_params = quote! { + #offset, + #width, + { + let #param_name: #bitfield_int_ty = unsafe { + ::#prefix::mem::transmute(#param_name) + }; + #param_name as u64 + } + }; + + ctor_impl.append_all(if ctx.options().rust_features().const_panic { + quote! { + let __bindgen_bitfield_unit = __bindgen_bitfield_unit.set_const(#bifield_set_params); + } + } else { + quote! { + __bindgen_bitfield_unit.set(#bifield_set_params); + } }); ctor_impl @@ -1569,6 +1577,7 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { let layout = self.layout(); let unit_field_ty = helpers::bitfield_unit(ctx, layout); + let unit_field_init = helpers::bitfield_init_value(ctx, layout); let field_ty = if parent.is_union() { wrap_union_field_if_needed( ctx, @@ -1657,6 +1666,11 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { } let access_spec = access_specifier(ctx, access_spec); + let const_mod = if ctx.options().rust_features().const_panic { + quote! { const } + } else { + quote! {} + }; let field = quote! { #access_spec #unit_field_ident : #field_ty , @@ -1666,8 +1680,8 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { if generate_ctor { methods.extend(Some(quote! { #[inline] - #access_spec fn #ctor_name ( #( #ctor_params ),* ) -> #unit_field_ty { - let mut __bindgen_bitfield_unit: #unit_field_ty = Default::default(); + #access_spec #const_mod fn #ctor_name ( #( #ctor_params ),* ) -> #unit_field_ty { + let mut __bindgen_bitfield_unit: #unit_field_ty = #unit_field_init; #ctor_impl __bindgen_bitfield_unit } @@ -4539,6 +4553,18 @@ pub mod utils { let items = vec![bitfield_unit_type]; let old_items = mem::replace(result, items); + + if ctx.options().rust_features().const_panic { + let bitfield_unit_const_src = + include_str!("./bitfield_unit_const.rs"); + + let bitfield_unit_const_impl = + proc_macro2::TokenStream::from_str(bitfield_unit_const_src) + .unwrap(); + let bitfield_unit_const_impl = quote!(#bitfield_unit_const_impl); + result.push(bitfield_unit_const_impl); + } + result.extend(old_items); } diff --git a/bindgen/features.rs b/bindgen/features.rs index 4f05b9eb07..6143ba24d8 100644 --- a/bindgen/features.rs +++ b/bindgen/features.rs @@ -127,6 +127,9 @@ macro_rules! rust_target_base { /// Rust stable 1.47 /// * `larger_arrays` ([Tracking issue](https://github.com/rust-lang/rust/pull/74060)) => Stable_1_47 => 1.47; + /// Rust stable 1.57 + /// * `const_panic` ([Tracking issue](https://github.com/rust-lang/rust/issues/51999)) + => Stable_1_57 => 1.57; /// Rust stable 1.64 /// * `core_ffi_c` ([Tracking issue](https://github.com/rust-lang/rust/issues/94501)) => Stable_1_64 => 1.64; @@ -236,6 +239,9 @@ rust_feature_def!( Stable_1_47 { => larger_arrays; } + Stable_1_57 { + => const_panic; + } Stable_1_64 { => core_ffi_c; }