Skip to content

Commit 5d54ee3

Browse files
committed
Merge #741: Remove PartialEq impl from Error
57bbde8 remove PartialEq bound from top-level Error type (Andrew Poelstra) 3649850 tests: remove all uses of Eq on error types (Andrew Poelstra) 4f52fb7 introduce `StaticDebugAndDisplay` blanket trait, use it for all errors (Andrew Poelstra) Pull request description: This is a short PR in terms of LOC, but may be controversial. I think it is necessary though. Currently we have `PartialEq` on our giant `Error` enum (though amusingly not `Eq`) so that we can use `assert_eq` in unit tests. We can get away with this because our error enum does not contain any `std::io::Error`s anywhere, which can't be compared, nor does it contain any boxed errors. In the next couple of PRs I am going to clean up the `expression` module to make the parser non-recursive and the error types strongly typed and detailed. To do this, I want to store `<Pk as FromStr>::Err`s, which to avoid a `Pk` parameter on `Error`, will need to be boxed. When we box the type we need to declare upfront what traits the error types have, and these traits will become requirements of the `MiniscriptKey` type. It's not really reasonable to require `PartialEq` or `Eq` since these are not common traits for errors. Really the only things we *can* reasonaby require are `Debug`, `Display` and `'static`. (I would like to also require `std::error::Error` but as far as I can tell there is no way to do this while retaining both nostd compatibility and additive features. See this [users.rust-lang.org thread about this](https://users.rust-lang.org/t/how-to-box-an-error-type-retaining-std-error-only-when-std-is-enabled/)). ACKs for top commit: sanket1729: ACK 57bbde8. Tree-SHA512: 58400af38e50da8ebee39ad8cb14be3532d801311d8afd2b3854446f89d22019d2e1711d58b971244aefd0f7685b50ca3f6c2da1bcbec95c49962306cbbcf014
2 parents 51cadfc + 57bbde8 commit 5d54ee3

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

src/blanket_traits.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ use core::{fmt, hash};
1717

1818
use crate::MiniscriptKey;
1919

20+
/// Auxiliary trait indicating that a type implements both `Debug` and `Display`.
21+
pub trait StaticDebugAndDisplay: fmt::Debug + fmt::Display + 'static {}
22+
23+
impl<T: fmt::Debug + fmt::Display + 'static> StaticDebugAndDisplay for T {}
24+
2025
/// Blanket trait describing a key where all associated types implement `FromStr`,
2126
/// and all `FromStr` errors can be displayed.
2227
pub trait FromStrKey:
@@ -36,7 +41,7 @@ pub trait FromStrKey:
3641
+ fmt::Debug
3742
+ hash::Hash;
3843
/// Dummy type. Do not use.
39-
type _Sha256FromStrErr: fmt::Debug + fmt::Display;
44+
type _Sha256FromStrErr: StaticDebugAndDisplay;
4045
/// Dummy type. Do not use.
4146
type _Hash256: FromStr<Err = Self::_Hash256FromStrErr>
4247
+ Clone
@@ -46,7 +51,7 @@ pub trait FromStrKey:
4651
+ fmt::Debug
4752
+ hash::Hash;
4853
/// Dummy type. Do not use.
49-
type _Hash256FromStrErr: fmt::Debug + fmt::Display;
54+
type _Hash256FromStrErr: StaticDebugAndDisplay;
5055
/// Dummy type. Do not use.
5156
type _Ripemd160: FromStr<Err = Self::_Ripemd160FromStrErr>
5257
+ Clone
@@ -56,7 +61,7 @@ pub trait FromStrKey:
5661
+ fmt::Debug
5762
+ hash::Hash;
5863
/// Dummy type. Do not use.
59-
type _Ripemd160FromStrErr: fmt::Debug + fmt::Display;
64+
type _Ripemd160FromStrErr: StaticDebugAndDisplay;
6065
/// Dummy type. Do not use.
6166
type _Hash160: FromStr<Err = Self::_Hash160FromStrErr>
6267
+ Clone
@@ -66,9 +71,9 @@ pub trait FromStrKey:
6671
+ fmt::Debug
6772
+ hash::Hash;
6873
/// Dummy type. Do not use.
69-
type _Hash160FromStrErr: fmt::Debug + fmt::Display;
74+
type _Hash160FromStrErr: StaticDebugAndDisplay;
7075
/// Dummy type. Do not use.
71-
type _FromStrErr: fmt::Debug + fmt::Display;
76+
type _FromStrErr: StaticDebugAndDisplay;
7277
}
7378

7479
impl<T> FromStrKey for T
@@ -78,11 +83,11 @@ where
7883
Self::Hash256: FromStr,
7984
Self::Ripemd160: FromStr,
8085
Self::Hash160: FromStr,
81-
<Self as FromStr>::Err: fmt::Debug + fmt::Display,
82-
<<Self as MiniscriptKey>::Sha256 as FromStr>::Err: fmt::Debug + fmt::Display,
83-
<Self::Hash256 as FromStr>::Err: fmt::Debug + fmt::Display,
84-
<Self::Ripemd160 as FromStr>::Err: fmt::Debug + fmt::Display,
85-
<Self::Hash160 as FromStr>::Err: fmt::Debug + fmt::Display,
86+
<Self as FromStr>::Err: StaticDebugAndDisplay,
87+
<<Self as MiniscriptKey>::Sha256 as FromStr>::Err: StaticDebugAndDisplay,
88+
<Self::Hash256 as FromStr>::Err: StaticDebugAndDisplay,
89+
<Self::Ripemd160 as FromStr>::Err: StaticDebugAndDisplay,
90+
<Self::Hash160 as FromStr>::Err: StaticDebugAndDisplay,
8691
{
8792
type _Sha256 = <T as MiniscriptKey>::Sha256;
8893
type _Sha256FromStrErr = <<T as MiniscriptKey>::Sha256 as FromStr>::Err;

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ pub trait ForEachKey<Pk: MiniscriptKey> {
409409

410410
/// Miniscript
411411
412-
#[derive(Debug, PartialEq)]
412+
#[derive(Debug)]
413413
pub enum Error {
414414
/// Opcode appeared which is not part of the script subset
415415
InvalidOpcode(Opcode),

src/miniscript/mod.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -1472,13 +1472,16 @@ mod tests {
14721472
fn duplicate_keys() {
14731473
// You cannot parse a Miniscript that has duplicate keys
14741474
let err = Miniscript::<String, Segwitv0>::from_str("and_v(v:pk(A),pk(A))").unwrap_err();
1475-
assert_eq!(err, Error::AnalysisError(crate::AnalysisError::RepeatedPubkeys));
1475+
assert!(matches!(err, Error::AnalysisError(crate::AnalysisError::RepeatedPubkeys)));
14761476

14771477
// ...though you can parse one with from_str_insane
14781478
let ok_insane =
14791479
Miniscript::<String, Segwitv0>::from_str_insane("and_v(v:pk(A),pk(A))").unwrap();
14801480
// ...but this cannot be sanity checked.
1481-
assert_eq!(ok_insane.sanity_check().unwrap_err(), crate::AnalysisError::RepeatedPubkeys);
1481+
assert!(matches!(
1482+
ok_insane.sanity_check().unwrap_err(),
1483+
crate::AnalysisError::RepeatedPubkeys
1484+
));
14821485
// ...it can be lifted, though it's unclear whether this is a deliberate
14831486
// choice or just an accident. It seems weird given that duplicate public
14841487
// keys are forbidden in several other places.
@@ -1492,7 +1495,10 @@ mod tests {
14921495
"and_v(v:and_v(v:older(4194304),pk(A)),and_v(v:older(1),pk(B)))",
14931496
)
14941497
.unwrap_err();
1495-
assert_eq!(err, Error::AnalysisError(crate::AnalysisError::HeightTimelockCombination));
1498+
assert!(matches!(
1499+
err,
1500+
Error::AnalysisError(crate::AnalysisError::HeightTimelockCombination)
1501+
));
14961502

14971503
// Though you can in an or() rather than and()
14981504
let ok_or = Miniscript::<String, Segwitv0>::from_str(
@@ -1512,10 +1518,10 @@ mod tests {
15121518
ok_insane.sanity_check().unwrap_err(),
15131519
crate::AnalysisError::HeightTimelockCombination
15141520
);
1515-
assert_eq!(
1521+
assert!(matches!(
15161522
ok_insane.lift().unwrap_err(),
15171523
Error::LiftError(crate::policy::LiftError::HeightTimelockCombination)
1518-
);
1524+
));
15191525
}
15201526

15211527
#[test]

0 commit comments

Comments
 (0)