diff --git a/src/lib.rs b/src/lib.rs index c4e3a15c9..a06dd62c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -631,12 +631,8 @@ impl error::Error for Error { } #[doc(hidden)] -impl<Pk, Ctx> From<miniscript::types::Error<Pk, Ctx>> for Error -where - Pk: MiniscriptKey, - Ctx: ScriptContext, -{ - fn from(e: miniscript::types::Error<Pk, Ctx>) -> Error { Error::TypeCheck(e.to_string()) } +impl From<miniscript::types::Error> for Error { + fn from(e: miniscript::types::Error) -> Error { Error::TypeCheck(e.to_string()) } } #[doc(hidden)] diff --git a/src/miniscript/types/extra_props.rs b/src/miniscript/types/extra_props.rs index 8cbb4aa3c..e6d8c3108 100644 --- a/src/miniscript/types/extra_props.rs +++ b/src/miniscript/types/extra_props.rs @@ -860,7 +860,7 @@ impl Property for ExtData { fn type_check_with_child<Pk, Ctx, C>( _fragment: &Terminal<Pk, Ctx>, mut _child: C, - ) -> Result<Self, Error<Pk, Ctx>> + ) -> Result<Self, Error> where C: FnMut(usize) -> Self, Pk: MiniscriptKey, @@ -871,13 +871,13 @@ impl Property for ExtData { /// Compute the type of a fragment assuming all the children of /// Miniscript have been computed already. - fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Result<Self, Error<Pk, Ctx>> + fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Result<Self, Error> where Ctx: ScriptContext, Pk: MiniscriptKey, { let wrap_err = |result: Result<Self, ErrorKind>| { - result.map_err(|kind| Error { fragment: fragment.clone(), error: kind }) + result.map_err(|kind| Error { fragment_string: fragment.to_string(), error: kind }) }; let ret = match *fragment { @@ -888,13 +888,13 @@ impl Property for ExtData { Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => { if k == 0 { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::ZeroThreshold, }); } if k > pks.len() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::OverThreshold(k, pks.len()), }); } @@ -910,7 +910,7 @@ impl Property for ExtData { // only consumes 4 bytes from the stack. if t == absolute::LockTime::ZERO.into() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::InvalidTime, }); } @@ -919,7 +919,7 @@ impl Property for ExtData { Terminal::Older(t) => { if t == Sequence::ZERO || !t.is_relative_lock_time() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::InvalidTime, }); } @@ -975,20 +975,20 @@ impl Property for ExtData { Terminal::Thresh(k, ref subs) => { if k == 0 { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::ZeroThreshold, }); } if k > subs.len() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::OverThreshold(k, subs.len()), }); } let res = Self::threshold(k, subs.len(), |n| Ok(subs[n].ext)); - res.map_err(|kind| Error { fragment: fragment.clone(), error: kind }) + res.map_err(|kind| Error { fragment_string: fragment.to_string(), error: kind }) } }; if let Ok(ref ret) = ret { diff --git a/src/miniscript/types/mod.rs b/src/miniscript/types/mod.rs index e95585c9b..7c27c0100 100644 --- a/src/miniscript/types/mod.rs +++ b/src/miniscript/types/mod.rs @@ -8,6 +8,8 @@ pub mod correctness; pub mod extra_props; pub mod malleability; +#[cfg(all(not(feature = "std"), not(test)))] +use alloc::string::{String, ToString}; use core::fmt; #[cfg(feature = "std")] use std::error; @@ -82,91 +84,91 @@ pub enum ErrorKind { /// Error type for typechecking #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct Error<Pk: MiniscriptKey, Ctx: ScriptContext> { +pub struct Error { /// The fragment that failed typecheck - pub fragment: Terminal<Pk, Ctx>, + pub fragment_string: String, /// The reason that typechecking failed pub error: ErrorKind, } -impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Error<Pk, Ctx> { +impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.error { ErrorKind::InvalidTime => write!( f, "fragment «{}» represents a timelock which value is invalid (time must be in [1; 0x80000000])", - self.fragment, + self.fragment_string, ), ErrorKind::NonZeroDupIf => write!( f, "fragment «{}» represents needs to be `z`, needs to consume zero elements from the stack", - self.fragment, + self.fragment_string, ), ErrorKind::ZeroThreshold => write!( f, "fragment «{}» has a threshold value of 0", - self.fragment, + self.fragment_string, ), ErrorKind::OverThreshold(k, n) => write!( f, "fragment «{}» is a {}-of-{} threshold, which does not make sense", - self.fragment, k, n, + self.fragment_string, k, n, ), ErrorKind::NoStrongChild => write!( f, "fragment «{}» requires at least one strong child \ (a 3rd party cannot create a witness without having \ seen one before) to prevent malleability", - self.fragment, + self.fragment_string, ), ErrorKind::LeftNotDissatisfiable => write!( f, "fragment «{}» requires its left child be dissatisfiable", - self.fragment, + self.fragment_string, ), ErrorKind::RightNotDissatisfiable => write!( f, "fragment «{}» requires its right child be dissatisfiable", - self.fragment, + self.fragment_string, ), ErrorKind::SwapNonOne => write!( f, "fragment «{}» attempts to use `SWAP` to prefix something which does not take exactly one input", - self.fragment, + self.fragment_string, ), ErrorKind::NonZeroZero => write!( f, "fragment «{}» attempts to use use the `j:` wrapper around a fragment which might be satisfied by an input of size zero", - self.fragment, + self.fragment_string, ), ErrorKind::LeftNotUnit => write!( f, "fragment «{}» requires its left child be a unit (outputs exactly 1 given a satisfying input)", - self.fragment, + self.fragment_string, ), ErrorKind::ChildBase1(base) => write!( f, "fragment «{}» cannot wrap a fragment of type {:?}", - self.fragment, base, + self.fragment_string, base, ), ErrorKind::ChildBase2(base1, base2) => write!( f, "fragment «{}» cannot accept children of types {:?} and {:?}", - self.fragment, base1, base2, + self.fragment_string, base1, base2, ), ErrorKind::ChildBase3(base1, base2, base3) => write!( f, "fragment «{}» cannot accept children of types {:?}, {:?} and {:?}", - self.fragment, base1, base2, base3, + self.fragment_string, base1, base2, base3, ), ErrorKind::ThresholdBase(idx, base) => write!( f, "fragment «{}» sub-fragment {} has type {:?} rather than {:?}", - self.fragment, + self.fragment_string, idx, base, if idx == 0 { Base::B } else { Base::W }, @@ -175,20 +177,20 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Error<Pk, Ctx> { f, "fragment «{}» sub-fragment {} can not be dissatisfied \ and cannot be used in a threshold", - self.fragment, idx, + self.fragment_string, idx, ), ErrorKind::ThresholdNonUnit(idx) => write!( f, "fragment «{}» sub-fragment {} is not a unit (does not put \ exactly 1 on the stack given a satisfying input)", - self.fragment, idx, + self.fragment_string, idx, ), ErrorKind::ThresholdNotStrong { k, n, n_strong } => write!( f, "fragment «{}» is a {}-of-{} threshold, and needs {} of \ its children to be strong to prevent malleability; however \ only {} children were strong.", - self.fragment, + self.fragment_string, k, n, n - k, @@ -199,7 +201,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Error<Pk, Ctx> { } #[cfg(feature = "std")] -impl<Pk: MiniscriptKey, Ctx: ScriptContext> error::Error for Error<Pk, Ctx> { +impl error::Error for Error { fn cause(&self) -> Option<&dyn error::Error> { None } } @@ -351,14 +353,14 @@ pub trait Property: Sized { fn type_check_common<'a, Pk, Ctx, C>( fragment: &'a Terminal<Pk, Ctx>, mut get_child: C, - ) -> Result<Self, Error<Pk, Ctx>> + ) -> Result<Self, Error> where - C: FnMut(&'a Terminal<Pk, Ctx>, usize) -> Result<Self, Error<Pk, Ctx>>, + C: FnMut(&'a Terminal<Pk, Ctx>, usize) -> Result<Self, Error>, Pk: MiniscriptKey, Ctx: ScriptContext, { let wrap_err = |result: Result<Self, ErrorKind>| { - result.map_err(|kind| Error { fragment: fragment.clone(), error: kind }) + result.map_err(|kind| Error { fragment_string: fragment.to_string(), error: kind }) }; let ret = match *fragment { @@ -369,13 +371,13 @@ pub trait Property: Sized { Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => { if k == 0 { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::ZeroThreshold, }); } if k > pks.len() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::OverThreshold(k, pks.len()), }); } @@ -391,7 +393,7 @@ pub trait Property: Sized { // only consumes 4 bytes from the stack. if t == absolute::LockTime::ZERO.into() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::InvalidTime, }); } @@ -400,7 +402,7 @@ pub trait Property: Sized { Terminal::Older(t) => { if t == Sequence::ZERO || !t.is_relative_lock_time() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::InvalidTime, }); } @@ -458,13 +460,13 @@ pub trait Property: Sized { Terminal::Thresh(k, ref subs) => { if k == 0 { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::ZeroThreshold, }); } if k > subs.len() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::OverThreshold(k, subs.len()), }); } @@ -473,13 +475,13 @@ pub trait Property: Sized { let res = Self::threshold(k, subs.len(), |n| match get_child(&subs[n].node, n) { Ok(x) => Ok(x), Err(e) => { - last_err_frag = Some(e.fragment); + last_err_frag = Some(e.fragment_string); Err(e.error) } }); res.map_err(|kind| Error { - fragment: last_err_frag.unwrap_or_else(|| fragment.clone()), + fragment_string: last_err_frag.unwrap_or_else(|| fragment.to_string()), error: kind, }) } @@ -495,7 +497,7 @@ pub trait Property: Sized { fn type_check_with_child<Pk, Ctx, C>( fragment: &Terminal<Pk, Ctx>, mut child: C, - ) -> Result<Self, Error<Pk, Ctx>> + ) -> Result<Self, Error> where C: FnMut(usize) -> Self, Pk: MiniscriptKey, @@ -506,7 +508,7 @@ pub trait Property: Sized { } /// Compute the type of a fragment. - fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Result<Self, Error<Pk, Ctx>> + fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Result<Self, Error> where Pk: MiniscriptKey, Ctx: ScriptContext, @@ -697,7 +699,7 @@ impl Property for Type { fn type_check_with_child<Pk, Ctx, C>( _fragment: &Terminal<Pk, Ctx>, mut _child: C, - ) -> Result<Self, Error<Pk, Ctx>> + ) -> Result<Self, Error> where C: FnMut(usize) -> Self, Pk: MiniscriptKey, @@ -708,13 +710,13 @@ impl Property for Type { /// Compute the type of a fragment assuming all the children of /// Miniscript have been computed already. - fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Result<Self, Error<Pk, Ctx>> + fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Result<Self, Error> where Pk: MiniscriptKey, Ctx: ScriptContext, { let wrap_err = |result: Result<Self, ErrorKind>| { - result.map_err(|kind| Error { fragment: fragment.clone(), error: kind }) + result.map_err(|kind| Error { fragment_string: fragment.to_string(), error: kind }) }; let ret = match *fragment { @@ -725,13 +727,13 @@ impl Property for Type { Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => { if k == 0 { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::ZeroThreshold, }); } if k > pks.len() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::OverThreshold(k, pks.len()), }); } @@ -747,7 +749,7 @@ impl Property for Type { // only consumes 4 bytes from the stack. if t == absolute::LockTime::ZERO.into() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::InvalidTime, }); } @@ -756,7 +758,7 @@ impl Property for Type { Terminal::Older(t) => { if t == Sequence::ZERO || !t.is_relative_lock_time() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::InvalidTime, }); } @@ -812,20 +814,20 @@ impl Property for Type { Terminal::Thresh(k, ref subs) => { if k == 0 { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::ZeroThreshold, }); } if k > subs.len() { return Err(Error { - fragment: fragment.clone(), + fragment_string: fragment.to_string(), error: ErrorKind::OverThreshold(k, subs.len()), }); } let res = Self::threshold(k, subs.len(), |n| Ok(subs[n].ty)); - res.map_err(|kind| Error { fragment: fragment.clone(), error: kind }) + res.map_err(|kind| Error { fragment_string: fragment.to_string(), error: kind }) } }; if let Ok(ref ret) = ret { diff --git a/src/policy/compiler.rs b/src/policy/compiler.rs index fabf27d3c..8aa4cea22 100644 --- a/src/policy/compiler.rs +++ b/src/policy/compiler.rs @@ -450,7 +450,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> AstElemExt<Pk, Ctx> { ast: Terminal<Pk, Ctx>, l: &AstElemExt<Pk, Ctx>, r: &AstElemExt<Pk, Ctx>, - ) -> Result<AstElemExt<Pk, Ctx>, types::Error<Pk, Ctx>> { + ) -> Result<AstElemExt<Pk, Ctx>, types::Error> { let lookup_ext = |n| match n { 0 => l.comp_ext_data, 1 => r.comp_ext_data, @@ -472,7 +472,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> AstElemExt<Pk, Ctx> { a: &AstElemExt<Pk, Ctx>, b: &AstElemExt<Pk, Ctx>, c: &AstElemExt<Pk, Ctx>, - ) -> Result<AstElemExt<Pk, Ctx>, types::Error<Pk, Ctx>> { + ) -> Result<AstElemExt<Pk, Ctx>, types::Error> { let lookup_ext = |n| match n { 0 => a.comp_ext_data, 1 => b.comp_ext_data,