From c155cbf8b2d400dbaf807dd781b317fca5ca6b35 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Wed, 19 Jun 2024 16:21:19 +0000 Subject: [PATCH] hashes: use workaround to get constfns on tagged hashes with MSRV As you can see from the - lines in the API diff, there is no reduction in API surface (we just remove the T:Tag bound from the sha256t::Tag type, which is not strictly necessary but maybe we would prefer to keep). --- api/hashes/all-features.txt | 6 ++++-- api/hashes/alloc-only.txt | 6 ++++-- api/hashes/no-features.txt | 6 ++++-- hashes/src/sha256t.rs | 29 ++++++++++++++++++++++++----- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/api/hashes/all-features.txt b/api/hashes/all-features.txt index 6b14979d1..8d6e86a63 100644 --- a/api/hashes/all-features.txt +++ b/api/hashes/all-features.txt @@ -5,7 +5,7 @@ #[repr(transparent)] pub struct bitcoin_hashes::sha1::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha256::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha256d::Hash(_) -#[repr(transparent)] pub struct bitcoin_hashes::sha256t::Hash(_, _) +#[repr(transparent)] pub struct bitcoin_hashes::sha256t::Hash(_, _) #[repr(transparent)] pub struct bitcoin_hashes::sha384::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha512::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha512_256::Hash(_) @@ -431,7 +431,6 @@ impl core::marker::StructuralPartialEq for bitcoin_hash impl std::io::Write for bitcoin_hashes::hmac::HmacEngine impl bitcoin_hashes::Hash for bitcoin_hashes::sha256t::Hash impl bitcoin_hashes::serde_macros::serde_details::SerdeHash for bitcoin_hashes::sha256t::Hash -impl bitcoin_hashes::sha256t::Hash impl core::borrow::Borrow<[u8]> for bitcoin_hashes::sha256t::Hash impl core::clone::Clone for bitcoin_hashes::sha256t::Hash impl core::cmp::Eq for bitcoin_hashes::sha256t::Hash @@ -458,6 +457,8 @@ impl core::cmp::PartialEq for bi impl core::cmp::PartialOrd for bitcoin_hashes::hmac::Hmac impl core::hash::Hash for bitcoin_hashes::hmac::Hmac impl core::marker::Copy for bitcoin_hashes::hmac::Hmac +impl bitcoin_hashes::sha256t::Hash where (T): bitcoin_hashes::sha256t::Tag +impl bitcoin_hashes::sha256t::Tag for (T) where T: bitcoin_hashes::sha256t::Tag impl core::marker::Freeze for bitcoin_hashes::hkdf::Hkdf where T: core::marker::Freeze impl core::marker::Freeze for bitcoin_hashes::hmac::Hmac where T: core::marker::Freeze impl core::marker::Freeze for bitcoin_hashes::hmac::HmacEngine where ::Engine: core::marker::Freeze @@ -578,6 +579,7 @@ pub const fn bitcoin_hashes::siphash24::HashEngine::new() -> bitcoin_hashes::sip pub const fn bitcoin_hashes::siphash24::HashEngine::with_keys(k0: u64, k1: u64) -> bitcoin_hashes::siphash24::HashEngine pub extern crate bitcoin_hashes::hex pub extern crate bitcoin_hashes::serde +pub fn (T)::engine() -> bitcoin_hashes::sha256::HashEngine pub fn bitcoin_hashes::FromSliceError::clone(&self) -> bitcoin_hashes::FromSliceError pub fn bitcoin_hashes::FromSliceError::eq(&self, other: &bitcoin_hashes::FromSliceError) -> bool pub fn bitcoin_hashes::FromSliceError::expected_length(&self) -> usize diff --git a/api/hashes/alloc-only.txt b/api/hashes/alloc-only.txt index f03fb2d6b..7ad1838d9 100644 --- a/api/hashes/alloc-only.txt +++ b/api/hashes/alloc-only.txt @@ -5,7 +5,7 @@ #[repr(transparent)] pub struct bitcoin_hashes::sha1::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha256::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha256d::Hash(_) -#[repr(transparent)] pub struct bitcoin_hashes::sha256t::Hash(_, _) +#[repr(transparent)] pub struct bitcoin_hashes::sha256t::Hash(_, _) #[repr(transparent)] pub struct bitcoin_hashes::sha384::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha512::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha512_256::Hash(_) @@ -373,7 +373,6 @@ impl core::fmt::Display for bitcoin_hashes::hmac::Hmac< impl core::fmt::LowerHex for bitcoin_hashes::hmac::Hmac impl core::marker::StructuralPartialEq for bitcoin_hashes::hmac::Hmac impl bitcoin_hashes::Hash for bitcoin_hashes::sha256t::Hash -impl bitcoin_hashes::sha256t::Hash impl core::borrow::Borrow<[u8]> for bitcoin_hashes::sha256t::Hash impl core::clone::Clone for bitcoin_hashes::sha256t::Hash impl core::cmp::Eq for bitcoin_hashes::sha256t::Hash @@ -398,6 +397,8 @@ impl core::cmp::PartialEq for bi impl core::cmp::PartialOrd for bitcoin_hashes::hmac::Hmac impl core::hash::Hash for bitcoin_hashes::hmac::Hmac impl core::marker::Copy for bitcoin_hashes::hmac::Hmac +impl bitcoin_hashes::sha256t::Hash where (T): bitcoin_hashes::sha256t::Tag +impl bitcoin_hashes::sha256t::Tag for (T) where T: bitcoin_hashes::sha256t::Tag impl core::marker::Freeze for bitcoin_hashes::hkdf::Hkdf where T: core::marker::Freeze impl core::marker::Freeze for bitcoin_hashes::hmac::Hmac where T: core::marker::Freeze impl core::marker::Freeze for bitcoin_hashes::hmac::HmacEngine where ::Engine: core::marker::Freeze @@ -505,6 +506,7 @@ pub const fn bitcoin_hashes::siphash24::Hash::to_byte_array(self) -> [u8; 8] pub const fn bitcoin_hashes::siphash24::HashEngine::new() -> bitcoin_hashes::siphash24::HashEngine pub const fn bitcoin_hashes::siphash24::HashEngine::with_keys(k0: u64, k1: u64) -> bitcoin_hashes::siphash24::HashEngine pub extern crate bitcoin_hashes::hex +pub fn (T)::engine() -> bitcoin_hashes::sha256::HashEngine pub fn bitcoin_hashes::FromSliceError::clone(&self) -> bitcoin_hashes::FromSliceError pub fn bitcoin_hashes::FromSliceError::eq(&self, other: &bitcoin_hashes::FromSliceError) -> bool pub fn bitcoin_hashes::FromSliceError::expected_length(&self) -> usize diff --git a/api/hashes/no-features.txt b/api/hashes/no-features.txt index 225243502..5afb2220b 100644 --- a/api/hashes/no-features.txt +++ b/api/hashes/no-features.txt @@ -5,7 +5,7 @@ #[repr(transparent)] pub struct bitcoin_hashes::sha1::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha256::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha256d::Hash(_) -#[repr(transparent)] pub struct bitcoin_hashes::sha256t::Hash(_, _) +#[repr(transparent)] pub struct bitcoin_hashes::sha256t::Hash(_, _) #[repr(transparent)] pub struct bitcoin_hashes::sha384::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha512::Hash(_) #[repr(transparent)] pub struct bitcoin_hashes::sha512_256::Hash(_) @@ -373,7 +373,6 @@ impl core::fmt::Display for bitcoin_hashes::hmac::Hmac< impl core::fmt::LowerHex for bitcoin_hashes::hmac::Hmac impl core::marker::StructuralPartialEq for bitcoin_hashes::hmac::Hmac impl bitcoin_hashes::Hash for bitcoin_hashes::sha256t::Hash -impl bitcoin_hashes::sha256t::Hash impl core::borrow::Borrow<[u8]> for bitcoin_hashes::sha256t::Hash impl core::clone::Clone for bitcoin_hashes::sha256t::Hash impl core::cmp::Eq for bitcoin_hashes::sha256t::Hash @@ -398,6 +397,8 @@ impl core::cmp::PartialEq for bi impl core::cmp::PartialOrd for bitcoin_hashes::hmac::Hmac impl core::hash::Hash for bitcoin_hashes::hmac::Hmac impl core::marker::Copy for bitcoin_hashes::hmac::Hmac +impl bitcoin_hashes::sha256t::Hash where (T): bitcoin_hashes::sha256t::Tag +impl bitcoin_hashes::sha256t::Tag for (T) where T: bitcoin_hashes::sha256t::Tag impl core::marker::Freeze for bitcoin_hashes::hkdf::Hkdf where T: core::marker::Freeze impl core::marker::Freeze for bitcoin_hashes::hmac::Hmac where T: core::marker::Freeze impl core::marker::Freeze for bitcoin_hashes::hmac::HmacEngine where ::Engine: core::marker::Freeze @@ -505,6 +506,7 @@ pub const fn bitcoin_hashes::siphash24::Hash::to_byte_array(self) -> [u8; 8] pub const fn bitcoin_hashes::siphash24::HashEngine::new() -> bitcoin_hashes::siphash24::HashEngine pub const fn bitcoin_hashes::siphash24::HashEngine::with_keys(k0: u64, k1: u64) -> bitcoin_hashes::siphash24::HashEngine pub extern crate bitcoin_hashes::hex +pub fn (T)::engine() -> bitcoin_hashes::sha256::HashEngine pub fn bitcoin_hashes::FromSliceError::clone(&self) -> bitcoin_hashes::FromSliceError pub fn bitcoin_hashes::FromSliceError::eq(&self, other: &bitcoin_hashes::FromSliceError) -> bool pub fn bitcoin_hashes::FromSliceError::expected_length(&self) -> usize diff --git a/hashes/src/sha256t.rs b/hashes/src/sha256t.rs index adbba8253..1d72da43f 100644 --- a/hashes/src/sha256t.rs +++ b/hashes/src/sha256t.rs @@ -19,7 +19,7 @@ pub trait Tag { /// Output of the SHA256t hash function. #[repr(transparent)] -pub struct Hash([u8; 32], PhantomData); +pub struct Hash([u8; 32], PhantomData); #[cfg(feature = "schemars")] impl schemars::JsonSchema for Hash { @@ -36,8 +36,24 @@ impl schemars::JsonSchema for Hash { } } -impl Hash { - fn internal_new(arr: [u8; 32]) -> Self { Hash(arr, Default::default()) } +// This impl, and the trait bound `(T,): Tag` below, are hacks to allow defining +// constfns on Hash for a generic T. This trick was discovered by +// https://github.com/rust-lang/rust/issues/90912 +// +// When we drop rustc 1.56.1 we will be able to remove this, which will be a +// technically breaking change but in practice probably fine to just drop. +impl Tag for (T,) +where + T: Tag, +{ + fn engine() -> sha256::HashEngine { T::engine() } +} + +impl Hash +where + (T,): Tag, +{ + fn internal_new(arr: [u8; 32]) -> Self { Hash(arr, PhantomData) } /// Zero cost conversion between a fixed length byte array shared reference and /// a shared reference to this Hash type. @@ -54,7 +70,7 @@ impl Hash { } /// Constructs a new engine. - pub fn engine() -> HashEngine { T::engine() } + pub fn engine() -> HashEngine { <(T,)>::engine() } /// Produces a hash from the current state of a given engine. pub fn from_engine(e: HashEngine) -> Hash { from_engine(e) } @@ -135,7 +151,10 @@ impl core::hash::Hash for Hash { crate::internal_macros::hash_trait_impls!(256, false, T: Tag); -fn from_engine(e: sha256::HashEngine) -> Hash { +fn from_engine(e: sha256::HashEngine) -> Hash +where + (T,): Tag, +{ Hash::from_byte_array(sha256::Hash::from_engine(e).to_byte_array()) }