Skip to content

Commit ec6f62b

Browse files
committed
Use internal macro for per-uint-type impls
NOTE: we remove usize, as usize is no longer supported (as checked by the #[bitflags] macro, see test_suite/ui/invalid_repr.rs). Also, u128 is added, even though #[repr(u128)] on enums is currently unstable.
1 parent cdd90eb commit ec6f62b

File tree

2 files changed

+37
-23
lines changed

2 files changed

+37
-23
lines changed

src/fallible.rs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,17 @@ use super::BitFlag;
55

66
// Coherence doesn't let us use a generic type here. Work around by implementing
77
// for each integer type manually.
8-
macro_rules! impl_try_from {
9-
($($ty:ty),*) => {
10-
$(
11-
impl<T> TryFrom<$ty> for BitFlags<T>
12-
where
13-
T: BitFlag<Numeric=$ty>,
14-
{
15-
type Error = FromBitsError<T>;
8+
for_each_uint! { ty =>
9+
impl<T> TryFrom<$ty> for BitFlags<T>
10+
where
11+
T: BitFlag<Numeric=$ty>,
12+
{
13+
type Error = FromBitsError<T>;
1614

17-
fn try_from(bits: T::Numeric) -> Result<Self, Self::Error> {
18-
Self::from_bits(bits)
19-
}
20-
}
21-
)*
22-
};
23-
}
24-
25-
impl_try_from! {
26-
u8, u16, u32, u64, usize
15+
fn try_from(bits: T::Numeric) -> Result<Self, Self::Error> {
16+
Self::from_bits(bits)
17+
}
18+
}
2719
}
2820

2921
/// The error struct used by [`BitFlags::from_bits`]

src/lib.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,30 @@ extern crate enumflags2_derive;
9393
#[doc(hidden)]
9494
pub use enumflags2_derive::bitflags_internal as bitflags;
9595

96+
// Internal macro: expand into a separate copy for each supported numeric type.
97+
macro_rules! for_each_uint {
98+
( $tyvar:ident => $($input:tt)* ) => {
99+
// This wrapper macro is necessary to create a $ escape sequence
100+
// for use in macro repetitions in implement!
101+
// cf. https://github.com/rust-lang/rust/issues/35853
102+
macro_rules! with_dollar {
103+
( $d:tt ) => {
104+
macro_rules! implement {
105+
( $d($d $tyvar:ty),* ) => {
106+
$d(
107+
$($input)*
108+
)*
109+
}
110+
}
111+
}
112+
}
113+
114+
with_dollar!($);
115+
116+
implement! { u8, u16, u32, u64, u128 }
117+
}
118+
}
119+
96120
/// A trait automatically implemented by `#[bitflags]` to make the enum
97121
/// a valid type parameter for `BitFlags<T>`.
98122
pub trait BitFlag: Copy + Clone + 'static + _internal::RawBitFlags {
@@ -203,11 +227,9 @@ pub mod _internal {
203227
+ Clone {
204228
}
205229

206-
impl BitFlagNum for u8 {}
207-
impl BitFlagNum for u16 {}
208-
impl BitFlagNum for u32 {}
209-
impl BitFlagNum for u64 {}
210-
impl BitFlagNum for usize {}
230+
for_each_uint! { ty =>
231+
impl BitFlagNum for $ty {}
232+
}
211233

212234
// Re-export libcore so the macro doesn't inject "extern crate" downstream.
213235
pub mod core {

0 commit comments

Comments
 (0)