From 15311c6ce76205d0f0ec17358a242c057f84efba Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 4 Jul 2021 15:59:25 -0700 Subject: actually enforce DecodeError impl'ing std::error::Error in std builds the previous test and code only tested one concrete archtecture, and it turns out never required `std::error::Error` on `DecodeError`. --- src/lib.rs | 17 +++++++++++++---- tests/lib.rs | 11 +++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 038f311..455b5e2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,7 @@ pub use reader::{Reader, ReadError, U8Reader, U16le, U16be, U32le, U32be, U64le, /// it is permissible for an implementor of `DecodeError` to have items that return `false` for /// all these functions; decoders are permitted to error in way that `yaxpeax-arch` does not know /// about. -pub trait DecodeError: PartialEq { +pub trait DecodeError: PartialEq + Display + Debug + Send + Sync + 'static { /// did the decoder fail because it reached the end of input? fn data_exhausted(&self) -> bool; /// did the decoder error because the instruction's opcode is invalid? @@ -157,9 +157,18 @@ impl AddressBounds for T where T: Address + Debug + Hash + PartialEq + Eq + S impl AddressBounds for T where T: Address + Debug + Hash + PartialEq + Eq {} #[cfg(feature = "std")] -trait DecodeErrorBounds: DecodeError + std::error::Error + Debug + Display {} +/// this is not a particularly interesting trait. it just exists to add a `std::error::Error` +/// bound onto `DecodeError` for `std` builds. +pub trait DecodeErrorBounds: std::error::Error + DecodeError {} +#[cfg(feature = "std")] +impl DecodeErrorBounds for T {} +#[cfg(not(feature = "std"))] +/// this is not a particularly interesting trait. it just exists to add a `std::error::Error` +/// bound onto `DecodeError` for `std` builds. +pub trait DecodeErrorBounds: DecodeError {} #[cfg(not(feature = "std"))] -trait DecodeErrorBounds: DecodeError + Debug + Display {} +impl DecodeErrorBounds for T {} + /// a collection of associated type parameters that constitute the definitions for an instruction /// set. `Arch` provides an `Instruction` and its associated `Operand`s, which is guaranteed to be @@ -180,7 +189,7 @@ pub trait Arch { type Word: Debug + Display + PartialEq + Eq; type Address: AddressBounds; type Instruction: Instruction + LengthedInstruction> + Debug + Default + Sized; - type DecodeError: DecodeError + Debug + Display; + type DecodeError: DecodeErrorBounds + Debug + Display; type Decoder: Decoder + Default; type Operand; } diff --git a/tests/lib.rs b/tests/lib.rs index 8e097de..9add6e3 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -10,6 +10,17 @@ fn test_u16() { } #[test] +fn generic_error_can_bail() { + use yaxpeax_arch::{Arch, Decoder, Reader}; + + #[allow(dead_code)] + fn decode>>(data: U, decoder: &A::Decoder) -> anyhow::Result<()> { + let mut reader = data.into(); + decoder.decode(&mut reader)?; + Ok(()) + } +} +#[test] fn error_can_bail() { use yaxpeax_arch::{Arch, AddressDiff, Decoder, Reader, LengthedInstruction, Instruction, StandardDecodeError, U8Reader}; struct TestIsa {} -- cgit v1.1