Repository: rust-bitcoin/rust-bitcoin
Pull request #3728 (2024-12-11 05:45:06)

units: Unify and flesh out ops impls
Sort out `Add`, `AddAssign`, `Sub`, and `SubAssign` for the following types:

- `Amount` 
- `SignedAmount`
- `FeeRate`
- `Weight`

And clean up as we go.

Note that `BlockInterval` isn't touched in this PR - it looks correct already.

The unit tests in the two patches "Add ops tests ..." can be moved if you want to verify that they don't build without the patch they follow.

apoelstra: In cb66457279e9e407f8cfad8ba38ab0d55fe5d398:

I'm skeptical that being more explicit here helps readability. `Add` means "adding self to self" while `Add<T>` means "adding two different types". So this makes the reader do a double-take.

In 9a647c75fdbac27d4776c182b7de446a65eca66b:

trailing whitespace after `&T` in two places.

Otherwise 679fbe119eca05a323720baa9539e4e869bd28b7 looks good.
tcharding: > I'm skeptical that being more explicit here helps readability.

No worries I can remove it. FWIW the explicitness made it easier for me to scan the 4 impls and see that they did

- T T
- T &T
- &T T
- &T &T
tcharding: Converting to draft to sort out the api files once and for all.
tcharding: > I'm skeptical that being more explicit here helps readability. 

FTR my argument is invalidated because we move 3 of the 4 imlps to macros (the one under discussion is left on its own).
apoelstra: Needs rebase.

Patch:
diff --git a/api/units/all-features.txt b/api/units/all-features.txt
index 8205d61f..4ec25b59 100644
--- a/api/units/all-features.txt
+++ b/api/units/all-features.txt
@@ -477,15 +477,24 @@ impl core::ops::arith::Add for bitcoin_units::SignedAmount
 impl core::ops::arith::Add for bitcoin_units::block::BlockInterval
 impl core::ops::arith::Add for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::Add for bitcoin_units::weight::Weight
+impl core::ops::arith::Add<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::Add<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::Add<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Add<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
+impl core::ops::arith::Add<bitcoin_units::Amount> for &bitcoin_units::Amount
+impl core::ops::arith::Add<bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl core::ops::arith::Add<bitcoin_units::block::BlockInterval> for bitcoin_units::block::BlockHeight
 impl core::ops::arith::Add<bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Add<bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
 impl core::ops::arith::AddAssign for bitcoin_units::Amount
 impl core::ops::arith::AddAssign for bitcoin_units::SignedAmount
 impl core::ops::arith::AddAssign for bitcoin_units::block::BlockInterval
 impl core::ops::arith::AddAssign for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::AddAssign for bitcoin_units::weight::Weight
+impl core::ops::arith::AddAssign<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::AddAssign<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::AddAssign<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::AddAssign<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
 impl core::ops::arith::Div for bitcoin_units::weight::Weight
 impl core::ops::arith::Div<bitcoin_units::weight::Weight> for bitcoin_units::Amount
 impl core::ops::arith::Div<i64> for bitcoin_units::SignedAmount
@@ -514,15 +523,24 @@ impl core::ops::arith::Sub for bitcoin_units::block::BlockHeight
 impl core::ops::arith::Sub for bitcoin_units::block::BlockInterval
 impl core::ops::arith::Sub for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::Sub for bitcoin_units::weight::Weight
+impl core::ops::arith::Sub<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::Sub<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::Sub<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Sub<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
+impl core::ops::arith::Sub<bitcoin_units::Amount> for &bitcoin_units::Amount
+impl core::ops::arith::Sub<bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl core::ops::arith::Sub<bitcoin_units::block::BlockInterval> for bitcoin_units::block::BlockHeight
 impl core::ops::arith::Sub<bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Sub<bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
 impl core::ops::arith::SubAssign for bitcoin_units::Amount
 impl core::ops::arith::SubAssign for bitcoin_units::SignedAmount
 impl core::ops::arith::SubAssign for bitcoin_units::block::BlockInterval
 impl core::ops::arith::SubAssign for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::SubAssign for bitcoin_units::weight::Weight
+impl core::ops::arith::SubAssign<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::SubAssign<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::SubAssign<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::SubAssign<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
 impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_units::Amount
 impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_units::SignedAmount
 impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_units::amount::Denomination
@@ -613,8 +631,14 @@ impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::SignedAmount> for bit
 impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::block::BlockInterval> for bitcoin_units::block::BlockInterval
 impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
 impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
+impl<'a> core::ops::arith::Add<&'a bitcoin_units::Amount> for &bitcoin_units::Amount
+impl<'a> core::ops::arith::Add<&'a bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl<'a> core::ops::arith::Add<&'a bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl<'a> core::ops::arith::Add<&'a bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
+impl<'a> core::ops::arith::Sub<&'a bitcoin_units::Amount> for &bitcoin_units::Amount
+impl<'a> core::ops::arith::Sub<&'a bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl<'a> core::ops::arith::Sub<&'a bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl<'a> core::ops::arith::Sub<&'a bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
 impl<'de> serde::de::Deserialize<'de> for bitcoin_units::block::BlockHeight
 impl<'de> serde::de::Deserialize<'de> for bitcoin_units::block::BlockInterval
 impl<'de> serde::de::Deserialize<'de> for bitcoin_units::fee_rate::FeeRate
@@ -743,14 +767,28 @@ pub const fn bitcoin_units::weight::Weight::to_kwu_floor(self) -> u64
 pub const fn bitcoin_units::weight::Weight::to_vbytes_ceil(self) -> u64
 pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64
 pub const fn bitcoin_units::weight::Weight::to_wu(self) -> u64
