Repository: rust-bitcoin/rust-bitcoin (language: rust)

Issue:
hashes: The `hex` optional dependency is unconditionally enabled in `std` feature
We are missing the `?`.

Noticed here: https://github.com/rust-bitcoin/rust-bitcoin/pull/3961#discussion_r1948702033


Discussion / hints:

Fix patch:
diff --git a/hashes/Cargo.toml b/hashes/Cargo.toml
index 35760c87e1..25e213790d 100644
--- a/hashes/Cargo.toml
+++ b/hashes/Cargo.toml
@@ -15,8 +15,8 @@ exclude = ["tests", "contrib"]
 
 [features]
 default = ["std"]
-std = ["alloc", "hex/std"]
-alloc = ["hex/alloc"]
+std = ["alloc", "hex?/std"]
+alloc = ["hex?/alloc"]
 serde = ["dep:serde", "hex"]
 # Smaller (but slower) implementation of sha256, sha512 and ripemd160
 small-hash = []
diff --git a/hashes/src/cmp.rs b/hashes/src/cmp.rs
index b19aeb4003..3a72b389ff 100644
--- a/hashes/src/cmp.rs
+++ b/hashes/src/cmp.rs
@@ -95,6 +95,7 @@ mod tests {
 }
 
 #[cfg(bench)]
