units: Add explicit None return impl for std::error::Error
What changed, and why it matters
This commit is a pure code-style/documentation change. It replaces empty default implementations of Rust's standard error trait with explicit implementations that return 'no underlying cause' (None). The behavior is identical before and after; nothing about security or program logic changes.
No security action needed. Treat as a normal maintainability/refactor commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch changes impl std::error::Error for T {} to impl std::error::Error for T { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } } across multiple error types in the units crate. The source method has a default implementation returning None, so this is a non-functional refactor intended to make the default behavior explicit for readability. No unsafe code, no API changes, no behavioral changes, and no security fixes are present.
Changed components
units/src/amount/error.rsunits/src/block.rsunits/src/fee_rate/serde.rsunits/src/locktime/absolute/error.rsunits/src/locktime/relative/error.rsunits/src/parse_int.rsunits/src/result.rsInspect captured patch +51 / −17
diff --git a/units/src/amount/error.rs b/units/src/amount/error.rs
index e0bf6007..61fef986 100644
--- a/units/src/amount/error.rs
+++ b/units/src/amount/error.rs
@@ -185,7 +185,9 @@ impl fmt::Display for OutOfRangeError {
}
#[cfg(feature = "std")]
-impl std::error::Error for OutOfRangeError {}
+impl std::error::Error for OutOfRangeError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
/// Error returned when the input string has higher precision than satoshis.
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -211,7 +213,9 @@ impl fmt::Display for TooPreciseError {
}
#[cfg(feature = "std")]
-impl std::error::Error for TooPreciseError {}
+impl std::error::Error for TooPreciseError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
/// Error returned when the input string is too large.
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -241,7 +245,9 @@ impl fmt::Display for InputTooLargeError {
}
#[cfg(feature = "std")]
-impl std::error::Error for InputTooLargeError {}
+impl std::error::Error for InputTooLargeError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
/// Error returned when digits were expected in the input but there were none.
///
@@ -266,7 +272,9 @@ impl fmt::Display for MissingDigitsError {
}
#[cfg(feature = "std")]
-impl std::error::Error for MissingDigitsError {}
+impl std::error::Error for MissingDigitsError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
#[derive(Debug, Clone, Eq, PartialEq)]
pub(super) enum MissingDigitsKind {
@@ -300,7 +308,9 @@ impl fmt::Display for InvalidCharacterError {
}
#[cfg(feature = "std")]
-impl std::error::Error for InvalidCharacterError {}
+impl std::error::Error for InvalidCharacterError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
/// Error returned when a valid character (e.g. '_') is in an invalid/bad position.
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -330,7 +340,9 @@ impl fmt::Display for BadPositionError {
}
#[cfg(feature = "std")]
-impl std::error::Error for BadPositionError {}
+impl std::error::Error for BadPositionError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
/// An error during amount parsing.
#[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/units/src/block.rs b/units/src/block.rs
index 7753bf36..7f73652b 100644
--- a/units/src/block.rs
+++ b/units/src/block.rs
@@ -645,7 +645,9 @@ pub mod error {
}
#[cfg(feature = "std")]
- impl std::error::Error for TooBigForRelativeHeightError {}
+ impl std::error::Error for TooBigForRelativeHeightError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+ }
/// An error consensus decoding an `BlockHeight`.
#[cfg(feature = "encoding")]
diff --git a/units/src/fee_rate/serde.rs b/units/src/fee_rate/serde.rs
index 975fff72..53b11b09 100644
--- a/units/src/fee_rate/serde.rs
+++ b/units/src/fee_rate/serde.rs
@@ -422,4 +422,6 @@ impl fmt::Display for OverflowError {
}
#[cfg(feature = "std")]
-impl std::error::Error for OverflowError {}
+impl std::error::Error for OverflowError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
diff --git a/units/src/locktime/absolute/error.rs b/units/src/locktime/absolute/error.rs
index 957abde8..1cc49c4a 100644
--- a/units/src/locktime/absolute/error.rs
+++ b/units/src/locktime/absolute/error.rs
@@ -68,7 +68,9 @@ impl fmt::Display for IncompatibleHeightError {
}
#[cfg(feature = "std")]
-impl std::error::Error for IncompatibleHeightError {}
+impl std::error::Error for IncompatibleHeightError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
/// Tried to satisfy a lock-by-height lock using a height value.
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -103,7 +105,9 @@ impl fmt::Display for IncompatibleTimeError {
}
#[cfg(feature = "std")]
-impl std::error::Error for IncompatibleTimeError {}
+impl std::error::Error for IncompatibleTimeError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
/// Error returned when parsing block height fails.
#[derive(Debug, Clone, Eq, PartialEq)]
diff --git a/units/src/locktime/relative/error.rs b/units/src/locktime/relative/error.rs
index 9ab5daee..dff5bead 100644
--- a/units/src/locktime/relative/error.rs
+++ b/units/src/locktime/relative/error.rs
@@ -33,7 +33,9 @@ impl fmt::Display for DisabledLockTimeError {
}
#[cfg(feature = "std")]
-impl std::error::Error for DisabledLockTimeError {}
+impl std::error::Error for DisabledLockTimeError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
/// Error returned when attempting to satisfy lock fails.
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -161,7 +163,9 @@ impl fmt::Display for TimeOverflowError {
}
#[cfg(feature = "std")]
-impl std::error::Error for TimeOverflowError {}
+impl std::error::Error for TimeOverflowError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
/// Error returned when `NumberOfBlocks::is_satisfied_by` is incorrectly called.
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -184,7 +188,9 @@ impl fmt::Display for InvalidHeightError {
}
#[cfg(feature = "std")]
-impl std::error::Error for InvalidHeightError {}
+impl std::error::Error for InvalidHeightError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
/// Error returned when `NumberOf512Seconds::is_satisfied_by` is incorrectly called.
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -207,7 +213,9 @@ impl fmt::Display for InvalidTimeError {
}
#[cfg(feature = "std")]
-impl std::error::Error for InvalidTimeError {}
+impl std::error::Error for InvalidTimeError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+}
#[cfg(test)]
mod tests {
diff --git a/units/src/parse_int.rs b/units/src/parse_int.rs
index 97be3e81..b02fce97 100644
--- a/units/src/parse_int.rs
+++ b/units/src/parse_int.rs
@@ -517,7 +517,9 @@ pub mod error {
}
#[cfg(feature = "std")]
- impl std::error::Error for MissingPrefixError {}
+ impl std::error::Error for MissingPrefixError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+ }
/// Error when hex string contains a prefix (e.g. 0x).
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -541,7 +543,9 @@ pub mod error {
}
#[cfg(feature = "std")]
- impl std::error::Error for ContainsPrefixError {}
+ impl std::error::Error for ContainsPrefixError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+ }
}
#[cfg(test)]
diff --git a/units/src/result.rs b/units/src/result.rs
index 42f293b9..71afd0d6 100644
--- a/units/src/result.rs
+++ b/units/src/result.rs
@@ -425,7 +425,9 @@ pub mod error {
}
#[cfg(feature = "std")]
- impl std::error::Error for NumOpError {}
+ impl std::error::Error for NumOpError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
+ }
}
#[cfg(feature = "arbitrary")]
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.