Skip to content

Commit c721775

Browse files
committed
avoid using modules in macro
1 parent ca329e9 commit c721775

File tree

5 files changed

+234
-74
lines changed

5 files changed

+234
-74
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bit-struct"
3-
version = "0.1.18"
3+
version = "0.1.19"
44
edition = "2021"
55
description = "Define structs which have fields which are assigned to individual bits, not bytes"
66
repository = "https://github.com/andrewgazelka/bit-struct"

src/lib.rs

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,41 @@
44

55
use core::fmt::{Debug, Display, Formatter};
66
use core::marker::PhantomData;
7-
use core::ops::{BitAnd, BitOrAssign, BitXorAssign, Shl, ShlAssign, Shr, ShrAssign};
7+
use core::ops::{BitAnd, BitOrAssign, BitXorAssign, Deref, DerefMut, Shl, ShlAssign, Shr, ShrAssign};
88
use num_traits::{Bounded, Num};
99

10+
#[repr(transparent)]
11+
#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash, Default)]
12+
pub struct UnsafeStorage<T>(T);
13+
14+
impl <T> UnsafeStorage<T> {
15+
pub fn new_unsafe(inner: T) -> Self {
16+
Self(inner)
17+
}
18+
}
19+
20+
impl <T> Deref for UnsafeStorage<T> {
21+
type Target = T;
22+
23+
fn deref(&self) -> &Self::Target {
24+
&self.0
25+
}
26+
}
27+
28+
impl <T> DerefMut for UnsafeStorage<T> {
29+
fn deref_mut(&mut self) -> &mut Self::Target {
30+
&mut self.0
31+
}
32+
}
33+
34+
impl <T: Copy> UnsafeStorage<T> {
35+
pub fn inner(&self) -> T {
36+
self.0
37+
}
38+
}
39+
40+
41+
1042
/// A struct which allows for getting/setting a given property
1143
pub struct GetSet<'a, P, T, const START: usize, const STOP: usize> {
1244
/// The referenced bitfield type.
@@ -674,58 +706,48 @@ macro_rules! bit_struct {
674706
}
675707
)*
676708
) => {
709+
$(
710+
$(#[doc = $struct_doc])*
711+
#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
712+
pub struct $name(bit_struct::UnsafeStorage<$kind>);
677713

678-
mod bit_struct_private_impl {
679-
use super::*;
680-
681-
$(
682-
$(#[doc = $struct_doc])*
683-
#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
684-
pub struct $name($kind);
685-
686-
impl TryFrom<$kind> for $name {
687-
type Error = ();
688-
fn try_from(elem: $kind) -> Result<$name, ()> {
689-
let mut res = Self(elem);
690-
$(
691-
if !res.$field().is_valid() {
692-
return Err(());
693-
}
694-
)*
695-
Ok(res)
696-
}
714+
impl TryFrom<$kind> for $name {
715+
type Error = ();
716+
fn try_from(elem: $kind) -> Result<$name, ()> {
717+
let mut res = unsafe{Self::from_unchecked(elem)};
718+
$(
719+
if !res.$field().is_valid() {
720+
return Err(());
721+
}
722+
)*
723+
Ok(res)
697724
}
725+
}
698726

699-
impl $name {
700-
701-
pub unsafe fn from_unchecked(inner: $kind) -> Self {
702-
Self(inner)
703-
}
727+
impl $name {
704728

705-
#[allow(clippy::too_many_arguments)]
706-
pub fn new($($field: $actual),*) -> Self {
707-
let mut res = Self(0);
708-
$(
709-
res.$field().set($field);
710-
)*
711-
res
712-
}
729+
pub unsafe fn from_unchecked(inner: $kind) -> Self {
730+
Self(bit_struct::UnsafeStorage::new_unsafe(inner))
731+
}
713732

714-
pub fn raw(self) -> $kind {
715-
self.0
716-
}
733+
#[allow(clippy::too_many_arguments)]
734+
pub fn new($($field: $actual),*) -> Self {
735+
let mut res = unsafe { Self::from_unchecked(0) };
736+
$(
737+
res.$field().set($field);
738+
)*
739+
res
740+
}
717741

718-
bit_struct::impl_fields!(<$kind as bit_struct::BitCount>::COUNT, $kind => $([$($field_doc),*], $field, $actual),*);
742+
pub fn raw(self) -> $kind {
743+
self.0.inner()
719744
}
720745

721-
)*
746+
bit_struct::impl_fields!(<$kind as bit_struct::BitCount>::COUNT, $kind => $([$($field_doc),*], $field, $actual),*);
722747
}
723748

724-
$(
725-
pub use bit_struct_private_impl::$name;
726749
)*
727750

728-
729751
$(
730752
bit_struct::bit_struct_impl!(
731753
$(#[doc = $struct_doc])*
Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,35 @@
11
error[E0277]: the trait bound `EnumNoBits: BitCount` is not satisfied
2-
--> tests/compile/incorrect_type.rs:6:1
3-
|
4-
6 | / bit_struct::bit_struct! {
5-
7 | | struct Incorrect(u16) {
6-
8 | | a: EnumNoBits
7-
9 | | }
8-
10 | | }
9-
| |_^ the trait `BitCount` is not implemented for `EnumNoBits`
10-
|
11-
= note: this error originates in the macro `bit_struct::impl_fields` (in Nightly builds, run with -Z macro-backtrace for more info)
2+
--> src/lib.rs
3+
|
4+
| / macro_rules! impl_fields {
5+
| |
6+
| | ($on: expr, $kind: ty =>
7+
| | [$($first_field_doc: expr),*], $head_field: ident, $head_actual: ty $(, [$($field_doc: expr),*], $field: ident, $actual: ty)*) => {
8+
| | $(#[doc=$first_field_doc])*
9+
| | pub fn $head_field(&mut self) -> bit_struct::GetSet<'_, $kind, $head_actual, {$on - <$head_actual as bit_struct::BitCount>::COUNT}, ...
10+
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `BitCount` is not implemented for `EnumNoBits`
11+
... |
12+
| | ($on: expr, $kind: ty =>) => {};
13+
| | }
14+
| |_- in this expansion of `bit_struct::impl_fields!` (#2)
15+
...
16+
| / macro_rules! bit_struct {
17+
| | (
18+
| | $(
19+
| | $(#[doc = $struct_doc:expr])*
20+
... |
21+
| | bit_struct::impl_fields!(<$kind as bit_struct::BitCount>::COUNT, $kind => $([$($field_doc),*], $field, $actual),*);
22+
| | ------------------------------------------------------------------------------------------------------------------ in this macro invocation (#2)
23+
... |
24+
| | };
25+
| | }
26+
| |_- in this expansion of `bit_struct::bit_struct!` (#1)
27+
|
28+
::: tests/compile/incorrect_type.rs:6:1
29+
|
30+
6 | / bit_struct::bit_struct! {
31+
7 | | struct Incorrect(u16) {
32+
8 | | a: EnumNoBits
33+
9 | | }
34+
10 | | }
35+
| |_- in this macro invocation (#1)

tests/compile/too_big.stderr

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,35 @@
11
error[E0080]: evaluation of constant value failed
2-
--> tests/compile/too_big.rs:1:1
3-
|
4-
1 | / bit_struct::bit_struct! {
5-
2 | | struct TooMany(u16) {
6-
3 | | a: u32
7-
4 | | }
8-
5 | | }
9-
| |_^ attempt to compute `16_usize - 32_usize`, which would overflow
10-
|
11-
= note: this error originates in the macro `bit_struct::impl_fields` (in Nightly builds, run with -Z macro-backtrace for more info)
2+
--> src/lib.rs
3+
|
4+
| / macro_rules! impl_fields {
5+
| |
6+
| | ($on: expr, $kind: ty =>
7+
| | [$($first_field_doc: expr),*], $head_field: ident, $head_actual: ty $(, [$($field_doc: expr),*], $field: ident, $actual: ty)*) => {
8+
| | $(#[doc=$first_field_doc])*
9+
| | pub fn $head_field(&mut self) -> bit_struct::GetSet<'_, $kind, $head_actual, {$on - <$head_actual as bit_struct::BitCount>::COUNT}, ...
10+
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `16_usize - 32_usize`, which would overflow
11+
... |
12+
| | ($on: expr, $kind: ty =>) => {};
13+
| | }
14+
| |_- in this expansion of `bit_struct::impl_fields!` (#2)
15+
...
16+
| / macro_rules! bit_struct {
17+
| | (
18+
| | $(
19+
| | $(#[doc = $struct_doc:expr])*
20+
... |
21+
| | bit_struct::impl_fields!(<$kind as bit_struct::BitCount>::COUNT, $kind => $([$($field_doc),*], $field, $actual),*);
22+
| | ------------------------------------------------------------------------------------------------------------------ in this macro invocation (#2)
23+
... |
24+
| | };
25+
| | }
26+
| |_- in this expansion of `bit_struct::bit_struct!` (#1)
27+
|
28+
::: tests/compile/too_big.rs:1:1
29+
|
30+
1 | / bit_struct::bit_struct! {
31+
2 | | struct TooMany(u16) {
32+
3 | | a: u32
33+
4 | | }
34+
5 | | }
35+
| |_- in this macro invocation (#1)

tests/compile/too_many.stderr

Lines changed: 102 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,103 @@
11
error[E0080]: evaluation of constant value failed
2-
--> tests/compile/too_many.rs:1:1
3-
|
4-
1 | / bit_struct::bit_struct! {
5-
2 | | struct TooMany(u16) {
6-
3 | | a: u8,
7-
4 | | b: u8,
8-
5 | | c: bit_struct::u1
9-
6 | | }
10-
7 | | }
11-
| |_^ attempt to compute `0_usize - 1_usize`, which would overflow
12-
|
13-
= note: this error originates in the macro `bit_struct::impl_fields` (in Nightly builds, run with -Z macro-backtrace for more info)
2+
--> src/lib.rs
3+
|
4+
| macro_rules! impl_fields {
5+
| _-
6+
| |_|
7+
| |_|
8+
| |
9+
| |
10+
| | ($on: expr, $kind: ty =>
11+
| | [$($first_field_doc: expr),*], $head_field: ident, $head_actual: ty $(, [$($field_doc: expr),*], $field: ident, $actual: ty)*) => {
12+
| | $(#[doc=$first_field_doc])*
13+
| | pub fn $head_field(&mut self) -> bit_struct::GetSet<'_, $kind, $head_actual, {$on - <$head_actual as bit_struct::BitCount>::COUNT}, ...
14+
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
15+
... |
16+
| | bit_struct::impl_fields!($on - <$head_actual as bit_struct::BitCount>::COUNT, $kind => $([$($field_doc),*], $field, $actual),*);
17+
| | -------------------------------------------------------------------------------------------------------------------------------
18+
| | |
19+
| | in this macro invocation (#3)
20+
| | in this macro invocation (#4)
21+
| | };
22+
| | ($on: expr, $kind: ty =>) => {};
23+
| | }
24+
| | -
25+
| |_|
26+
| |_in this expansion of `bit_struct::impl_fields!` (#2)
27+
| |_in this expansion of `bit_struct::impl_fields!` (#3)
28+
| in this expansion of `bit_struct::impl_fields!` (#4)
29+
...
30+
| / macro_rules! bit_struct {
31+
| (
32+
| $(
33+
| $(#[doc = $struct_doc:expr])*
34+
...
35+
| bit_struct::impl_fields!(<$kind as bit_struct::BitCount>::COUNT, $kind => $([$($field_doc),*], $field, $actual),*);
36+
| ------------------------------------------------------------------------------------------------------------------ in this macro invocation (#2)
37+
...
38+
| };
39+
| | }
40+
| |_- in this expansion of `bit_struct::bit_struct!` (#1)
41+
|
42+
::: tests/compile/too_many.rs:1:1
43+
|
44+
1 | / bit_struct::bit_struct! {
45+
2 | | struct TooMany(u16) {
46+
3 | | a: u8,
47+
4 | | b: u8,
48+
5 | | c: bit_struct::u1
49+
6 | | }
50+
7 | | }
51+
| |_- in this macro invocation (#1)
52+
53+
error[E0080]: evaluation of constant value failed
54+
--> src/lib.rs
55+
|
56+
| macro_rules! impl_fields {
57+
| _-
58+
| |_|
59+
| |_|
60+
| |
61+
| |
62+
| | ($on: expr, $kind: ty =>
63+
| | [$($first_field_doc: expr),*], $head_field: ident, $head_actual: ty $(, [$($field_doc: expr),*], $field: ident, $actual: ty)*) => {
64+
| | $(#[doc=$first_field_doc])*
65+
| | pub fn $head_field(&mut self) -> bit_struct::GetSet<'_, $kind, $head_actual, {$on - <$head_actual as bit_struct::BitCount>::COUNT}, {$on - 1}...
66+
| | ^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
67+
... |
68+
| | bit_struct::impl_fields!($on - <$head_actual as bit_struct::BitCount>::COUNT, $kind => $([$($field_doc),*], $field, $actual),*);
69+
| | -------------------------------------------------------------------------------------------------------------------------------
70+
| | |
71+
| | in this macro invocation (#3)
72+
| | in this macro invocation (#4)
73+
| | };
74+
| | ($on: expr, $kind: ty =>) => {};
75+
| | }
76+
| | -
77+
| |_|
78+
| |_in this expansion of `bit_struct::impl_fields!` (#2)
79+
| |_in this expansion of `bit_struct::impl_fields!` (#3)
80+
| in this expansion of `bit_struct::impl_fields!` (#4)
81+
...
82+
| / macro_rules! bit_struct {
83+
| (
84+
| $(
85+
| $(#[doc = $struct_doc:expr])*
86+
...
87+
| bit_struct::impl_fields!(<$kind as bit_struct::BitCount>::COUNT, $kind => $([$($field_doc),*], $field, $actual),*);
88+
| ------------------------------------------------------------------------------------------------------------------ in this macro invocation (#2)
89+
...
90+
| };
91+
| | }
92+
| |_- in this expansion of `bit_struct::bit_struct!` (#1)
93+
|
94+
::: tests/compile/too_many.rs:1:1
95+
|
96+
1 | / bit_struct::bit_struct! {
97+
2 | | struct TooMany(u16) {
98+
3 | | a: u8,
99+
4 | | b: u8,
100+
5 | | c: bit_struct::u1
101+
6 | | }
102+
7 | | }
103+
| |_- in this macro invocation (#1)

0 commit comments

Comments
 (0)