Merge rust-bitcoin/rust-bitcoin#1000: Replace runtime size check with compile time check
7a3bb7d3ec
Replace runtime size check with compile time check (Tobin C. Harding) Pull request description: Add a macro `const_assert` that uses some const declaration trickery to trigger a compile time error if a boolean expression is false. Replace runtime checks using `debug_assert_eq!` with the newly defined `const_asert!` macro. ## Note This PR is the first patch from a [recently closed PR](https://github.com/rust-bitcoin/rust-bitcoin/pull/953). Props to @elichai for the macro idea in the review of that PR. ACKs for top commit: Kixunil: ACK7a3bb7d3ec
apoelstra: ACK7a3bb7d3ec
Tree-SHA512: cfd4dcf6c66e06796cab6dc49445f0f8c5d4e686893a17735420dccedd75ad7c632d240a5ab92ee47ce459b799daeaf3fdf9c6b77c1b81b09e87197a9f86c5ba
This commit is contained in:
commit
18033f7db8
|
@ -242,7 +242,7 @@ macro_rules! decoder_fn {
|
||||||
($name:ident, $val_type:ty, $readfn:ident, $byte_len: expr) => {
|
($name:ident, $val_type:ty, $readfn:ident, $byte_len: expr) => {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $name(&mut self) -> Result<$val_type, Error> {
|
fn $name(&mut self) -> Result<$val_type, Error> {
|
||||||
debug_assert_eq!(::core::mem::size_of::<$val_type>(), $byte_len); // size_of isn't a constfn in 1.22
|
const_assert!(::core::mem::size_of::<$val_type>() == $byte_len);
|
||||||
let mut val = [0; $byte_len];
|
let mut val = [0; $byte_len];
|
||||||
self.read_exact(&mut val[..]).map_err(Error::Io)?;
|
self.read_exact(&mut val[..]).map_err(Error::Io)?;
|
||||||
Ok(endian::$readfn(&val))
|
Ok(endian::$readfn(&val))
|
||||||
|
|
|
@ -593,3 +593,12 @@ macro_rules! write_err {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Asserts a boolean expression at compile time.
|
||||||
|
macro_rules! const_assert {
|
||||||
|
($x:expr) => {
|
||||||
|
{
|
||||||
|
const _: [(); 0 - !$x as usize] = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ macro_rules! define_be_to_array {
|
||||||
($name: ident, $type: ty, $byte_len: expr) => {
|
($name: ident, $type: ty, $byte_len: expr) => {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn $name(val: $type) -> [u8; $byte_len] {
|
pub fn $name(val: $type) -> [u8; $byte_len] {
|
||||||
debug_assert_eq!(::core::mem::size_of::<$type>(), $byte_len); // size_of isn't a constfn in 1.22
|
const_assert!(::core::mem::size_of::<$type>() == $byte_len);
|
||||||
let mut res = [0; $byte_len];
|
let mut res = [0; $byte_len];
|
||||||
for i in 0..$byte_len {
|
for i in 0..$byte_len {
|
||||||
res[i] = ((val >> ($byte_len - i - 1)*8) & 0xff) as u8;
|
res[i] = ((val >> ($byte_len - i - 1)*8) & 0xff) as u8;
|
||||||
|
@ -41,7 +41,7 @@ macro_rules! define_le_to_array {
|
||||||
($name: ident, $type: ty, $byte_len: expr) => {
|
($name: ident, $type: ty, $byte_len: expr) => {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn $name(val: $type) -> [u8; $byte_len] {
|
pub fn $name(val: $type) -> [u8; $byte_len] {
|
||||||
debug_assert_eq!(::core::mem::size_of::<$type>(), $byte_len); // size_of isn't a constfn in 1.22
|
const_assert!(::core::mem::size_of::<$type>() == $byte_len);
|
||||||
let mut res = [0; $byte_len];
|
let mut res = [0; $byte_len];
|
||||||
for i in 0..$byte_len {
|
for i in 0..$byte_len {
|
||||||
res[i] = ((val >> i*8) & 0xff) as u8;
|
res[i] = ((val >> i*8) & 0xff) as u8;
|
||||||
|
|
Loading…
Reference in New Issue