-pub fn &bitcoin_units::fee_rate::FeeRate::add(self, other: &'a bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
-pub fn &bitcoin_units::fee_rate::FeeRate::add(self, other: bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
-pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, other: &'a bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
-pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, other: bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
+pub fn &bitcoin_units::Amount::add(self, rhs: &'a bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::Amount::add(self, rhs: bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::Amount::sub(self, rhs: &'a bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::Amount::sub(self, rhs: bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::add(self, rhs: &'a bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::add(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::sub(self, rhs: &'a bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::sub(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::add(self, rhs: &'a bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::add(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, rhs: &'a bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::add(self, rhs: &'a bitcoin_units::weight::Weight) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::add(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::sub(self, rhs: &'a bitcoin_units::weight::Weight) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::sub(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
 pub fn T::checked_sum(self) -> core::option::Option<bitcoin_units::Amount>
 pub fn T::checked_sum(self) -> core::option::Option<bitcoin_units::SignedAmount>
+pub fn bitcoin_units::Amount::add(self, rhs: &bitcoin_units::Amount) -> Self::Output
 pub fn bitcoin_units::Amount::add(self, rhs: bitcoin_units::Amount) -> Self::Output
-pub fn bitcoin_units::Amount::add_assign(&mut self, other: bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::add_assign(&mut self, rhs: &bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::add_assign(&mut self, rhs: bitcoin_units::Amount)
 pub fn bitcoin_units::Amount::arbitrary(u: &mut arbitrary::unstructured::Unstructured<'a>) -> arbitrary::error::Result<Self>
 pub fn bitcoin_units::Amount::clone(&self) -> bitcoin_units::Amount
 pub fn bitcoin_units::Amount::cmp(&self, other: &bitcoin_units::Amount) -> core::cmp::Ordering
@@ -783,8 +821,10 @@ pub fn bitcoin_units::Amount::ser_sat<S: serde::ser::Serializer>(self, s: S, _:
 pub fn bitcoin_units::Amount::ser_sat_opt<S: serde::ser::Serializer>(self, s: S, _: private::Token) -> core::result::Result<<S as serde::ser::Serializer>::Ok, <S as serde::ser::Serializer>::Error>
 pub fn bitcoin_units::Amount::ser_str<S: serde::ser::Serializer>(self, s: S, _: private::Token) -> core::result::Result<<S as serde::ser::Serializer>::Ok, <S as serde::ser::Serializer>::Error>
 pub fn bitcoin_units::Amount::ser_str_opt<S: serde::ser::Serializer>(self, s: S, _: private::Token) -> core::result::Result<<S as serde::ser::Serializer>::Ok, <S as serde::ser::Serializer>::Error>
+pub fn bitcoin_units::Amount::sub(self, rhs: &bitcoin_units::Amount) -> Self::Output
 pub fn bitcoin_units::Amount::sub(self, rhs: bitcoin_units::Amount) -> Self::Output
-pub fn bitcoin_units::Amount::sub_assign(&mut self, other: bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::sub_assign(&mut self, rhs: &bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::sub_assign(&mut self, rhs: bitcoin_units::Amount)
 pub fn bitcoin_units::Amount::sum<I: core::iter::traits::iterator::Iterator<Item = Self>>(iter: I) -> Self
 pub fn bitcoin_units::Amount::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::Amount>
 pub fn bitcoin_units::Amount::to_btc(self) -> f64
@@ -797,8 +837,10 @@ pub fn bitcoin_units::Amount::type_prefix(_: private::Token) -> &'static str
 pub fn bitcoin_units::Amount::unchecked_add(self, rhs: bitcoin_units::Amount) -> bitcoin_units::Amount
 pub fn bitcoin_units::Amount::unchecked_sub(self, rhs: bitcoin_units::Amount) -> bitcoin_units::Amount
 pub fn bitcoin_units::SignedAmount::abs(self) -> bitcoin_units::SignedAmount
+pub fn bitcoin_units::SignedAmount::add(self, rhs: &bitcoin_units::SignedAmount) -> Self::Output
 pub fn bitcoin_units::SignedAmount::add(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
-pub fn bitcoin_units::SignedAmount::add_assign(&mut self, other: bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::add_assign(&mut self, rhs: &bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::add_assign(&mut self, rhs: bitcoin_units::SignedAmount)
 pub fn bitcoin_units::SignedAmount::arbitrary(u: &mut arbitrary::unstructured::Unstructured<'a>) -> arbitrary::error::Result<Self>
 pub fn bitcoin_units::SignedAmount::clone(&self) -> bitcoin_units::SignedAmount
 pub fn bitcoin_units::SignedAmount::cmp(&self, other: &bitcoin_units::SignedAmount) -> core::cmp::Ordering
@@ -835,8 +877,10 @@ pub fn bitcoin_units::SignedAmount::ser_sat_opt<S: serde::ser::Serializer>(self,
 pub fn bitcoin_units::SignedAmount::ser_str<S: serde::ser::Serializer>(self, s: S, _: private::Token) -> core::result::Result<<S as serde::ser::Serializer>::Ok, <S as serde::ser::Serializer>::Error>
 pub fn bitcoin_units::SignedAmount::ser_str_opt<S: serde::ser::Serializer>(self, s: S, _: private::Token) -> core::result::Result<<S as serde::ser::Serializer>::Ok, <S as serde::ser::Serializer>::Error>
 pub fn bitcoin_units::SignedAmount::signum(self) -> i64
+pub fn bitcoin_units::SignedAmount::sub(self, rhs: &bitcoin_units::SignedAmount) -> Self::Output
 pub fn bitcoin_units::SignedAmount::sub(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
-pub fn bitcoin_units::SignedAmount::sub_assign(&mut self, other: bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::sub_assign(&mut self, rhs: &bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::sub_assign(&mut self, rhs: bitcoin_units::SignedAmount)
 pub fn bitcoin_units::SignedAmount::sum<I: core::iter::traits::iterator::Iterator<Item = Self>>(iter: I) -> Self
 pub fn bitcoin_units::SignedAmount::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::SignedAmount>
 pub fn bitcoin_units::SignedAmount::to_btc(self) -> f64
@@ -977,10 +1021,10 @@ pub fn bitcoin_units::block::BlockInterval::try_from(s: alloc::string::String) -
 pub fn bitcoin_units::block::TooBigForRelativeBlockHeightError::clone(&self) -> bitcoin_units::block::TooBigForRelativeBlockHeightError
 pub fn bitcoin_units::block::TooBigForRelativeBlockHeightError::eq(&self, other: &bitcoin_units::block::TooBigForRelativeBlockHeightError) -> bool
 pub fn bitcoin_units::block::TooBigForRelativeBlockHeightError::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
-pub fn bitcoin_units::fee_rate::FeeRate::add(self, other: &bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
+pub fn bitcoin_units::fee_rate::FeeRate::add(self, rhs: &bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::add(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::add_assign(&mut self, rhs: &bitcoin_units::fee_rate::FeeRate)
-pub fn bitcoin_units::fee_rate::FeeRate::add_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::fee_rate::FeeRate::add_assign(&mut self, rhs: bitcoin_units::fee_rate::FeeRate)
 pub fn bitcoin_units::fee_rate::FeeRate::arbitrary(u: &mut arbitrary::unstructured::Unstructured<'a>) -> arbitrary::error::Result<Self>
 pub fn bitcoin_units::fee_rate::FeeRate::clone(&self) -> bitcoin_units::fee_rate::FeeRate
 pub fn bitcoin_units::fee_rate::FeeRate::cmp(&self, other: &bitcoin_units::fee_rate::FeeRate) -> core::cmp::Ordering
@@ -995,10 +1039,10 @@ pub fn bitcoin_units::fee_rate::FeeRate::hash<__H: core::hash::Hasher>(&self, st
 pub fn bitcoin_units::fee_rate::FeeRate::mul(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::partial_cmp(&self, other: &bitcoin_units::fee_rate::FeeRate) -> core::option::Option<core::cmp::Ordering>
 pub fn bitcoin_units::fee_rate::FeeRate::serialize<__S>(&self, __serializer: __S) -> core::result::Result<<__S as serde::ser::Serializer>::Ok, <__S as serde::ser::Serializer>::Error> where __S: serde::ser::Serializer
-pub fn bitcoin_units::fee_rate::FeeRate::sub(self, other: &bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
+pub fn bitcoin_units::fee_rate::FeeRate::sub(self, rhs: &bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::sub(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::sub_assign(&mut self, rhs: &bitcoin_units::fee_rate::FeeRate)
-pub fn bitcoin_units::fee_rate::FeeRate::sub_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::fee_rate::FeeRate::sub_assign(&mut self, rhs: bitcoin_units::fee_rate::FeeRate)
 pub fn bitcoin_units::fee_rate::FeeRate::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::fee_rate::FeeRate>
 pub fn bitcoin_units::fee_rate::FeeRate::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = Self>
 pub fn bitcoin_units::fee_rate::FeeRate::try_from(s: &str) -> core::result::Result<Self, Self::Error>
@@ -1103,8 +1147,10 @@ pub fn bitcoin_units::parse::hex_u32_prefixed(s: &str) -> core::result::Result<u
 pub fn bitcoin_units::parse::hex_u32_unchecked(s: &str) -> core::result::Result<u32, bitcoin_units::parse::ParseIntError>
 pub fn bitcoin_units::parse::hex_u32_unprefixed(s: &str) -> core::result::Result<u32, bitcoin_units::parse::UnprefixedHexError>
 pub fn bitcoin_units::parse::int<T: bitcoin_units::parse::Integer, S: core::convert::AsRef<str> + core::convert::Into<bitcoin_internals::error::input_string::InputString>>(s: S) -> core::result::Result<T, bitcoin_units::parse::ParseIntError>
+pub fn bitcoin_units::weight::Weight::add(self, rhs: &bitcoin_units::weight::Weight) -> Self::Output
 pub fn bitcoin_units::weight::Weight::add(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
-pub fn bitcoin_units::weight::Weight::add_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::weight::Weight::add_assign(&mut self, rhs: &bitcoin_units::weight::Weight)
+pub fn bitcoin_units::weight::Weight::add_assign(&mut self, rhs: bitcoin_units::weight::Weight)
 pub fn bitcoin_units::weight::Weight::arbitrary(u: &mut arbitrary::unstructured::Unstructured<'a>) -> arbitrary::error::Result<Self>
 pub fn bitcoin_units::weight::Weight::clone(&self) -> bitcoin_units::weight::Weight
 pub fn bitcoin_units::weight::Weight::cmp(&self, other: &bitcoin_units::weight::Weight) -> core::cmp::Ordering
@@ -1122,8 +1168,10 @@ pub fn bitcoin_units::weight::Weight::mul(self, rhs: u64) -> Self::Output
 pub fn bitcoin_units::weight::Weight::mul_assign(&mut self, rhs: u64)
 pub fn bitcoin_units::weight::Weight::partial_cmp(&self, other: &bitcoin_units::weight::Weight) -> core::option::Option<core::cmp::Ordering>
 pub fn bitcoin_units::weight::Weight::serialize<__S>(&self, __serializer: __S) -> core::result::Result<<__S as serde::ser::Serializer>::Ok, <__S as serde::ser::Serializer>::Error> where __S: serde::ser::Serializer
+pub fn bitcoin_units::weight::Weight::sub(self, rhs: &bitcoin_units::weight::Weight) -> Self::Output
 pub fn bitcoin_units::weight::Weight::sub(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
-pub fn bitcoin_units::weight::Weight::sub_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::weight::Weight::sub_assign(&mut self, rhs: &bitcoin_units::weight::Weight)
+pub fn bitcoin_units::weight::Weight::sub_assign(&mut self, rhs: bitcoin_units::weight::Weight)
 pub fn bitcoin_units::weight::Weight::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::weight::Weight>
 pub fn bitcoin_units::weight::Weight::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = Self>
 pub fn bitcoin_units::weight::Weight::try_from(s: &str) -> core::result::Result<Self, Self::Error>
@@ -1197,7 +1245,10 @@ pub trait bitcoin_units::amount::CheckedSum<R>: sealed::Sealed<R>
 pub trait bitcoin_units::amount::serde::SerdeAmount: core::marker::Copy + core::marker::Sized
 pub trait bitcoin_units::amount::serde::SerdeAmountForOpt: core::marker::Copy + core::marker::Sized + bitcoin_units::amount::serde::SerdeAmount
 pub trait bitcoin_units::parse::Integer: core::str::traits::FromStr<Err = core::num::error::ParseIntError> + core::convert::TryFrom<i8> + core::marker::Sized + sealed::Sealed
+pub type &bitcoin_units::Amount::Output = bitcoin_units::Amount
+pub type &bitcoin_units::SignedAmount::Output = bitcoin_units::SignedAmount
 pub type &bitcoin_units::fee_rate::FeeRate::Output = bitcoin_units::fee_rate::FeeRate
+pub type &bitcoin_units::weight::Weight::Output = bitcoin_units::weight::Weight
 pub type bitcoin_units::Amount::Err = bitcoin_units::amount::error::ParseError
 pub type bitcoin_units::Amount::Error = bitcoin_units::amount::error::OutOfRangeError
 pub type bitcoin_units::Amount::Output = bitcoin_units::Amount
diff --git a/api/units/alloc-only.txt b/api/units/alloc-only.txt
index 8e5fed4e..691aeca9 100644
--- a/api/units/alloc-only.txt
+++ b/api/units/alloc-only.txt
@@ -455,15 +455,24 @@ impl core::ops::arith::Add for bitcoin_units::SignedAmount
 impl core::ops::arith::Add for bitcoin_units::block::BlockInterval
 impl core::ops::arith::Add for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::Add for bitcoin_units::weight::Weight
+impl core::ops::arith::Add<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::Add<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::Add<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Add<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
+impl core::ops::arith::Add<bitcoin_units::Amount> for &bitcoin_units::Amount
+impl core::ops::arith::Add<bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl core::ops::arith::Add<bitcoin_units::block::BlockInterval> for bitcoin_units::block::BlockHeight
 impl core::ops::arith::Add<bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Add<bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
 impl core::ops::arith::AddAssign for bitcoin_units::Amount
 impl core::ops::arith::AddAssign for bitcoin_units::SignedAmount
 impl core::ops::arith::AddAssign for bitcoin_units::block::BlockInterval
 impl core::ops::arith::AddAssign for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::AddAssign for bitcoin_units::weight::Weight
+impl core::ops::arith::AddAssign<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::AddAssign<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::AddAssign<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::AddAssign<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
 impl core::ops::arith::Div for bitcoin_units::weight::Weight
 impl core::ops::arith::Div<bitcoin_units::weight::Weight> for bitcoin_units::Amount
 impl core::ops::arith::Div<i64> for bitcoin_units::SignedAmount
@@ -492,15 +501,24 @@ impl core::ops::arith::Sub for bitcoin_units::block::BlockHeight
 impl core::ops::arith::Sub for bitcoin_units::block::BlockInterval
 impl core::ops::arith::Sub for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::Sub for bitcoin_units::weight::Weight
+impl core::ops::arith::Sub<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::Sub<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::Sub<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Sub<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
+impl core::ops::arith::Sub<bitcoin_units::Amount> for &bitcoin_units::Amount
+impl core::ops::arith::Sub<bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl core::ops::arith::Sub<bitcoin_units::block::BlockInterval> for bitcoin_units::block::BlockHeight
 impl core::ops::arith::Sub<bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Sub<bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
 impl core::ops::arith::SubAssign for bitcoin_units::Amount
 impl core::ops::arith::SubAssign for bitcoin_units::SignedAmount
 impl core::ops::arith::SubAssign for bitcoin_units::block::BlockInterval
 impl core::ops::arith::SubAssign for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::SubAssign for bitcoin_units::weight::Weight
+impl core::ops::arith::SubAssign<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::SubAssign<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::SubAssign<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::SubAssign<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
 impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_units::Amount
 impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_units::SignedAmount
 impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_units::amount::Denomination
@@ -579,8 +597,14 @@ impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::SignedAmount> for bit
 impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::block::BlockInterval> for bitcoin_units::block::BlockInterval
 impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
 impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
+impl<'a> core::ops::arith::Add<&'a bitcoin_units::Amount> for &bitcoin_units::Amount
+impl<'a> core::ops::arith::Add<&'a bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl<'a> core::ops::arith::Add<&'a bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl<'a> core::ops::arith::Add<&'a bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
+impl<'a> core::ops::arith::Sub<&'a bitcoin_units::Amount> for &bitcoin_units::Amount
+impl<'a> core::ops::arith::Sub<&'a bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl<'a> core::ops::arith::Sub<&'a bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl<'a> core::ops::arith::Sub<&'a bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
 impl<T> bitcoin_units::amount::CheckedSum<bitcoin_units::Amount> for T where T: core::iter::traits::iterator::Iterator<Item = bitcoin_units::Amount>
 impl<T> bitcoin_units::amount::CheckedSum<bitcoin_units::SignedAmount> for T where T: core::iter::traits::iterator::Iterator<Item = bitcoin_units::SignedAmount>
 pub bitcoin_units::amount::Denomination::Bit
@@ -701,14 +725,28 @@ pub const fn bitcoin_units::weight::Weight::to_kwu_floor(self) -> u64
 pub const fn bitcoin_units::weight::Weight::to_vbytes_ceil(self) -> u64
 pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64
 pub const fn bitcoin_units::weight::Weight::to_wu(self) -> u64
-pub fn &bitcoin_units::fee_rate::FeeRate::add(self, other: &'a bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
-pub fn &bitcoin_units::fee_rate::FeeRate::add(self, other: bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
-pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, other: &'a bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
-pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, other: bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
+pub fn &bitcoin_units::Amount::add(self, rhs: &'a bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::Amount::add(self, rhs: bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::Amount::sub(self, rhs: &'a bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::Amount::sub(self, rhs: bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::add(self, rhs: &'a bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::add(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::sub(self, rhs: &'a bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::sub(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::add(self, rhs: &'a bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::add(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, rhs: &'a bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::add(self, rhs: &'a bitcoin_units::weight::Weight) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::add(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::sub(self, rhs: &'a bitcoin_units::weight::Weight) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::sub(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
 pub fn T::checked_sum(self) -> core::option::Option<bitcoin_units::Amount>
 pub fn T::checked_sum(self) -> core::option::Option<bitcoin_units::SignedAmount>
+pub fn bitcoin_units::Amount::add(self, rhs: &bitcoin_units::Amount) -> Self::Output
 pub fn bitcoin_units::Amount::add(self, rhs: bitcoin_units::Amount) -> Self::Output
-pub fn bitcoin_units::Amount::add_assign(&mut self, other: bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::add_assign(&mut self, rhs: &bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::add_assign(&mut self, rhs: bitcoin_units::Amount)
 pub fn bitcoin_units::Amount::clone(&self) -> bitcoin_units::Amount
 pub fn bitcoin_units::Amount::cmp(&self, other: &bitcoin_units::Amount) -> core::cmp::Ordering
 pub fn bitcoin_units::Amount::default() -> Self
@@ -731,8 +769,10 @@ pub fn bitcoin_units::Amount::mul_assign(&mut self, rhs: u64)
 pub fn bitcoin_units::Amount::partial_cmp(&self, other: &bitcoin_units::Amount) -> core::option::Option<core::cmp::Ordering>
 pub fn bitcoin_units::Amount::rem(self, modulus: u64) -> Self
 pub fn bitcoin_units::Amount::rem_assign(&mut self, modulus: u64)
+pub fn bitcoin_units::Amount::sub(self, rhs: &bitcoin_units::Amount) -> Self::Output
 pub fn bitcoin_units::Amount::sub(self, rhs: bitcoin_units::Amount) -> Self::Output
-pub fn bitcoin_units::Amount::sub_assign(&mut self, other: bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::sub_assign(&mut self, rhs: &bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::sub_assign(&mut self, rhs: bitcoin_units::Amount)
 pub fn bitcoin_units::Amount::sum<I: core::iter::traits::iterator::Iterator<Item = Self>>(iter: I) -> Self
 pub fn bitcoin_units::Amount::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::Amount>
 pub fn bitcoin_units::Amount::to_btc(self) -> f64
@@ -744,8 +784,10 @@ pub fn bitcoin_units::Amount::try_from(value: bitcoin_units::SignedAmount) -> co
 pub fn bitcoin_units::Amount::unchecked_add(self, rhs: bitcoin_units::Amount) -> bitcoin_units::Amount
 pub fn bitcoin_units::Amount::unchecked_sub(self, rhs: bitcoin_units::Amount) -> bitcoin_units::Amount
 pub fn bitcoin_units::SignedAmount::abs(self) -> bitcoin_units::SignedAmount
+pub fn bitcoin_units::SignedAmount::add(self, rhs: &bitcoin_units::SignedAmount) -> Self::Output
 pub fn bitcoin_units::SignedAmount::add(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
-pub fn bitcoin_units::SignedAmount::add_assign(&mut self, other: bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::add_assign(&mut self, rhs: &bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::add_assign(&mut self, rhs: bitcoin_units::SignedAmount)
 pub fn bitcoin_units::SignedAmount::clone(&self) -> bitcoin_units::SignedAmount
 pub fn bitcoin_units::SignedAmount::cmp(&self, other: &bitcoin_units::SignedAmount) -> core::cmp::Ordering
 pub fn bitcoin_units::SignedAmount::default() -> Self
@@ -772,8 +814,10 @@ pub fn bitcoin_units::SignedAmount::positive_sub(self, rhs: bitcoin_units::Signe
 pub fn bitcoin_units::SignedAmount::rem(self, modulus: i64) -> Self
 pub fn bitcoin_units::SignedAmount::rem_assign(&mut self, modulus: i64)
 pub fn bitcoin_units::SignedAmount::signum(self) -> i64
+pub fn bitcoin_units::SignedAmount::sub(self, rhs: &bitcoin_units::SignedAmount) -> Self::Output
 pub fn bitcoin_units::SignedAmount::sub(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
-pub fn bitcoin_units::SignedAmount::sub_assign(&mut self, other: bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::sub_assign(&mut self, rhs: &bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::sub_assign(&mut self, rhs: bitcoin_units::SignedAmount)
 pub fn bitcoin_units::SignedAmount::sum<I: core::iter::traits::iterator::Iterator<Item = Self>>(iter: I) -> Self
 pub fn bitcoin_units::SignedAmount::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::SignedAmount>
 pub fn bitcoin_units::SignedAmount::to_btc(self) -> f64
@@ -882,10 +926,10 @@ pub fn bitcoin_units::block::BlockInterval::try_from(s: alloc::string::String) -
 pub fn bitcoin_units::block::TooBigForRelativeBlockHeightError::clone(&self) -> bitcoin_units::block::TooBigForRelativeBlockHeightError
 pub fn bitcoin_units::block::TooBigForRelativeBlockHeightError::eq(&self, other: &bitcoin_units::block::TooBigForRelativeBlockHeightError) -> bool
 pub fn bitcoin_units::block::TooBigForRelativeBlockHeightError::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
-pub fn bitcoin_units::fee_rate::FeeRate::add(self, other: &bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
+pub fn bitcoin_units::fee_rate::FeeRate::add(self, rhs: &bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::add(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::add_assign(&mut self, rhs: &bitcoin_units::fee_rate::FeeRate)
-pub fn bitcoin_units::fee_rate::FeeRate::add_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::fee_rate::FeeRate::add_assign(&mut self, rhs: bitcoin_units::fee_rate::FeeRate)
 pub fn bitcoin_units::fee_rate::FeeRate::clone(&self) -> bitcoin_units::fee_rate::FeeRate
 pub fn bitcoin_units::fee_rate::FeeRate::cmp(&self, other: &bitcoin_units::fee_rate::FeeRate) -> core::cmp::Ordering
 pub fn bitcoin_units::fee_rate::FeeRate::eq(&self, other: &bitcoin_units::fee_rate::FeeRate) -> bool
@@ -897,10 +941,10 @@ pub fn bitcoin_units::fee_rate::FeeRate::from_str(s: &str) -> core::result::Resu
 pub fn bitcoin_units::fee_rate::FeeRate::hash<__H: core::hash::Hasher>(&self, state: &mut __H)
 pub fn bitcoin_units::fee_rate::FeeRate::mul(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::partial_cmp(&self, other: &bitcoin_units::fee_rate::FeeRate) -> core::option::Option<core::cmp::Ordering>
-pub fn bitcoin_units::fee_rate::FeeRate::sub(self, other: &bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
+pub fn bitcoin_units::fee_rate::FeeRate::sub(self, rhs: &bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::sub(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::sub_assign(&mut self, rhs: &bitcoin_units::fee_rate::FeeRate)
-pub fn bitcoin_units::fee_rate::FeeRate::sub_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::fee_rate::FeeRate::sub_assign(&mut self, rhs: bitcoin_units::fee_rate::FeeRate)
 pub fn bitcoin_units::fee_rate::FeeRate::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::fee_rate::FeeRate>
 pub fn bitcoin_units::fee_rate::FeeRate::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = Self>
 pub fn bitcoin_units::fee_rate::FeeRate::try_from(s: &str) -> core::result::Result<Self, Self::Error>
@@ -991,8 +1035,10 @@ pub fn bitcoin_units::parse::hex_u32_prefixed(s: &str) -> core::result::Result<u
 pub fn bitcoin_units::parse::hex_u32_unchecked(s: &str) -> core::result::Result<u32, bitcoin_units::parse::ParseIntError>
 pub fn bitcoin_units::parse::hex_u32_unprefixed(s: &str) -> core::result::Result<u32, bitcoin_units::parse::UnprefixedHexError>
 pub fn bitcoin_units::parse::int<T: bitcoin_units::parse::Integer, S: core::convert::AsRef<str> + core::convert::Into<bitcoin_internals::error::input_string::InputString>>(s: S) -> core::result::Result<T, bitcoin_units::parse::ParseIntError>
+pub fn bitcoin_units::weight::Weight::add(self, rhs: &bitcoin_units::weight::Weight) -> Self::Output
 pub fn bitcoin_units::weight::Weight::add(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
-pub fn bitcoin_units::weight::Weight::add_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::weight::Weight::add_assign(&mut self, rhs: &bitcoin_units::weight::Weight)
+pub fn bitcoin_units::weight::Weight::add_assign(&mut self, rhs: bitcoin_units::weight::Weight)
 pub fn bitcoin_units::weight::Weight::clone(&self) -> bitcoin_units::weight::Weight
 pub fn bitcoin_units::weight::Weight::cmp(&self, other: &bitcoin_units::weight::Weight) -> core::cmp::Ordering
 pub fn bitcoin_units::weight::Weight::div(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
@@ -1007,8 +1053,10 @@ pub fn bitcoin_units::weight::Weight::mul(self, rhs: bitcoin_units::fee_rate::Fe
 pub fn bitcoin_units::weight::Weight::mul(self, rhs: u64) -> Self::Output
 pub fn bitcoin_units::weight::Weight::mul_assign(&mut self, rhs: u64)
 pub fn bitcoin_units::weight::Weight::partial_cmp(&self, other: &bitcoin_units::weight::Weight) -> core::option::Option<core::cmp::Ordering>
+pub fn bitcoin_units::weight::Weight::sub(self, rhs: &bitcoin_units::weight::Weight) -> Self::Output
 pub fn bitcoin_units::weight::Weight::sub(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
-pub fn bitcoin_units::weight::Weight::sub_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::weight::Weight::sub_assign(&mut self, rhs: &bitcoin_units::weight::Weight)
+pub fn bitcoin_units::weight::Weight::sub_assign(&mut self, rhs: bitcoin_units::weight::Weight)
 pub fn bitcoin_units::weight::Weight::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::weight::Weight>
 pub fn bitcoin_units::weight::Weight::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = Self>
 pub fn bitcoin_units::weight::Weight::try_from(s: &str) -> core::result::Result<Self, Self::Error>
@@ -1073,7 +1121,10 @@ pub struct bitcoin_units::parse::UnprefixedHexError(_)
 pub struct bitcoin_units::weight::Weight(_)
 pub trait bitcoin_units::amount::CheckedSum<R>: sealed::Sealed<R>
 pub trait bitcoin_units::parse::Integer: core::str::traits::FromStr<Err = core::num::error::ParseIntError> + core::convert::TryFrom<i8> + core::marker::Sized + sealed::Sealed
+pub type &bitcoin_units::Amount::Output = bitcoin_units::Amount
+pub type &bitcoin_units::SignedAmount::Output = bitcoin_units::SignedAmount
 pub type &bitcoin_units::fee_rate::FeeRate::Output = bitcoin_units::fee_rate::FeeRate
+pub type &bitcoin_units::weight::Weight::Output = bitcoin_units::weight::Weight
 pub type bitcoin_units::Amount::Err = bitcoin_units::amount::error::ParseError
 pub type bitcoin_units::Amount::Error = bitcoin_units::amount::error::OutOfRangeError
 pub type bitcoin_units::Amount::Output = bitcoin_units::Amount
diff --git a/api/units/no-features.txt b/api/units/no-features.txt
index 6ca6ce9c..86c9be56 100644
--- a/api/units/no-features.txt
+++ b/api/units/no-features.txt
@@ -439,15 +439,24 @@ impl core::ops::arith::Add for bitcoin_units::SignedAmount
 impl core::ops::arith::Add for bitcoin_units::block::BlockInterval
 impl core::ops::arith::Add for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::Add for bitcoin_units::weight::Weight
+impl core::ops::arith::Add<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::Add<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::Add<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Add<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
+impl core::ops::arith::Add<bitcoin_units::Amount> for &bitcoin_units::Amount
+impl core::ops::arith::Add<bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl core::ops::arith::Add<bitcoin_units::block::BlockInterval> for bitcoin_units::block::BlockHeight
 impl core::ops::arith::Add<bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Add<bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
 impl core::ops::arith::AddAssign for bitcoin_units::Amount
 impl core::ops::arith::AddAssign for bitcoin_units::SignedAmount
 impl core::ops::arith::AddAssign for bitcoin_units::block::BlockInterval
 impl core::ops::arith::AddAssign for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::AddAssign for bitcoin_units::weight::Weight
+impl core::ops::arith::AddAssign<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::AddAssign<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::AddAssign<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::AddAssign<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
 impl core::ops::arith::Div for bitcoin_units::weight::Weight
 impl core::ops::arith::Div<bitcoin_units::weight::Weight> for bitcoin_units::Amount
 impl core::ops::arith::Div<i64> for bitcoin_units::SignedAmount
@@ -476,15 +485,24 @@ impl core::ops::arith::Sub for bitcoin_units::block::BlockHeight
 impl core::ops::arith::Sub for bitcoin_units::block::BlockInterval
 impl core::ops::arith::Sub for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::Sub for bitcoin_units::weight::Weight
+impl core::ops::arith::Sub<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::Sub<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::Sub<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Sub<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
+impl core::ops::arith::Sub<bitcoin_units::Amount> for &bitcoin_units::Amount
+impl core::ops::arith::Sub<bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl core::ops::arith::Sub<bitcoin_units::block::BlockInterval> for bitcoin_units::block::BlockHeight
 impl core::ops::arith::Sub<bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::Sub<bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
 impl core::ops::arith::SubAssign for bitcoin_units::Amount
 impl core::ops::arith::SubAssign for bitcoin_units::SignedAmount
 impl core::ops::arith::SubAssign for bitcoin_units::block::BlockInterval
 impl core::ops::arith::SubAssign for bitcoin_units::fee_rate::FeeRate
 impl core::ops::arith::SubAssign for bitcoin_units::weight::Weight
+impl core::ops::arith::SubAssign<&bitcoin_units::Amount> for bitcoin_units::Amount
+impl core::ops::arith::SubAssign<&bitcoin_units::SignedAmount> for bitcoin_units::SignedAmount
 impl core::ops::arith::SubAssign<&bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
+impl core::ops::arith::SubAssign<&bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
 impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_units::Amount
 impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_units::SignedAmount
 impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_units::amount::Denomination
@@ -563,8 +581,14 @@ impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::SignedAmount> for bit
 impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::block::BlockInterval> for bitcoin_units::block::BlockInterval
 impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::fee_rate::FeeRate> for bitcoin_units::fee_rate::FeeRate
 impl<'a> core::iter::traits::accum::Sum<&'a bitcoin_units::weight::Weight> for bitcoin_units::weight::Weight
+impl<'a> core::ops::arith::Add<&'a bitcoin_units::Amount> for &bitcoin_units::Amount
+impl<'a> core::ops::arith::Add<&'a bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl<'a> core::ops::arith::Add<&'a bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl<'a> core::ops::arith::Add<&'a bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
+impl<'a> core::ops::arith::Sub<&'a bitcoin_units::Amount> for &bitcoin_units::Amount
+impl<'a> core::ops::arith::Sub<&'a bitcoin_units::SignedAmount> for &bitcoin_units::SignedAmount
 impl<'a> core::ops::arith::Sub<&'a bitcoin_units::fee_rate::FeeRate> for &bitcoin_units::fee_rate::FeeRate
+impl<'a> core::ops::arith::Sub<&'a bitcoin_units::weight::Weight> for &bitcoin_units::weight::Weight
 impl<T> bitcoin_units::amount::CheckedSum<bitcoin_units::Amount> for T where T: core::iter::traits::iterator::Iterator<Item = bitcoin_units::Amount>
 impl<T> bitcoin_units::amount::CheckedSum<bitcoin_units::SignedAmount> for T where T: core::iter::traits::iterator::Iterator<Item = bitcoin_units::SignedAmount>
 pub bitcoin_units::amount::Denomination::Bit
@@ -683,14 +707,28 @@ pub const fn bitcoin_units::weight::Weight::to_kwu_floor(self) -> u64
 pub const fn bitcoin_units::weight::Weight::to_vbytes_ceil(self) -> u64
 pub const fn bitcoin_units::weight::Weight::to_vbytes_floor(self) -> u64
 pub const fn bitcoin_units::weight::Weight::to_wu(self) -> u64
-pub fn &bitcoin_units::fee_rate::FeeRate::add(self, other: &'a bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
-pub fn &bitcoin_units::fee_rate::FeeRate::add(self, other: bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
-pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, other: &'a bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
-pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, other: bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
+pub fn &bitcoin_units::Amount::add(self, rhs: &'a bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::Amount::add(self, rhs: bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::Amount::sub(self, rhs: &'a bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::Amount::sub(self, rhs: bitcoin_units::Amount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::add(self, rhs: &'a bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::add(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::sub(self, rhs: &'a bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::SignedAmount::sub(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::add(self, rhs: &'a bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::add(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, rhs: &'a bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::fee_rate::FeeRate::sub(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::add(self, rhs: &'a bitcoin_units::weight::Weight) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::add(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::sub(self, rhs: &'a bitcoin_units::weight::Weight) -> Self::Output
+pub fn &bitcoin_units::weight::Weight::sub(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
 pub fn T::checked_sum(self) -> core::option::Option<bitcoin_units::Amount>
 pub fn T::checked_sum(self) -> core::option::Option<bitcoin_units::SignedAmount>
+pub fn bitcoin_units::Amount::add(self, rhs: &bitcoin_units::Amount) -> Self::Output
 pub fn bitcoin_units::Amount::add(self, rhs: bitcoin_units::Amount) -> Self::Output
-pub fn bitcoin_units::Amount::add_assign(&mut self, other: bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::add_assign(&mut self, rhs: &bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::add_assign(&mut self, rhs: bitcoin_units::Amount)
 pub fn bitcoin_units::Amount::clone(&self) -> bitcoin_units::Amount
 pub fn bitcoin_units::Amount::cmp(&self, other: &bitcoin_units::Amount) -> core::cmp::Ordering
 pub fn bitcoin_units::Amount::default() -> Self
@@ -711,8 +749,10 @@ pub fn bitcoin_units::Amount::mul_assign(&mut self, rhs: u64)
 pub fn bitcoin_units::Amount::partial_cmp(&self, other: &bitcoin_units::Amount) -> core::option::Option<core::cmp::Ordering>
 pub fn bitcoin_units::Amount::rem(self, modulus: u64) -> Self
 pub fn bitcoin_units::Amount::rem_assign(&mut self, modulus: u64)
+pub fn bitcoin_units::Amount::sub(self, rhs: &bitcoin_units::Amount) -> Self::Output
 pub fn bitcoin_units::Amount::sub(self, rhs: bitcoin_units::Amount) -> Self::Output
-pub fn bitcoin_units::Amount::sub_assign(&mut self, other: bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::sub_assign(&mut self, rhs: &bitcoin_units::Amount)
+pub fn bitcoin_units::Amount::sub_assign(&mut self, rhs: bitcoin_units::Amount)
 pub fn bitcoin_units::Amount::sum<I: core::iter::traits::iterator::Iterator<Item = Self>>(iter: I) -> Self
 pub fn bitcoin_units::Amount::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::Amount>
 pub fn bitcoin_units::Amount::to_signed(self) -> core::result::Result<bitcoin_units::SignedAmount, bitcoin_units::amount::error::OutOfRangeError>
@@ -720,8 +760,10 @@ pub fn bitcoin_units::Amount::try_from(value: bitcoin_units::SignedAmount) -> co
 pub fn bitcoin_units::Amount::unchecked_add(self, rhs: bitcoin_units::Amount) -> bitcoin_units::Amount
 pub fn bitcoin_units::Amount::unchecked_sub(self, rhs: bitcoin_units::Amount) -> bitcoin_units::Amount
 pub fn bitcoin_units::SignedAmount::abs(self) -> bitcoin_units::SignedAmount
+pub fn bitcoin_units::SignedAmount::add(self, rhs: &bitcoin_units::SignedAmount) -> Self::Output
 pub fn bitcoin_units::SignedAmount::add(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
-pub fn bitcoin_units::SignedAmount::add_assign(&mut self, other: bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::add_assign(&mut self, rhs: &bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::add_assign(&mut self, rhs: bitcoin_units::SignedAmount)
 pub fn bitcoin_units::SignedAmount::clone(&self) -> bitcoin_units::SignedAmount
 pub fn bitcoin_units::SignedAmount::cmp(&self, other: &bitcoin_units::SignedAmount) -> core::cmp::Ordering
 pub fn bitcoin_units::SignedAmount::default() -> Self
@@ -746,8 +788,10 @@ pub fn bitcoin_units::SignedAmount::positive_sub(self, rhs: bitcoin_units::Signe
 pub fn bitcoin_units::SignedAmount::rem(self, modulus: i64) -> Self
 pub fn bitcoin_units::SignedAmount::rem_assign(&mut self, modulus: i64)
 pub fn bitcoin_units::SignedAmount::signum(self) -> i64
+pub fn bitcoin_units::SignedAmount::sub(self, rhs: &bitcoin_units::SignedAmount) -> Self::Output
 pub fn bitcoin_units::SignedAmount::sub(self, rhs: bitcoin_units::SignedAmount) -> Self::Output
-pub fn bitcoin_units::SignedAmount::sub_assign(&mut self, other: bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::sub_assign(&mut self, rhs: &bitcoin_units::SignedAmount)
+pub fn bitcoin_units::SignedAmount::sub_assign(&mut self, rhs: bitcoin_units::SignedAmount)
 pub fn bitcoin_units::SignedAmount::sum<I: core::iter::traits::iterator::Iterator<Item = Self>>(iter: I) -> Self
 pub fn bitcoin_units::SignedAmount::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::SignedAmount>
 pub fn bitcoin_units::SignedAmount::to_unsigned(self) -> core::result::Result<bitcoin_units::Amount, bitcoin_units::amount::error::OutOfRangeError>
@@ -848,10 +892,10 @@ pub fn bitcoin_units::block::BlockInterval::try_from(s: &str) -> core::result::R
 pub fn bitcoin_units::block::TooBigForRelativeBlockHeightError::clone(&self) -> bitcoin_units::block::TooBigForRelativeBlockHeightError
 pub fn bitcoin_units::block::TooBigForRelativeBlockHeightError::eq(&self, other: &bitcoin_units::block::TooBigForRelativeBlockHeightError) -> bool
 pub fn bitcoin_units::block::TooBigForRelativeBlockHeightError::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
-pub fn bitcoin_units::fee_rate::FeeRate::add(self, other: &bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
+pub fn bitcoin_units::fee_rate::FeeRate::add(self, rhs: &bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::add(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::add_assign(&mut self, rhs: &bitcoin_units::fee_rate::FeeRate)
-pub fn bitcoin_units::fee_rate::FeeRate::add_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::fee_rate::FeeRate::add_assign(&mut self, rhs: bitcoin_units::fee_rate::FeeRate)
 pub fn bitcoin_units::fee_rate::FeeRate::clone(&self) -> bitcoin_units::fee_rate::FeeRate
 pub fn bitcoin_units::fee_rate::FeeRate::cmp(&self, other: &bitcoin_units::fee_rate::FeeRate) -> core::cmp::Ordering
 pub fn bitcoin_units::fee_rate::FeeRate::eq(&self, other: &bitcoin_units::fee_rate::FeeRate) -> bool
@@ -863,10 +907,10 @@ pub fn bitcoin_units::fee_rate::FeeRate::from_str(s: &str) -> core::result::Resu
 pub fn bitcoin_units::fee_rate::FeeRate::hash<__H: core::hash::Hasher>(&self, state: &mut __H)
 pub fn bitcoin_units::fee_rate::FeeRate::mul(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::partial_cmp(&self, other: &bitcoin_units::fee_rate::FeeRate) -> core::option::Option<core::cmp::Ordering>
-pub fn bitcoin_units::fee_rate::FeeRate::sub(self, other: &bitcoin_units::fee_rate::FeeRate) -> <bitcoin_units::fee_rate::FeeRate as core::ops::arith::Add>::Output
+pub fn bitcoin_units::fee_rate::FeeRate::sub(self, rhs: &bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::sub(self, rhs: bitcoin_units::fee_rate::FeeRate) -> Self::Output
 pub fn bitcoin_units::fee_rate::FeeRate::sub_assign(&mut self, rhs: &bitcoin_units::fee_rate::FeeRate)
-pub fn bitcoin_units::fee_rate::FeeRate::sub_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::fee_rate::FeeRate::sub_assign(&mut self, rhs: bitcoin_units::fee_rate::FeeRate)
 pub fn bitcoin_units::fee_rate::FeeRate::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::fee_rate::FeeRate>
 pub fn bitcoin_units::fee_rate::FeeRate::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = Self>
 pub fn bitcoin_units::fee_rate::FeeRate::try_from(s: &str) -> core::result::Result<Self, Self::Error>
@@ -947,8 +991,10 @@ pub fn bitcoin_units::parse::hex_u32_prefixed(s: &str) -> core::result::Result<u
 pub fn bitcoin_units::parse::hex_u32_unchecked(s: &str) -> core::result::Result<u32, bitcoin_units::parse::ParseIntError>
 pub fn bitcoin_units::parse::hex_u32_unprefixed(s: &str) -> core::result::Result<u32, bitcoin_units::parse::UnprefixedHexError>
 pub fn bitcoin_units::parse::int<T: bitcoin_units::parse::Integer, S: core::convert::AsRef<str> + core::convert::Into<bitcoin_internals::error::input_string::InputString>>(s: S) -> core::result::Result<T, bitcoin_units::parse::ParseIntError>
+pub fn bitcoin_units::weight::Weight::add(self, rhs: &bitcoin_units::weight::Weight) -> Self::Output
 pub fn bitcoin_units::weight::Weight::add(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
-pub fn bitcoin_units::weight::Weight::add_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::weight::Weight::add_assign(&mut self, rhs: &bitcoin_units::weight::Weight)
+pub fn bitcoin_units::weight::Weight::add_assign(&mut self, rhs: bitcoin_units::weight::Weight)
 pub fn bitcoin_units::weight::Weight::clone(&self) -> bitcoin_units::weight::Weight
 pub fn bitcoin_units::weight::Weight::cmp(&self, other: &bitcoin_units::weight::Weight) -> core::cmp::Ordering
 pub fn bitcoin_units::weight::Weight::div(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
@@ -963,8 +1009,10 @@ pub fn bitcoin_units::weight::Weight::mul(self, rhs: bitcoin_units::fee_rate::Fe
 pub fn bitcoin_units::weight::Weight::mul(self, rhs: u64) -> Self::Output
 pub fn bitcoin_units::weight::Weight::mul_assign(&mut self, rhs: u64)
 pub fn bitcoin_units::weight::Weight::partial_cmp(&self, other: &bitcoin_units::weight::Weight) -> core::option::Option<core::cmp::Ordering>
+pub fn bitcoin_units::weight::Weight::sub(self, rhs: &bitcoin_units::weight::Weight) -> Self::Output
 pub fn bitcoin_units::weight::Weight::sub(self, rhs: bitcoin_units::weight::Weight) -> Self::Output
-pub fn bitcoin_units::weight::Weight::sub_assign(&mut self, rhs: Self)
+pub fn bitcoin_units::weight::Weight::sub_assign(&mut self, rhs: &bitcoin_units::weight::Weight)
+pub fn bitcoin_units::weight::Weight::sub_assign(&mut self, rhs: bitcoin_units::weight::Weight)
 pub fn bitcoin_units::weight::Weight::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = &'a bitcoin_units::weight::Weight>
 pub fn bitcoin_units::weight::Weight::sum<I>(iter: I) -> Self where I: core::iter::traits::iterator::Iterator<Item = Self>
 pub fn bitcoin_units::weight::Weight::try_from(s: &str) -> core::result::Result<Self, Self::Error>
@@ -1027,7 +1075,10 @@ pub struct bitcoin_units::parse::UnprefixedHexError(_)
 pub struct bitcoin_units::weight::Weight(_)
 pub trait bitcoin_units::amount::CheckedSum<R>: sealed::Sealed<R>
 pub trait bitcoin_units::parse::Integer: core::str::traits::FromStr<Err = core::num::error::ParseIntError> + core::convert::TryFrom<i8> + core::marker::Sized + sealed::Sealed
+pub type &bitcoin_units::Amount::Output = bitcoin_units::Amount
+pub type &bitcoin_units::SignedAmount::Output = bitcoin_units::SignedAmount
 pub type &bitcoin_units::fee_rate::FeeRate::Output = bitcoin_units::fee_rate::FeeRate
+pub type &bitcoin_units::weight::Weight::Output = bitcoin_units::weight::Weight
 pub type bitcoin_units::Amount::Err = bitcoin_units::amount::error::ParseError
 pub type bitcoin_units::Amount::Error = bitcoin_units::amount::error::OutOfRangeError
 pub type bitcoin_units::Amount::Output = bitcoin_units::Amount
diff --git a/units/src/amount/signed.rs b/units/src/amount/signed.rs
index 4ee898d2..ea58bf32 100644
--- a/units/src/amount/signed.rs
+++ b/units/src/amount/signed.rs
@@ -388,10 +388,8 @@ fn add(self, rhs: SignedAmount) -> Self::Output {
         self.checked_add(rhs).expect("SignedAmount addition error")
     }
 }
-
-impl ops::AddAssign for SignedAmount {
-    fn add_assign(&mut self, other: SignedAmount) { *self = *self + other }
-}
+crate::internal_macros::impl_add_for_references!(SignedAmount);
+crate::internal_macros::impl_add_assign!(SignedAmount);
 
 impl ops::Sub for SignedAmount {
     type Output = SignedAmount;
@@ -400,10 +398,8 @@ fn sub(self, rhs: SignedAmount) -> Self::Output {
         self.checked_sub(rhs).expect("SignedAmount subtraction error")
     }
 }
-
-impl ops::SubAssign for SignedAmount {
-    fn sub_assign(&mut self, other: SignedAmount) { *self = *self - other }
-}
+crate::internal_macros::impl_sub_for_references!(SignedAmount);
+crate::internal_macros::impl_sub_assign!(SignedAmount);
 
 impl ops::Rem<i64> for SignedAmount {
     type Output = SignedAmount;
diff --git a/units/src/amount/unsigned.rs b/units/src/amount/unsigned.rs
index 6bd45f14..87f1553c 100644
--- a/units/src/amount/unsigned.rs
+++ b/units/src/amount/unsigned.rs
@@ -457,10 +457,8 @@ fn add(self, rhs: Amount) -> Self::Output {
         self.checked_add(rhs).expect("Amount addition error")
     }
 }
-
-impl ops::AddAssign for Amount {
-    fn add_assign(&mut self, other: Amount) { *self = *self + other }
-}
+crate::internal_macros::impl_add_for_references!(Amount);
+crate::internal_macros::impl_add_assign!(Amount);
 
 impl ops::Sub for Amount {
     type Output = Amount;
@@ -469,10 +467,8 @@ fn sub(self, rhs: Amount) -> Self::Output {
         self.checked_sub(rhs).expect("Amount subtraction error")
     }
 }
-
-impl ops::SubAssign for Amount {
-    fn sub_assign(&mut self, other: Amount) { *self = *self - other }
-}
+crate::internal_macros::impl_sub_for_references!(Amount);
+crate::internal_macros::impl_sub_assign!(Amount);
 
 impl ops::Rem<u64> for Amount {
     type Output = Amount;
diff --git a/units/src/fee_rate.rs b/units/src/fee_rate.rs
index d6b4c33c..6700434c 100644
--- a/units/src/fee_rate.rs
+++ b/units/src/fee_rate.rs
@@ -2,8 +2,7 @@
 
 //! Implements `FeeRate` and assoctiated features.
 
-use core::fmt;
-use core::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
+use core::{fmt, ops};
 
 #[cfg(feature = "arbitrary")]
 use arbitrary::{Arbitrary, Unstructured};
@@ -185,56 +184,24 @@ impl From<FeeRate> for u64 {
     fn from(value: FeeRate) -> Self { value.to_sat_per_kwu() }
 }
 
-impl Add for FeeRate {
+impl ops::Add for FeeRate {
     type Output = FeeRate;
 
     fn add(self, rhs: FeeRate) -> Self::Output { FeeRate(self.0 + rhs.0) }
 }
+crate::internal_macros::impl_add_for_references!(FeeRate);
+crate::internal_macros::impl_add_assign!(FeeRate);
 
-impl Add<FeeRate> for &FeeRate {
-    type Output = FeeRate;
-
-    fn add(self, other: FeeRate) -> <FeeRate as Add>::Output { FeeRate(self.0 + other.0) }
-}
-
-impl Add<&FeeRate> for FeeRate {
-    type Output = FeeRate;
-
-    fn add(self, other: &FeeRate) -> <FeeRate as Add>::Output { FeeRate(self.0 + other.0) }
-}
-
-impl<'a> Add<&'a FeeRate> for &FeeRate {
-    type Output = FeeRate;
-
-    fn add(self, other: &'a FeeRate) -> <FeeRate as Add>::Output { FeeRate(self.0 + other.0) }
-}
-
-impl Sub for FeeRate {
+impl ops::Sub for FeeRate {
     type Output = FeeRate;
 
     fn sub(self, rhs: FeeRate) -> Self::Output { FeeRate(self.0 - rhs.0) }
 }
-
-impl Sub<FeeRate> for &FeeRate {
-    type Output = FeeRate;
-
-    fn sub(self, other: FeeRate) -> <FeeRate as Add>::Output { FeeRate(self.0 - other.0) }
-}
-
-impl Sub<&FeeRate> for FeeRate {
-    type Output = FeeRate;
-
-    fn sub(self, other: &FeeRate) -> <FeeRate as Add>::Output { FeeRate(self.0 - other.0) }
-}
-
-impl<'a> Sub<&'a FeeRate> for &FeeRate {
-    type Output = FeeRate;
-
-    fn sub(self, other: &'a FeeRate) -> <FeeRate as Add>::Output { FeeRate(self.0 - other.0) }
-}
+crate::internal_macros::impl_sub_for_references!(FeeRate);
+crate::internal_macros::impl_sub_assign!(FeeRate);
 
 /// Computes the ceiling so that the fee computation is conservative.
-impl Mul<FeeRate> for Weight {
+impl ops::Mul<FeeRate> for Weight {
     type Output = Amount;
 
     fn mul(self, rhs: FeeRate) -> Self::Output {
@@ -242,13 +209,13 @@ fn mul(self, rhs: FeeRate) -> Self::Output {
     }
 }
 
-impl Mul<Weight> for FeeRate {
+impl ops::Mul<Weight> for FeeRate {
     type Output = Amount;
 
     fn mul(self, rhs: Weight) -> Self::Output { rhs * self }
 }
 
-impl Div<Weight> for Amount {
+impl ops::Div<Weight> for Amount {
     type Output = FeeRate;
 
     /// Truncating integer division.
@@ -258,22 +225,6 @@ impl Div<Weight> for Amount {
     fn div(self, rhs: Weight) -> Self::Output { FeeRate(self.to_sat() * 1000 / rhs.to_wu()) }
 }
 
-impl AddAssign for FeeRate {
-    fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0 }
-}
-
-impl AddAssign<&FeeRate> for FeeRate {
-    fn add_assign(&mut self, rhs: &FeeRate) { self.0 += rhs.0 }
-}
-
-impl SubAssign for FeeRate {
-    fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0 }
-}
-
-impl SubAssign<&FeeRate> for FeeRate {
-    fn sub_assign(&mut self, rhs: &FeeRate) { self.0 -= rhs.0 }
-}
-
 impl core::iter::Sum for FeeRate {
     fn sum<I>(iter: I) -> Self
     where
diff --git a/units/src/internal_macros.rs b/units/src/internal_macros.rs
new file mode 100644
index 00000000..03536b5e
--- /dev/null
+++ b/units/src/internal_macros.rs
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: CC0-1.0
+
+//! Internal macros.
+//!
+//! Macros meant to be used inside the `bitcoin-units` library.
+
+/// Implements `ops::Add` for various references.
+///
+/// Requires `$ty` it implement `Add` e.g. 'impl Add<T> for T'. Adds impls of:
+///
+/// - Add<T> for &T
+/// - Add<&T> for T
+/// - Add<&T> for &T
+macro_rules! impl_add_for_references {
+    ($ty:ident) => {
+        impl core::ops::Add<$ty> for &$ty {
+            type Output = $ty;
+
+            fn add(self, rhs: $ty) -> Self::Output { *self + rhs }
+        }
+
+        impl core::ops::Add<&$ty> for $ty {
+            type Output = $ty;
+
+            fn add(self, rhs: &$ty) -> Self::Output { self + *rhs }
+        }
+
+        impl<'a> core::ops::Add<&'a $ty> for &$ty {
+            type Output = $ty;
+
+            fn add(self, rhs: &'a $ty) -> Self::Output { *self + *rhs }
+        }
+    }
+}
+pub(crate) use impl_add_for_references;
+
+/// Implement `ops::AddAssign` for `$ty` and `&$ty`.
+macro_rules! impl_add_assign {
+    ($ty:ident) => {
+         impl core::ops::AddAssign<$ty> for $ty {
+            fn add_assign(&mut self, rhs: $ty) { *self = *self + rhs }
+        }
+
+        impl core::ops::AddAssign<&$ty> for $ty {
+            fn add_assign(&mut self, rhs: &$ty) { *self = *self + *rhs }
+        }
+    }
+}
+pub(crate) use impl_add_assign;
+
+/// Implement `ops::Sub` for various references.
+///
+/// Requires `$ty` it implement `Sub` e.g. 'impl Sub<T> for T'. Adds impls of:
+///
+/// - Sub<T> for &T
+/// - Sub<&T> for T
+/// - Sub<&T> for &T
+macro_rules! impl_sub_for_references {
+    ($ty:ident) => {
+        impl core::ops::Sub<$ty> for &$ty {
+            type Output = $ty;
+
+            fn sub(self, rhs: $ty) -> Self::Output { *self - rhs }
+        }
+
+        impl core::ops::Sub<&$ty> for $ty {
+            type Output = $ty;
+
+            fn sub(self, rhs: &$ty) -> Self::Output { self - *rhs }
+        }
+
+        impl<'a> core::ops::Sub<&'a $ty> for &$ty {
+            type Output = $ty;
+
+            fn sub(self, rhs: &'a $ty) -> Self::Output { *self - *rhs }
+        }
+    }
+}
+pub(crate) use impl_sub_for_references;
+
+/// Implement `ops::SubAssign` for `$ty` and `&$ty`.
+macro_rules! impl_sub_assign {
+    ($ty:ident) => {
+         impl core::ops::SubAssign<$ty> for $ty {
+            fn sub_assign(&mut self, rhs: $ty) { *self = *self - rhs }
+        }
+
+        impl core::ops::SubAssign<&$ty> for $ty {
+            fn sub_assign(&mut self, rhs: &$ty) { *self = *self - *rhs }
+        }
+   }
+}
+pub(crate) use impl_sub_assign;
diff --git a/units/src/lib.rs b/units/src/lib.rs
index f97bc430..ffcbfa3d 100644
--- a/units/src/lib.rs
+++ b/units/src/lib.rs
@@ -23,6 +23,8 @@
 #[cfg(feature = "std")]
 extern crate std;
 
+mod internal_macros;
+
 #[doc(hidden)]
 pub mod _export {
     /// A re-export of core::*
diff --git a/units/src/weight.rs b/units/src/weight.rs
index a8b1e94c..9c8b9d8a 100644
--- a/units/src/weight.rs
+++ b/units/src/weight.rs
@@ -2,8 +2,7 @@
 
 //! Implements `Weight` and associated features.
 
-use core::fmt;
-use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
+use core::{fmt, ops};
 
 #[cfg(feature = "arbitrary")]
 use arbitrary::{Arbitrary, Unstructured};
@@ -167,55 +166,51 @@ impl From<Weight> for u64 {
     fn from(value: Weight) -> Self { value.to_wu() }
 }
 
-impl Add for Weight {
+impl ops::Add for Weight {
     type Output = Weight;
 
     fn add(self, rhs: Weight) -> Self::Output { Weight(self.0 + rhs.0) }
 }
+crate::internal_macros::impl_add_for_references!(Weight);
+crate::internal_macros::impl_add_assign!(Weight);
 
-impl AddAssign for Weight {
-    fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0 }
-}
-
-impl Sub for Weight {
+impl ops::Sub for Weight {
     type Output = Weight;
 
     fn sub(self, rhs: Weight) -> Self::Output { Weight(self.0 - rhs.0) }
 }
+crate::internal_macros::impl_sub_for_references!(Weight);
+crate::internal_macros::impl_sub_assign!(Weight);
 
-impl SubAssign for Weight {
-    fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0 }
-}
-
-impl Mul<u64> for Weight {
+impl ops::Mul<u64> for Weight {
     type Output = Weight;
 
     fn mul(self, rhs: u64) -> Self::Output { Weight(self.0 * rhs) }
 }
 
-impl Mul<Weight> for u64 {
+impl ops::Mul<Weight> for u64 {
     type Output = Weight;
 
     fn mul(self, rhs: Weight) -> Self::Output { Weight(self * rhs.0) }
 }
 
-impl MulAssign<u64> for Weight {
+impl ops::MulAssign<u64> for Weight {
     fn mul_assign(&mut self, rhs: u64) { self.0 *= rhs }
 }
 
-impl Div<u64> for Weight {
+impl ops::Div<u64> for Weight {
     type Output = Weight;
 
     fn div(self, rhs: u64) -> Self::Output { Weight(self.0 / rhs) }
 }
 
-impl Div<Weight> for Weight {
+impl ops::Div<Weight> for Weight {
     type Output = u64;
 
     fn div(self, rhs: Weight) -> Self::Output { self.to_wu() / rhs.to_wu() }
 }
 
-impl DivAssign<u64> for Weight {
+impl ops::DivAssign<u64> for Weight {
     fn div_assign(&mut self, rhs: u64) { self.0 /= rhs }
 }
 
@@ -362,4 +357,52 @@ fn checked_div() {
 
     #[test]
     fn checked_div_overflows() { assert!(TWO.checked_div(0).is_none()) }
+
+    #[test]
+    #[allow(clippy::op_ref)]
+    fn addition() {
+        let one = Weight(1);
+        let two = Weight(2);
+        let three = Weight(3);
+
+        assert!(one + two == three);
+        assert!(&one + two == three);
+        assert!(one + &two == three);
+        assert!(&one + &two == three);
+    }
+
+    #[test]
+    #[allow(clippy::op_ref)]
+    fn subtract() {
+        let one = Weight(1);
+        let two = Weight(2);
+        let three = Weight(3);
+
+        assert!(three - two == one);
+        assert!(&three - two == one);
+        assert!(three - &two == one);
+        assert!(&three - &two == one);
+    }
+
+    #[test]
+    fn add_assign() {
+        let mut f = Weight(1);
+        f += Weight(2);
+        assert_eq!(f, Weight(3));
+
+        let mut f = Weight(1);
+        f += &Weight(2);
+        assert_eq!(f, Weight(3));
+    }
+
+    #[test]
+    fn sub_assign() {
+        let mut f = Weight(3);
+        f -= Weight(2);
+        assert_eq!(f, Weight(1));
+
+        let mut f = Weight(3);
+        f -= &Weight(2);
+        assert_eq!(f, Weight(1));
+    }
 }


Test patch:
diff --git a/units/src/amount/tests.rs b/units/src/amount/tests.rs
index 9d3687f6..ac4237ac 100644
--- a/units/src/amount/tests.rs
+++ b/units/src/amount/tests.rs
@@ -977,3 +977,99 @@ fn trailing_zeros_for_amount() {
     assert_eq!(format!("{}", Amount::from_sat(400_000_000_000_010)), "4000000.0000001 BTC");
     assert_eq!(format!("{}", Amount::from_sat(400_000_000_000_000)), "4000000 BTC");
 }
+
+#[test]
+#[allow(clippy::op_ref)]
+fn unsigned_addition() {
+    let one = Amount::from_sat(1);
+    let two = Amount::from_sat(2);
+    let three = Amount::from_sat(3);
+
+    assert!(one + two == three);
+    assert!(&one + two == three);
+    assert!(one + &two == three);
+    assert!(&one + &two == three);
+}
+
+#[test]
+#[allow(clippy::op_ref)]
+fn unsigned_subtract() {
+    let one = Amount::from_sat(1);
+    let two = Amount::from_sat(2);
+    let three = Amount::from_sat(3);
+
+    assert!(three - two == one);
+    assert!(&three - two == one);
+    assert!(three - &two == one);
+    assert!(&three - &two == one);
+}
+
+#[test]
+fn unsigned_add_assign() {
+    let mut f = Amount::from_sat(1);
+    f += Amount::from_sat(2);
+    assert_eq!(f, Amount::from_sat(3));
+
+    let mut f = Amount::from_sat(1);
+    f += &Amount::from_sat(2);
+    assert_eq!(f, Amount::from_sat(3));
+}
+
+#[test]
+fn unsigned_sub_assign() {
+    let mut f = Amount::from_sat(3);
+    f -= Amount::from_sat(2);
+    assert_eq!(f, Amount::from_sat(1));
+
+    let mut f = Amount::from_sat(3);
+    f -= &Amount::from_sat(2);
+    assert_eq!(f, Amount::from_sat(1));
+}
+
+#[test]
+#[allow(clippy::op_ref)]
+fn signed_addition() {
+    let one = SignedAmount::from_sat(1);
+    let two = SignedAmount::from_sat(2);
+    let three = SignedAmount::from_sat(3);
+
+    assert!(one + two == three);
+    assert!(&one + two == three);
+    assert!(one + &two == three);
+    assert!(&one + &two == three);
+}
+
+#[test]
+#[allow(clippy::op_ref)]
+fn signed_subtract() {
+    let one = SignedAmount::from_sat(1);
+    let two = SignedAmount::from_sat(2);
+    let three = SignedAmount::from_sat(3);
+
+    assert!(three - two == one);
+    assert!(&three - two == one);
+    assert!(three - &two == one);
+    assert!(&three - &two == one);
+}
+
+#[test]
+fn signed_add_assign() {
+    let mut f = SignedAmount::from_sat(1);
+    f += SignedAmount::from_sat(2);
+    assert_eq!(f, SignedAmount::from_sat(3));
+
+    let mut f = SignedAmount::from_sat(1);
+    f += &SignedAmount::from_sat(2);
+    assert_eq!(f, SignedAmount::from_sat(3));
+}
+
+#[test]
+fn signed_sub_assign() {
+    let mut f = SignedAmount::from_sat(3);
+    f -= SignedAmount::from_sat(2);
+    assert_eq!(f, SignedAmount::from_sat(1));
+
+    let mut f = SignedAmount::from_sat(3);
+    f -= &SignedAmount::from_sat(2);
+    assert_eq!(f, SignedAmount::from_sat(1));
+}