Skip to content

Commit

Permalink
Clarify compile time asserts, give them cleaner error messages
Browse files Browse the repository at this point in the history
First step in making .into() more usable
  • Loading branch information
danlehmann committed Aug 27, 2024
1 parent 4b661d9 commit 8e11918
Showing 1 changed file with 25 additions and 16 deletions.
41 changes: 25 additions & 16 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,6 @@ macro_rules! impl_number_native {

impl_number_native!(u8, u16, u32, u64, u128);

struct CompileTimeAssert<const A: usize, const B: usize> {}

impl<const A: usize, const B: usize> CompileTimeAssert<A, B> {
pub const SMALLER_OR_EQUAL: () = {
assert!(A <= B);
};
}

#[derive(Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd)]
pub struct UInt<T, const BITS: usize> {
value: T,
Expand Down Expand Up @@ -530,7 +522,10 @@ macro_rules! uint_impl {
pub const fn widen<const BITS_RESULT: usize>(
self,
) -> UInt<$type, BITS_RESULT> {
let _ = CompileTimeAssert::<BITS, BITS_RESULT>::SMALLER_OR_EQUAL;
const { if BITS >= BITS_RESULT {

Check failure on line 525 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build-and-test

inline-const is experimental
panic!("Can not call widen() with the given bit widths");
} };

// Query MAX of the result to ensure we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
let _ = UInt::<$type, BITS_RESULT>::MAX;
UInt::<$type, BITS_RESULT> { value: self.value }
Expand Down Expand Up @@ -1626,7 +1621,10 @@ macro_rules! from_arbitrary_int_impl {
{
#[inline]
fn from(item: UInt<$from, BITS_FROM>) -> Self {
let _ = CompileTimeAssert::<BITS_FROM, BITS>::SMALLER_OR_EQUAL;
const { if BITS_FROM > BITS {

Check failure on line 1624 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build-and-test

inline-const is experimental

Check failure on line 1624 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build-and-test

inline-const is experimental

Check failure on line 1624 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build-and-test

inline-const is experimental

Check failure on line 1624 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build-and-test

inline-const is experimental

Check failure on line 1624 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build-and-test

inline-const is experimental
panic!("Can not call from() to convert between the given bit widths.");
} };

Self { value: item.value as $into }
}
}
Expand All @@ -1643,7 +1641,10 @@ macro_rules! from_arbitrary_int_impl {
{
#[inline]
fn from(item: UInt<$from, BITS_FROM>) -> Self {
let _ = CompileTimeAssert::<BITS_FROM, BITS>::SMALLER_OR_EQUAL;
const { if BITS_FROM > BITS {
panic!("Can not call from() to convert between the given bit widths.");
} };

Self { value: item.value as $into }
}
}
Expand All @@ -1658,15 +1659,19 @@ macro_rules! from_native_impl {
impl<const BITS: usize> const From<$from> for UInt<$into, BITS> {
#[inline]
fn from(from: $from) -> Self {
let _ = CompileTimeAssert::<{ <$from>::BITS as usize }, BITS>::SMALLER_OR_EQUAL;
const { if <$from>::BITS as usize > BITS {

Check failure on line 1662 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build-and-test

inline-const is experimental

Check failure on line 1662 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build-and-test

inline-const is experimental
panic!("Can not call from() to convert between the given bit widths.");
} };
Self { value: from as $into }
}
}

impl<const BITS: usize> const From<UInt<$from, BITS>> for $into {
#[inline]
fn from(from: UInt<$from, BITS>) -> Self {
let _ = CompileTimeAssert::<BITS, { <$into>::BITS as usize }>::SMALLER_OR_EQUAL;
const { if BITS > <$from>::BITS as usize {

Check failure on line 1672 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build-and-test

inline-const is experimental

Check failure on line 1672 in src/lib.rs

View workflow job for this annotation

GitHub Actions / build-and-test

inline-const is experimental
panic!("Can not call from() to convert between the given bit widths.");
} };
from.value as $into
}
}
Expand All @@ -1681,15 +1686,19 @@ macro_rules! from_native_impl {
impl<const BITS: usize> From<$from> for UInt<$into, BITS> {
#[inline]
fn from(from: $from) -> Self {
let _ = CompileTimeAssert::<{ <$from>::BITS as usize }, BITS>::SMALLER_OR_EQUAL;
const { if <$from>::BITS as usize > BITS {
panic!("Can not call from() to convert between the given bit widths.");
} };
Self { value: from as $into }
}
}

impl<const BITS: usize> From<UInt<$from, BITS>> for $into {
#[inline]
fn from(from: UInt<$from, BITS>) -> Self {
let _ = CompileTimeAssert::<BITS, { <$into>::BITS as usize }>::SMALLER_OR_EQUAL;
const { if BITS > <$from>::BITS as usize {
panic!("Can not call from() to convert between the given bit widths.");
} };
from.value as $into
}
}
Expand Down Expand Up @@ -1768,7 +1777,7 @@ macro_rules! boolu1 {
match value.value() {
0 => false,
1 => true,
_ => panic!("arbitrary_int_type already validates that this is unreachable"), //TODO: unreachable!() is not const yet
_ => unreachable!(),
}
}
}
Expand Down

0 comments on commit 8e11918

Please sign in to comment.