+#[cfg(feature = "hex")]
 mod benches {
     use test::Bencher;
 
diff --git a/hashes/src/hash160/mod.rs b/hashes/src/hash160/mod.rs
index fd2e366c20..d70ec275d3 100644
--- a/hashes/src/hash160/mod.rs
+++ b/hashes/src/hash160/mod.rs
@@ -47,6 +47,7 @@ impl crate::HashEngine for HashEngine {
 mod tests {
     #[test]
     #[cfg(feature = "alloc")]
+    #[cfg(feature = "hex")]
     fn test() {
         use alloc::string::ToString;
 
diff --git a/hashes/src/hkdf/mod.rs b/hashes/src/hkdf/mod.rs
index f9f027857c..5df8722d1a 100644
--- a/hashes/src/hkdf/mod.rs
+++ b/hashes/src/hkdf/mod.rs
@@ -107,6 +107,7 @@ where
 
 #[cfg(test)]
 #[cfg(feature = "alloc")]
+#[cfg(feature = "hex")]
 mod tests {
     use hex::prelude::{DisplayHex, FromHex};
 
diff --git a/hashes/src/lib.rs b/hashes/src/lib.rs
index 0324da01a5..f4fb6fd446 100644
--- a/hashes/src/lib.rs
+++ b/hashes/src/lib.rs
@@ -326,6 +326,7 @@ mod tests {
 
     #[test]
     #[cfg(feature = "alloc")]
+    #[cfg(feature = "hex")]
     fn newtype_fmt_roundtrip() {
         use alloc::format;
 
diff --git a/hashes/src/sha256d/mod.rs b/hashes/src/sha256d/mod.rs
index 003801d998..54943db517 100644
--- a/hashes/src/sha256d/mod.rs
+++ b/hashes/src/sha256d/mod.rs
@@ -45,6 +45,7 @@ mod tests {
 
     #[test]
     #[cfg(feature = "alloc")]
+    #[cfg(feature = "hex")]
     fn test() {
         use alloc::string::ToString;
 
@@ -98,6 +99,7 @@ mod tests {
 
     #[test]
     #[cfg(feature = "alloc")]
+    #[cfg(feature = "hex")]
     fn fmt_roundtrips() {
         use alloc::format;
 
diff --git a/hashes/src/sha256t/mod.rs b/hashes/src/sha256t/mod.rs
index e2461eebff..5f4ce2fe1b 100644
--- a/hashes/src/sha256t/mod.rs
+++ b/hashes/src/sha256t/mod.rs
@@ -182,10 +182,12 @@ mod tests {
 
     // The digest created by sha256 hashing `&[0]` starting with `TEST_MIDSTATE`.
     #[cfg(feature = "alloc")]
+    #[cfg(feature = "hex")]
     const HASH_ZERO_BACKWARD: &str =
         "29589d5122ec666ab5b4695070b6debc63881a4f85d88d93ddc90078038213ed";
     // And the same thing, forward.
     #[cfg(feature = "alloc")]
+    #[cfg(feature = "hex")]
     const HASH_ZERO_FORWARD: &str =
         "ed1382037800c9dd938dd8854f1a8863bcdeb6705069b4b56a66ec22519d5829";
 
@@ -198,10 +200,12 @@ mod tests {
 
     // We support manually implementing `Tag` and creating a tagged hash from it.
     #[cfg(feature = "alloc")]
+    #[cfg(feature = "hex")]
     pub type TestHash = sha256t::Hash<TestHashTag>;
 
     #[test]
     #[cfg(feature = "alloc")]
+    #[cfg(feature = "hex")]
     fn manually_created_sha256t_hash_type() {
         use alloc::string::ToString;
 
diff --git a/hashes/src/sha384/mod.rs b/hashes/src/sha384/mod.rs
index 200bf9f6ea..c20b356dcd 100644
--- a/hashes/src/sha384/mod.rs
+++ b/hashes/src/sha384/mod.rs
@@ -41,6 +41,7 @@ impl crate::HashEngine for HashEngine {
 mod tests {
     #[test]
     #[cfg(feature = "alloc")]
+    #[cfg(feature = "hex")]
     fn test() {
         use alloc::string::ToString;
 
diff --git a/hashes/src/sha512_256/mod.rs b/hashes/src/sha512_256/mod.rs
index 3452508f03..40b4ca6517 100644
--- a/hashes/src/sha512_256/mod.rs
+++ b/hashes/src/sha512_256/mod.rs
@@ -51,6 +51,7 @@ impl crate::HashEngine for HashEngine {
 mod tests {
     #[test]
     #[cfg(feature = "alloc")]
+    #[cfg(feature = "hex")]
     fn test() {
         use alloc::string::ToString;
 
diff --git a/io/Cargo.toml b/io/Cargo.toml
index d245121da6..f59c35e00c 100644
--- a/io/Cargo.toml
+++ b/io/Cargo.toml
@@ -23,6 +23,9 @@ internals = { package = "bitcoin-internals", version = "0.4.0" }
 
 hashes = { package = "bitcoin_hashes", version = "0.16.0", default-features = false, optional = true }
 
+[dev-dependencies]
+hashes = { package = "bitcoin_hashes", version = "0.16.0", default-features = false, features = ["hex"] }
+
 [package.metadata.docs.rs]
 all-features = true
 rustdoc-args = ["--cfg", "docsrs"]


Test patch:
diff --git a/hashes/src/ripemd160/tests.rs b/hashes/src/ripemd160/tests.rs
index d6340591cc..3b9a324b68 100644
--- a/hashes/src/ripemd160/tests.rs
+++ b/hashes/src/ripemd160/tests.rs
@@ -1,5 +1,6 @@
 #[test]
 #[cfg(feature = "alloc")]
+#[cfg(feature = "hex")]
 fn test() {
     use alloc::string::ToString;
 
diff --git a/hashes/src/sha1/tests.rs b/hashes/src/sha1/tests.rs
index 2bfe37b1cf..ce30cd3342 100644
--- a/hashes/src/sha1/tests.rs
+++ b/hashes/src/sha1/tests.rs
@@ -1,5 +1,6 @@
 #[test]
 #[cfg(feature = "alloc")]
+#[cfg(feature = "hex")]
 fn test() {
     use alloc::string::ToString;
 
diff --git a/hashes/src/sha256/tests.rs b/hashes/src/sha256/tests.rs
index 65f166e17e..4e45ae6545 100644
--- a/hashes/src/sha256/tests.rs
+++ b/hashes/src/sha256/tests.rs
@@ -5,6 +5,7 @@ use crate::{sha256, HashEngine};
 
 #[test]
 #[cfg(feature = "alloc")]
+#[cfg(feature = "hex")]
 fn test() {
     use alloc::string::ToString;
 
@@ -70,6 +71,7 @@ fn test() {
 
 #[test]
 #[cfg(feature = "alloc")]
+#[cfg(feature = "hex")]
 fn fmt_roundtrips() {
     use alloc::format;
 
diff --git a/hashes/src/sha512/tests.rs b/hashes/src/sha512/tests.rs
index 4b46f01760..ecf78582b2 100644
--- a/hashes/src/sha512/tests.rs
+++ b/hashes/src/sha512/tests.rs
@@ -1,5 +1,6 @@
 #[test]
 #[cfg(feature = "alloc")]
+#[cfg(feature = "hex")]
 fn test() {
     use alloc::string::ToString;