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

Issue:
Remove `impl_from_infallible`
If #3842 merges remove the macro from `internals` and fix `bitcoin` crate.


Discussion / hints:

Fix patch:
diff --git a/base58/src/error.rs b/base58/src/error.rs
index 6257056ec..c86e6dacc 100644
--- a/base58/src/error.rs
+++ b/base58/src/error.rs
@@ -3,6 +3,7 @@
 //! Error code for the `base58` crate.
 
 use core::fmt;
+use core::convert::Infallible;
 
 use internals::write_err;
 
@@ -20,8 +21,13 @@ pub(super) enum ErrorInner {
     TooShort(TooShortError),
 }
 
-internals::impl_from_infallible!(Error);
-internals::impl_from_infallible!(ErrorInner);
+impl From<Infallible> for Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl From<Infallible> for ErrorInner {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl Error {
     /// Returns the invalid base58 ssscharacter, if encountered.
@@ -95,7 +101,9 @@ pub(super) struct IncorrectChecksumError {
     pub(super) expected: u32,
 }
 
-internals::impl_from_infallible!(IncorrectChecksumError);
+impl From<Infallible> for IncorrectChecksumError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for IncorrectChecksumError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -116,8 +124,9 @@ pub(super) struct TooShortError {
     /// The length of the decoded data.
     pub(super) length: usize,
 }
-
-internals::impl_from_infallible!(TooShortError);
+impl From<Infallible> for TooShortError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for TooShortError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -141,8 +150,13 @@ pub(super) struct InvalidCharacterErrorInner {
     pub(super) invalid: u8,
 }
 
-internals::impl_from_infallible!(InvalidCharacterError);
-internals::impl_from_infallible!(InvalidCharacterErrorInner);
+impl From<Infallible> for InvalidCharacterError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl From<Infallible> for InvalidCharacterErrorInner {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl InvalidCharacterError {
     pub(super) fn new(invalid: u8) -> Self { Self(InvalidCharacterErrorInner { invalid }) }
diff --git a/bitcoin/src/address/error.rs b/bitcoin/src/address/error.rs
index 1de9e7f95..65eb34f4d 100644
--- a/bitcoin/src/address/error.rs
+++ b/bitcoin/src/address/error.rs
@@ -1,6 +1,7 @@
 //! Error code for the address module.
 
 use core::fmt;
+use core::convert::Infallible;
 
 use internals::write_err;
 
@@ -21,7 +22,9 @@ pub enum FromScriptError {
     WitnessVersion(witness_version::TryFromError),
 }
 
-internals::impl_from_infallible!(FromScriptError);
+impl From<Infallible> for FromScriptError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for FromScriptError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -84,7 +87,9 @@ pub enum ParseError {
     NetworkValidation(NetworkValidationError),
 }
 
-internals::impl_from_infallible!(ParseError);
+impl From<Infallible> for ParseError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for ParseError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -175,7 +180,9 @@ pub enum Bech32Error {
     UnknownHrp(UnknownHrpError),
 }
 
-internals::impl_from_infallible!(Bech32Error);
+impl From<Infallible> for Bech32Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for Bech32Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -221,7 +228,9 @@ impl From<UnknownHrpError> for Bech32Error {
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct ParseBech32Error(pub(crate) bech32::segwit::DecodeError);
 
-internals::impl_from_infallible!(ParseBech32Error);
+impl From<Infallible> for ParseBech32Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for ParseBech32Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -248,7 +257,9 @@ pub enum Base58Error {
     InvalidLegacyPrefix(InvalidLegacyPrefixError),
 }
 
-internals::impl_from_infallible!(Base58Error);
+impl From<Infallible> for Base58Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for Base58Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/bip152.rs b/bitcoin/src/bip152.rs
index e515e3281..d2cdcaf8e 100644
--- a/bitcoin/src/bip152.rs
+++ b/bitcoin/src/bip152.rs
@@ -5,6 +5,7 @@
 //! Implementation of compact blocks data structure and algorithms.
 
 use core::{convert, fmt, mem};
+use core::convert::Infallible;
 #[cfg(feature = "std")]
 use std::error;
 
@@ -30,7 +31,9 @@ pub enum Error {
     InvalidPrefill,
 }
 
-internals::impl_from_infallible!(Error);
+impl From<Infallible> for Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/bip158.rs b/bitcoin/src/bip158.rs
index 8af3cd784..893376703 100644
--- a/bitcoin/src/bip158.rs
+++ b/bitcoin/src/bip158.rs
@@ -39,6 +39,7 @@
 
 use core::cmp::{self, Ordering};
 use core::fmt;
+use core::convert::Infallible;
 
 use hashes::{sha256d, siphash24, HashEngine as _};
 use internals::{write_err, ToU64 as _};
@@ -79,7 +80,9 @@ pub enum Error {
     Io(io::Error),
 }
 
-internals::impl_from_infallible!(Error);
+impl From<Infallible> for Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
diff --git a/bitcoin/src/bip32.rs b/bitcoin/src/bip32.rs
index 885c500d5..b02900435 100644
--- a/bitcoin/src/bip32.rs
+++ b/bitcoin/src/bip32.rs
@@ -8,6 +8,7 @@
 use core::ops::Index;
 use core::str::FromStr;
 use core::{fmt, slice};
+use core::convert::Infallible;
 
 use hashes::{hash160, hash_newtype, sha512, GeneralHash, HashEngine, Hmac, HmacEngine};
 use internals::write_err;
@@ -519,7 +520,9 @@ pub enum Error {
     InvalidBase58PayloadLength(InvalidBase58PayloadLengthError),
 }
 
-internals::impl_from_infallible!(Error);
+impl From<Infallible> for Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/blockdata/block.rs b/bitcoin/src/blockdata/block.rs
index d32e74213..e2e793565 100644
--- a/bitcoin/src/blockdata/block.rs
+++ b/bitcoin/src/blockdata/block.rs
@@ -8,6 +8,7 @@
 //! these blocks and the blockchain.
 
 use core::fmt;
+use core::convert::Infallible;
 
 use hashes::{sha256d, HashEngine};
 use internals::{compact_size, ToU64};
@@ -383,7 +384,9 @@ pub enum InvalidBlockError {
     InvalidWitnessCommitment,
 }
 
-internals::impl_from_infallible!(InvalidBlockError);
+impl From<Infallible> for InvalidBlockError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for InvalidBlockError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -413,7 +416,9 @@ pub enum Bip34Error {
     NegativeHeight,
 }
 
-internals::impl_from_infallible!(Bip34Error);
+impl From<Infallible> for Bip34Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for Bip34Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -457,7 +462,9 @@ pub enum ValidationError {
     BadTarget,
 }
 
-internals::impl_from_infallible!(ValidationError);
+impl From<Infallible> for ValidationError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for ValidationError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/blockdata/script/mod.rs b/bitcoin/src/blockdata/script/mod.rs
index 9f9284cb1..ac2a01842 100644
--- a/bitcoin/src/blockdata/script/mod.rs
+++ b/bitcoin/src/blockdata/script/mod.rs
@@ -58,6 +58,7 @@ pub mod witness_program;
 pub mod witness_version;
 
 use core::fmt;
+use core::convert::Infallible;
 
 use io::{BufRead, Write};
 use primitives::opcodes::all::*;
@@ -234,7 +235,9 @@ pub enum Error {
     Serialization,
 }
 
-internals::impl_from_infallible!(Error);
+impl From<Infallible> for Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/blockdata/script/witness_program.rs b/bitcoin/src/blockdata/script/witness_program.rs
index 3fe824f49..9f1448da3 100644
--- a/bitcoin/src/blockdata/script/witness_program.rs
+++ b/bitcoin/src/blockdata/script/witness_program.rs
@@ -8,6 +8,7 @@
 //! [BIP141]: <https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki>
 
 use core::fmt;
+use core::convert::Infallible;
 
 use internals::array_vec::ArrayVec;
 use secp256k1::{Secp256k1, Verification};
@@ -139,7 +140,9 @@ pub enum Error {
     InvalidSegwitV0Length(usize),
 }
 
-internals::impl_from_infallible!(Error);
+impl From<Infallible> for Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/blockdata/script/witness_version.rs b/bitcoin/src/blockdata/script/witness_version.rs
index e9a1126d3..98b6edc16 100644
--- a/bitcoin/src/blockdata/script/witness_version.rs
+++ b/bitcoin/src/blockdata/script/witness_version.rs
@@ -9,6 +9,7 @@
 
 use core::fmt;
 use core::str::FromStr;
+use core::convert::Infallible;
 
 use internals::write_err;
 use units::parse::{self, ParseIntError};
@@ -159,7 +160,9 @@ pub enum FromStrError {
     Invalid(TryFromError),
 }
 
-internals::impl_from_infallible!(FromStrError);
+impl From<Infallible> for FromStrError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for FromStrError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -202,7 +205,9 @@ pub enum TryFromInstructionError {
     DataPush,
 }
 
-internals::impl_from_infallible!(TryFromInstructionError);
+impl From<Infallible> for TryFromInstructionError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for TryFromInstructionError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/consensus/error.rs b/bitcoin/src/consensus/error.rs
index e69e75b96..500e9ecef 100644
--- a/bitcoin/src/consensus/error.rs
+++ b/bitcoin/src/consensus/error.rs
@@ -3,6 +3,7 @@
 //! Consensus encoding errors.
 
 use core::fmt;
+use core::convert::Infallible;
 
 use hex::error::{InvalidCharError, OddLengthStringError};
 use hex::DisplayHex as _;
@@ -21,7 +22,9 @@ pub enum DeserializeError {
     Unconsumed,
 }
 
-internals::impl_from_infallible!(DeserializeError);
+impl From<Infallible> for DeserializeError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for DeserializeError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -64,7 +67,9 @@ pub enum DecodeError<E> {
     Other(E), // Yielded by the inner iterator.
 }
 
-internals::impl_from_infallible!(DecodeError<E>);
+impl<E> From<Infallible> for DecodeError<E> {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl<E: fmt::Debug> fmt::Display for DecodeError<E> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -101,7 +106,9 @@ pub enum Error {
     Parse(ParseError),
 }
 
-internals::impl_from_infallible!(Error);
+impl From<Infallible> for Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -169,7 +176,9 @@ pub enum ParseError {
     UnsupportedSegwitFlag(u8),
 }
 
-internals::impl_from_infallible!(ParseError);
+impl From<Infallible> for ParseError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for ParseError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/consensus_validation.rs b/bitcoin/src/consensus_validation.rs
index 4f814c904..d3d67f0ea 100644
--- a/bitcoin/src/consensus_validation.rs
+++ b/bitcoin/src/consensus_validation.rs
@@ -5,6 +5,7 @@
 //! Relies on the `bitcoinconsensus` crate that uses Bitcoin Core libconsensus to perform validation.
 
 use core::fmt;
+use core::convert::Infallible;
 
 use internals::write_err;
 
@@ -237,7 +238,9 @@ pub enum TxVerifyError {
     UnknownSpentOutput(OutPoint),
 }
 
-internals::impl_from_infallible!(TxVerifyError);
+impl From<Infallible> for TxVerifyError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for TxVerifyError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/crypto/ecdsa.rs b/bitcoin/src/crypto/ecdsa.rs
index 2755f0b51..90e6d105e 100644
--- a/bitcoin/src/crypto/ecdsa.rs
+++ b/bitcoin/src/crypto/ecdsa.rs
@@ -6,6 +6,7 @@
 
 use core::str::FromStr;
 use core::{fmt, iter};
+use core::convert::Infallible;
 
 #[cfg(feature = "arbitrary")]
 use arbitrary::{Arbitrary, Unstructured};
@@ -213,7 +214,9 @@ pub enum DecodeError {
     Secp256k1(secp256k1::Error),
 }
 
-internals::impl_from_infallible!(DecodeError);
+impl From<Infallible> for DecodeError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for DecodeError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -258,7 +261,9 @@ pub enum ParseSignatureError {
     Decode(DecodeError),
 }
 
-internals::impl_from_infallible!(ParseSignatureError);
+impl From<Infallible> for ParseSignatureError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for ParseSignatureError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs
index ac5c8a7c3..e51350afa 100644
--- a/bitcoin/src/crypto/key.rs
+++ b/bitcoin/src/crypto/key.rs
@@ -8,6 +8,7 @@
 use core::fmt::{self, Write as _};
 use core::ops;
 use core::str::FromStr;
+use core::convert::Infallible;
 
 use hashes::hash160;
 use hex::{FromHex, HexToArrayError};
@@ -918,7 +919,9 @@ pub enum FromSliceError {
     InvalidLength(usize),
 }
 
-internals::impl_from_infallible!(FromSliceError);
+impl From<Infallible> for FromSliceError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for FromSliceError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -962,7 +965,9 @@ pub enum FromWifError {
     Secp256k1(secp256k1::Error),
 }
 
-internals::impl_from_infallible!(FromWifError);
+impl From<Infallible> for FromWifError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for FromWifError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -1022,7 +1027,9 @@ pub enum ParsePublicKeyError {
     InvalidHexLength(usize),
 }
 
-internals::impl_from_infallible!(ParsePublicKeyError);
+impl From<Infallible> for ParsePublicKeyError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for ParsePublicKeyError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -1061,7 +1068,9 @@ pub enum ParseCompressedPublicKeyError {
     Hex(hex::HexToArrayError),
 }
 
-internals::impl_from_infallible!(ParseCompressedPublicKeyError);
+impl From<Infallible> for ParseCompressedPublicKeyError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for ParseCompressedPublicKeyError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/crypto/sighash.rs b/bitcoin/src/crypto/sighash.rs
index 808b64caf..22999fd1a 100644
--- a/bitcoin/src/crypto/sighash.rs
+++ b/bitcoin/src/crypto/sighash.rs
@@ -12,6 +12,7 @@
 //! [`SighashCache`] and calling its methods.
 
 use core::{fmt, str};
+use core::convert::Infallible;
 
 #[cfg(feature = "arbitrary")]
 use arbitrary::{Arbitrary, Unstructured};
@@ -302,7 +303,9 @@ pub enum PrevoutsIndexError {
     InvalidAllIndex,
 }
 
-internals::impl_from_infallible!(PrevoutsIndexError);
+impl From<Infallible> for PrevoutsIndexError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for PrevoutsIndexError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1203,7 +1206,9 @@ pub enum TaprootError {
     InvalidSighashType(u32),
 }
 
-internals::impl_from_infallible!(TaprootError);
+impl From<Infallible> for TaprootError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for TaprootError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1262,7 +1267,9 @@ pub enum P2wpkhError {
     NotP2wpkhScript,
 }
 
-internals::impl_from_infallible!(P2wpkhError);
+impl From<Infallible> for P2wpkhError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl From<transaction::InputsIndexError> for P2wpkhError {
     fn from(value: transaction::InputsIndexError) -> Self { P2wpkhError::Sighash(value) }
@@ -1327,7 +1334,9 @@ pub enum AnnexError {
     IncorrectPrefix(u8),
 }
 
-internals::impl_from_infallible!(AnnexError);
+impl From<Infallible> for AnnexError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for AnnexError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1438,7 +1447,9 @@ pub enum SigningDataError<E> {
     Sighash(E),
 }
 
-internals::impl_from_infallible!(SigningDataError<E>);
+impl<E> From<Infallible> for SigningDataError<E> {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl<E> SigningDataError<E> {
     /// Returns the sighash variant, panicking if it's IO.
diff --git a/bitcoin/src/crypto/taproot.rs b/bitcoin/src/crypto/taproot.rs
index f050a9ec3..fed166e30 100644
--- a/bitcoin/src/crypto/taproot.rs
+++ b/bitcoin/src/crypto/taproot.rs
@@ -5,6 +5,7 @@
 //! This module provides Taproot keys used in Bitcoin (including reexporting secp256k1 keys).
 
 use core::fmt;
+use core::convert::Infallible;
 
 #[cfg(feature = "arbitrary")]
 use arbitrary::{Arbitrary, Unstructured};
@@ -96,7 +97,9 @@ pub enum SigFromSliceError {
     InvalidSignatureSize(usize),
 }
 
-internals::impl_from_infallible!(SigFromSliceError);
+impl From<Infallible> for SigFromSliceError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for SigFromSliceError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/merkle_tree/block.rs b/bitcoin/src/merkle_tree/block.rs
index 4410c8a94..d2f6bdacd 100644
--- a/bitcoin/src/merkle_tree/block.rs
+++ b/bitcoin/src/merkle_tree/block.rs
@@ -10,6 +10,7 @@
 //! Support proofs that transaction(s) belong to a block.
 
 use core::fmt;
+use core::convert::Infallible;
 
 use internals::ToU64 as _;
 use io::{BufRead, Write};
@@ -473,7 +474,9 @@ pub enum MerkleBlockError {
     IdenticalHashesFound,
 }
 
-internals::impl_from_infallible!(MerkleBlockError);
+impl From<Infallible> for MerkleBlockError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for MerkleBlockError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/psbt/error.rs b/bitcoin/src/psbt/error.rs
index 26da3e4f6..35f38146f 100644
--- a/bitcoin/src/psbt/error.rs
+++ b/bitcoin/src/psbt/error.rs
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: CC0-1.0
 
 use core::fmt;
+use core::convert::Infallible;
 
 use internals::write_err;
 
@@ -107,7 +108,9 @@ pub enum Error {
     Io(io::Error),
 }
 
-internals::impl_from_infallible!(Error);
+impl From<Infallible> for Error {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs
index 370bd61bf..dfec08fa0 100644
--- a/bitcoin/src/psbt/mod.rs
+++ b/bitcoin/src/psbt/mod.rs
@@ -14,6 +14,7 @@ pub mod raw;
 pub mod serialize;
 
 use core::{cmp, fmt};
+use core::convert::Infallible;
 #[cfg(feature = "std")]
 use std::collections::{HashMap, HashSet};
 
@@ -857,7 +858,9 @@ pub enum GetKeyError {
     NotSupported,
 }
 
-internals::impl_from_infallible!(GetKeyError);
+impl From<Infallible> for GetKeyError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for GetKeyError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -970,7 +973,9 @@ pub enum SignError {
     Unsupported,
 }
 
-internals::impl_from_infallible!(SignError);
+impl From<Infallible> for SignError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for SignError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1059,7 +1064,9 @@ pub enum ExtractTxError {
     },
 }
 
-internals::impl_from_infallible!(ExtractTxError);
+impl From<Infallible> for ExtractTxError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for ExtractTxError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1111,7 +1118,9 @@ pub enum IndexOutOfBoundsError {
     },
 }
 
-internals::impl_from_infallible!(IndexOutOfBoundsError);
+impl From<Infallible> for IndexOutOfBoundsError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for IndexOutOfBoundsError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1147,6 +1156,7 @@ impl std::error::Error for IndexOutOfBoundsError {
 mod display_from_str {
     use core::fmt;
     use core::str::FromStr;
+    use core::convert::Infallible;
 
     use base64::display::Base64Display;
     use base64::prelude::{Engine as _, BASE64_STANDARD};
@@ -1164,7 +1174,9 @@ mod display_from_str {
         Base64Encoding(::base64::DecodeError),
     }
 
-    internals::impl_from_infallible!(PsbtParseError);
+    impl From<Infallible> for PsbtParseError {
+        fn from(never: Infallible) -> Self { match never {} }
+    }
 
     impl fmt::Display for PsbtParseError {
         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/bitcoin/src/sign_message.rs b/bitcoin/src/sign_message.rs
index b93175778..979a174c9 100644
--- a/bitcoin/src/sign_message.rs
+++ b/bitcoin/src/sign_message.rs
@@ -22,6 +22,7 @@ pub const BITCOIN_SIGNED_MSG_PREFIX: &[u8] = b"\x18Bitcoin Signed Message:\n";
 #[cfg(feature = "secp-recovery")]
 mod message_signing {
     use core::fmt;
+    use core::convert::Infallible;
 
     use hashes::sha256d;
     use internals::write_err;
@@ -44,7 +45,9 @@ mod message_signing {
         UnsupportedAddressType(AddressType),
     }
 
-    internals::impl_from_infallible!(MessageSignatureError);
+    impl From<Infallible> for MessageSignatureError {
+        fn from(never: Infallible) -> Self { match never {} }
+    }
 
     impl fmt::Display for MessageSignatureError {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/bitcoin/src/taproot/mod.rs b/bitcoin/src/taproot/mod.rs
index ca5cbe115..53a3f95ea 100644
--- a/bitcoin/src/taproot/mod.rs
+++ b/bitcoin/src/taproot/mod.rs
@@ -10,6 +10,7 @@ pub mod serialized_signature;
 use core::cmp::{Ordering, Reverse};
 use core::fmt;
 use core::iter::FusedIterator;
+use core::convert::Infallible;
 
 use hashes::{sha256t, HashEngine};
 use internals::{impl_to_hex_from_lower_hex, write_err};
@@ -585,7 +586,9 @@ pub enum IncompleteBuilderError {
     HiddenParts(TaprootBuilder),
 }
 
-internals::impl_from_infallible!(IncompleteBuilderError);
+impl From<Infallible> for IncompleteBuilderError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl IncompleteBuilderError {
     /// Converts error into the original incomplete [`TaprootBuilder`] instance.
@@ -631,7 +634,9 @@ pub enum HiddenNodesError {
     HiddenParts(NodeInfo),
 }
 
-internals::impl_from_infallible!(HiddenNodesError);
+impl From<Infallible> for HiddenNodesError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl HiddenNodesError {
     /// Converts error into the original incomplete [`NodeInfo`] instance.
@@ -1341,7 +1346,9 @@ pub enum TaprootBuilderError {
     EmptyTree,
 }
 
-internals::impl_from_infallible!(TaprootBuilderError);
+impl From<Infallible> for TaprootBuilderError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for TaprootBuilderError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1398,7 +1405,9 @@ pub enum TaprootError {
     EmptyTree,
 }
 
-internals::impl_from_infallible!(TaprootError);
+impl From<Infallible> for TaprootError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for TaprootError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1454,7 +1463,9 @@ impl InvalidMerkleBranchSizeError {
     pub fn invalid_merkle_branch_size(&self) -> usize { self.0 }
 }
 
-internals::impl_from_infallible!(InvalidMerkleBranchSizeError);
+impl From<Infallible> for InvalidMerkleBranchSizeError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for InvalidMerkleBranchSizeError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1478,7 +1489,9 @@ impl InvalidMerkleTreeDepthError {
     pub fn invalid_merkle_tree_depth(&self) -> usize { self.0 }
 }
 
-internals::impl_from_infallible!(InvalidMerkleTreeDepthError);
+impl From<Infallible> for InvalidMerkleTreeDepthError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for InvalidMerkleTreeDepthError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1502,7 +1515,9 @@ impl InvalidTaprootLeafVersionError {
     pub fn invalid_leaf_version(&self) -> u8 { self.0 }
 }
 
-internals::impl_from_infallible!(InvalidTaprootLeafVersionError);
+impl From<Infallible> for InvalidTaprootLeafVersionError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for InvalidTaprootLeafVersionError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1522,7 +1537,9 @@ impl InvalidControlBlockSizeError {
     pub fn invalid_control_block_size(&self) -> usize { self.0 }
 }
 
-internals::impl_from_infallible!(InvalidControlBlockSizeError);
+impl From<Infallible> for InvalidControlBlockSizeError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for InvalidControlBlockSizeError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/internals/src/macros.rs b/internals/src/macros.rs
index ef0addd6f..69725e232 100644
--- a/internals/src/macros.rs
+++ b/internals/src/macros.rs
@@ -15,65 +15,6 @@ macro_rules! const_assert {
     }
 }
 
-/// Derives `From<core::convert::Infallible>` for the given type.
-///
-/// Supports types with arbitrary combinations of lifetimes and type parameters.
-///
-/// Note: Paths are not supported (for ex. impl_from_infallible!(Hello<D: std::fmt::Display>).
-///
-/// # Examples
-///
-/// ```rust
-/// # #[allow(unused)]
-/// # fn main() {
-/// # use core::fmt::{Display, Debug};
-/// use bitcoin_internals::impl_from_infallible;
-///
-/// enum AlphaEnum { Item }
-/// impl_from_infallible!(AlphaEnum);
-///
-/// enum BetaEnum<'b> { Item(&'b usize) }
-/// impl_from_infallible!(BetaEnum<'b>);
-///
-/// enum GammaEnum<T> { Item(T) }
-/// impl_from_infallible!(GammaEnum<T>);
-///
-/// enum DeltaEnum<'b, 'a: 'static + 'b, T: 'a, D: Debug + Display + 'a> {
-///     Item((&'b usize, &'a usize, T, D))
-/// }
-/// impl_from_infallible!(DeltaEnum<'b, 'a: 'static + 'b, T: 'a, D: Debug + Display + 'a>);
-///
-/// struct AlphaStruct;
-/// impl_from_infallible!(AlphaStruct);
-///
-/// struct BetaStruct<'b>(&'b usize);
-/// impl_from_infallible!(BetaStruct<'b>);
-///
-/// struct GammaStruct<T>(T);
-/// impl_from_infallible!(GammaStruct<T>);
-///
-/// struct DeltaStruct<'b, 'a: 'static + 'b, T: 'a, D: Debug + Display + 'a> {
-///     hello: &'a T,
-///     what: &'b D,
-/// }
-/// impl_from_infallible!(DeltaStruct<'b, 'a: 'static + 'b, T: 'a, D: Debug + Display + 'a>);
-/// # }
-/// ```
-///
-/// See <https://stackoverflow.com/a/61189128> for more information about this macro.
-#[macro_export]
-macro_rules! impl_from_infallible {
-    ( $name:ident $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? ) => {
-        impl $(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?
-            From<core::convert::Infallible>
-        for $name
-            $(< $( $lt ),+ >)?
-        {
-            fn from(never: core::convert::Infallible) -> Self { match never {} }
-        }
-    }
-}
-
 /// Adds an implementation of `pub fn to_hex(&self) -> String` if `alloc` feature is enabled.
 ///
 /// The added function allocates a `String` then calls through to [`core::fmt::LowerHex`].
diff --git a/units/src/fee_rate/serde.rs b/units/src/fee_rate/serde.rs
index 281680053..486b01fe9 100644
--- a/units/src/fee_rate/serde.rs
+++ b/units/src/fee_rate/serde.rs
@@ -23,6 +23,7 @@
 //! ```
 
 use core::fmt;
+use core::convert::Infallible;
 
 pub mod as_sat_per_kwu {
     //! Serialize and deserialize [`FeeRate`] denominated in satoshis per 1000 weight units.
@@ -243,7 +244,9 @@ pub mod as_sat_per_vb_ceil {
 #[non_exhaustive]
 pub struct OverflowError;
 
-internals::impl_from_infallible!(OverflowError);
+impl From<Infallible> for OverflowError {
+    fn from(never: Infallible) -> Self { match never {} }
+}
 
 impl fmt::Display for OverflowError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {


Test patch: