From 7e725cf880dd5151e746083729a3c749453b0491 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 30 Oct 2019 07:30:20 -0700 Subject: [PATCH] Migrate from failure to thiserror The failure crate invents its own traits that don't use std::error::Error (because failure predates certain features added to Error); this prevents using ? on an error from failure in a function using Error. The thiserror crate integrates with the standard Error trait instead. --- cranelift/codegen/Cargo.toml | 3 +-- cranelift/codegen/src/isa/mod.rs | 8 ++++---- cranelift/codegen/src/result.rs | 18 ++++++------------ cranelift/codegen/src/settings.rs | 10 +++++----- cranelift/codegen/src/verifier/mod.rs | 13 ++++--------- cranelift/module/Cargo.toml | 2 +- cranelift/module/src/module.rs | 21 +++++++++------------ cranelift/wasm/Cargo.toml | 3 +-- cranelift/wasm/src/environ/spec.rs | 12 ++++++------ 9 files changed, 37 insertions(+), 53 deletions(-) diff --git a/cranelift/codegen/Cargo.toml b/cranelift/codegen/Cargo.toml index fc7a9023a8..5149c68ee4 100644 --- a/cranelift/codegen/Cargo.toml +++ b/cranelift/codegen/Cargo.toml @@ -16,13 +16,12 @@ edition = "2018" cranelift-codegen-shared = { path = "./shared", version = "0.46.1" } cranelift-entity = { path = "../cranelift-entity", version = "0.46.1" } cranelift-bforest = { path = "../cranelift-bforest", version = "0.46.1" } -failure = { version = "0.1.1", default-features = false, features = ["derive"] } -failure_derive = { version = "0.1.1", default-features = false } hashbrown = { version = "0.6", optional = true } target-lexicon = "0.8.1" log = { version = "0.4.6", default-features = false } serde = { version = "1.0.94", features = ["derive"], optional = true } smallvec = { version = "0.6.10" } +thiserror = "1.0.4" # It is a goal of the cranelift-codegen crate to have minimal external dependencies. # Please don't add any unless they are essential to the task of creating binary # machine code. Integration tests that need external dependencies can be diff --git a/cranelift/codegen/src/isa/mod.rs b/cranelift/codegen/src/isa/mod.rs index 067dff318f..66dde9621a 100644 --- a/cranelift/codegen/src/isa/mod.rs +++ b/cranelift/codegen/src/isa/mod.rs @@ -65,8 +65,8 @@ use crate::settings::SetResult; use crate::timing; use alloc::boxed::Box; use core::fmt; -use failure_derive::Fail; use target_lexicon::{triple, Architecture, PointerWidth, Triple}; +use thiserror::Error; #[cfg(feature = "riscv")] mod riscv; @@ -124,14 +124,14 @@ pub fn lookup_by_name(name: &str) -> Result { } /// Describes reason for target lookup failure -#[derive(Fail, PartialEq, Eq, Copy, Clone, Debug)] +#[derive(Error, PartialEq, Eq, Copy, Clone, Debug)] pub enum LookupError { /// Support for this target was disabled in the current build. - #[fail(display = "Support for this target is disabled")] + #[error("Support for this target is disabled")] SupportDisabled, /// Support for this target has not yet been implemented. - #[fail(display = "Support for this target has not been implemented yet")] + #[error("Support for this target has not been implemented yet")] Unsupported, } diff --git a/cranelift/codegen/src/result.rs b/cranelift/codegen/src/result.rs index b0af78a3d6..7a577d09f2 100644 --- a/cranelift/codegen/src/result.rs +++ b/cranelift/codegen/src/result.rs @@ -1,19 +1,19 @@ //! Result and error types representing the outcome of compiling a function. use crate::verifier::VerifierErrors; -use failure_derive::Fail; +use thiserror::Error; /// A compilation error. /// /// When Cranelift fails to compile a function, it will return one of these error codes. -#[derive(Fail, Debug, PartialEq, Eq)] +#[derive(Error, Debug, PartialEq, Eq)] pub enum CodegenError { /// A list of IR verifier errors. /// /// This always represents a bug, either in the code that generated IR for Cranelift, or a bug /// in Cranelift itself. - #[fail(display = "Verifier errors:\n{}", _0)] - Verifier(#[cause] VerifierErrors), + #[error("Verifier errors")] + Verifier(#[from] VerifierErrors), /// An implementation limit was exceeded. /// @@ -21,22 +21,16 @@ pub enum CodegenError { /// limits][limits] that cause compilation to fail when they are exceeded. /// /// [limits]: https://cranelift.readthedocs.io/en/latest/ir.html#implementation-limits - #[fail(display = "Implementation limit exceeded")] + #[error("Implementation limit exceeded")] ImplLimitExceeded, /// The code size for the function is too large. /// /// Different target ISAs may impose a limit on the size of a compiled function. If that limit /// is exceeded, compilation fails. - #[fail(display = "Code for function is too large")] + #[error("Code for function is too large")] CodeTooLarge, } /// A convenient alias for a `Result` that uses `CodegenError` as the error type. pub type CodegenResult = Result; - -impl From for CodegenError { - fn from(e: VerifierErrors) -> Self { - Self::Verifier(e) - } -} diff --git a/cranelift/codegen/src/settings.rs b/cranelift/codegen/src/settings.rs index a20f0662f1..bb0e78a1af 100644 --- a/cranelift/codegen/src/settings.rs +++ b/cranelift/codegen/src/settings.rs @@ -26,7 +26,7 @@ use alloc::boxed::Box; use alloc::string::{String, ToString}; use core::fmt; use core::str; -use failure_derive::Fail; +use thiserror::Error; /// A string-based configurator for settings groups. /// @@ -165,18 +165,18 @@ impl Configurable for Builder { } /// An error produced when changing a setting. -#[derive(Fail, Debug, PartialEq, Eq)] +#[derive(Error, Debug, PartialEq, Eq)] pub enum SetError { /// No setting by this name exists. - #[fail(display = "No existing setting named '{}'", _0)] + #[error("No existing setting named '{0}'")] BadName(String), /// Type mismatch for setting (e.g., setting an enum setting as a bool). - #[fail(display = "Trying to set a setting with the wrong type")] + #[error("Trying to set a setting with the wrong type")] BadType, /// This is not a valid value for this setting. - #[fail(display = "Unexpected value for a setting, expected {}", _0)] + #[error("Unexpected value for a setting, expected {0}")] BadValue(String), } diff --git a/cranelift/codegen/src/verifier/mod.rs b/cranelift/codegen/src/verifier/mod.rs index b57add8de6..f31b4e2340 100644 --- a/cranelift/codegen/src/verifier/mod.rs +++ b/cranelift/codegen/src/verifier/mod.rs @@ -77,7 +77,7 @@ use alloc::string::String; use alloc::vec::Vec; use core::cmp::Ordering; use core::fmt::{self, Display, Formatter, Write}; -use failure_derive::Fail; +use thiserror::Error; pub use self::cssa::verify_cssa; pub use self::liveness::verify_liveness; @@ -127,7 +127,8 @@ mod liveness; mod locations; /// A verifier error. -#[derive(Fail, Debug, PartialEq, Eq)] +#[derive(Error, Debug, PartialEq, Eq)] +#[error("{location}: {message}")] pub struct VerifierError { /// The entity causing the verifier error. pub location: AnyEntity, @@ -135,12 +136,6 @@ pub struct VerifierError { pub message: String, } -impl Display for VerifierError { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "{}: {}", self.location, self.message) - } -} - /// Result of a step in the verification process. /// /// Functions that return `VerifierStepResult<()>` should also take a @@ -160,7 +155,7 @@ pub type VerifierStepResult = Result; pub type VerifierResult = Result; /// List of verifier errors. -#[derive(Fail, Debug, Default, PartialEq, Eq)] +#[derive(Error, Debug, Default, PartialEq, Eq)] pub struct VerifierErrors(pub Vec); impl VerifierErrors { diff --git a/cranelift/module/Cargo.toml b/cranelift/module/Cargo.toml index 5923cd792f..9c2e162b5e 100644 --- a/cranelift/module/Cargo.toml +++ b/cranelift/module/Cargo.toml @@ -14,8 +14,8 @@ edition = "2018" cranelift-codegen = { path = "../cranelift-codegen", version = "0.46.1", default-features = false } cranelift-entity = { path = "../cranelift-entity", version = "0.46.1" } hashbrown = { version = "0.6", optional = true } -failure = { version = "0.1.1", default-features = false } log = { version = "0.4.6", default-features = false } +thiserror = "1.0.4" [features] default = ["std"] diff --git a/cranelift/module/src/module.rs b/cranelift/module/src/module.rs index f45db2e79e..6b682101cb 100644 --- a/cranelift/module/src/module.rs +++ b/cranelift/module/src/module.rs @@ -11,11 +11,11 @@ use crate::Backend; use cranelift_codegen::binemit::{self, CodeInfo}; use cranelift_codegen::entity::{entity_impl, PrimaryMap}; use cranelift_codegen::{ir, isa, CodegenError, Context}; -use failure::Fail; use log::info; use std::borrow::ToOwned; use std::string::String; use std::vec::Vec; +use thiserror::Error; /// A function identifier for use in the `Module` interface. #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -121,32 +121,29 @@ pub struct FunctionDeclaration { } /// Error messages for all `Module` and `Backend` methods -#[derive(Fail, Debug)] +#[derive(Error, Debug)] pub enum ModuleError { /// Indicates an identifier was used before it was declared - #[fail(display = "Undeclared identifier: {}", _0)] + #[error("Undeclared identifier: {0}")] Undeclared(String), /// Indicates an identifier was used as data/function first, but then used as the other - #[fail(display = "Incompatible declaration of identifier: {}", _0)] + #[error("Incompatible declaration of identifier: {0}")] IncompatibleDeclaration(String), /// Indicates a function identifier was declared with a /// different signature than declared previously - #[fail( - display = "Function {} signature {:?} is incompatible with previous declaration {:?}", - _0, _2, _1 - )] + #[error("Function {0} signature {2:?} is incompatible with previous declaration {1:?}")] IncompatibleSignature(String, ir::Signature, ir::Signature), /// Indicates an identifier was defined more than once - #[fail(display = "Duplicate definition of identifier: {}", _0)] + #[error("Duplicate definition of identifier: {0}")] DuplicateDefinition(String), /// Indicates an identifier was defined, but was declared as an import - #[fail(display = "Invalid to define identifier declared as an import: {}", _0)] + #[error("Invalid to define identifier declared as an import: {0}")] InvalidImportDefinition(String), /// Wraps a `cranelift-codegen` error - #[fail(display = "Compilation error: {}", _0)] + #[error("Compilation error: {0}")] Compilation(CodegenError), /// Wraps a generic error from a backend - #[fail(display = "Backend error: {}", _0)] + #[error("Backend error: {0}")] Backend(String), } diff --git a/cranelift/wasm/Cargo.toml b/cranelift/wasm/Cargo.toml index 80feba60c6..6ea44409f9 100644 --- a/cranelift/wasm/Cargo.toml +++ b/cranelift/wasm/Cargo.toml @@ -16,10 +16,9 @@ cranelift-codegen = { path = "../cranelift-codegen", version = "0.46.1", default cranelift-entity = { path = "../cranelift-entity", version = "0.46.1" } cranelift-frontend = { path = "../cranelift-frontend", version = "0.46.1", default-features = false } hashbrown = { version = "0.6", optional = true } -failure = { version = "0.1.1", default-features = false, features = ["derive"] } -failure_derive = { version = "0.1.1", default-features = false } log = { version = "0.4.6", default-features = false } serde = { version = "1.0.94", features = ["derive"], optional = true } +thiserror = "1.0.4" [dev-dependencies] wabt = "0.9.1" diff --git a/cranelift/wasm/src/environ/spec.rs b/cranelift/wasm/src/environ/spec.rs index 46a823fc80..ad0a93236e 100644 --- a/cranelift/wasm/src/environ/spec.rs +++ b/cranelift/wasm/src/environ/spec.rs @@ -16,8 +16,8 @@ use cranelift_codegen::ir::immediates::Offset32; use cranelift_codegen::ir::{self, InstBuilder}; use cranelift_codegen::isa::TargetFrontendConfig; use cranelift_frontend::FunctionBuilder; -use failure_derive::Fail; use std::boxed::Box; +use thiserror::Error; use wasmparser::BinaryReaderError; use wasmparser::Operator; @@ -42,13 +42,13 @@ pub enum GlobalVariable { /// /// When a WebAssembly function can't be translated, one of these error codes will be returned /// to describe the failure. -#[derive(Fail, Debug)] +#[derive(Error, Debug)] pub enum WasmError { /// The input WebAssembly code is invalid. /// /// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly /// code. This should never happen for validated WebAssembly code. - #[fail(display = "Invalid input WebAssembly code at offset {}: {}", _1, _0)] + #[error("Invalid input WebAssembly code at offset {offset}: {message}")] InvalidWebAssembly { /// A string describing the validation error. message: &'static str, @@ -59,7 +59,7 @@ pub enum WasmError { /// A feature used by the WebAssembly code is not supported by the embedding environment. /// /// Embedding environments may have their own limitations and feature restrictions. - #[fail(display = "Unsupported feature: {}", _0)] + #[error("Unsupported feature: {0}")] Unsupported(std::string::String), /// An implementation limit was exceeded. @@ -68,11 +68,11 @@ pub enum WasmError { /// limits][limits] that cause compilation to fail when they are exceeded. /// /// [limits]: https://cranelift.readthedocs.io/en/latest/ir.html#implementation-limits - #[fail(display = "Implementation limit exceeded")] + #[error("Implementation limit exceeded")] ImplLimitExceeded, /// Any user-defined error. - #[fail(display = "User error: {}", _0)] + #[error("User error: {0}")] User(std::string::String), }