diff --git a/Cargo.lock b/Cargo.lock index 05b1a92bd2..102a126904 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -535,7 +535,6 @@ dependencies = [ "smallvec", "souper-ir", "target-lexicon", - "thiserror", "wast 35.0.2", ] @@ -635,7 +634,6 @@ dependencies = [ "cranelift-entity", "hashbrown", "log", - "thiserror", ] [[package]] @@ -675,7 +673,6 @@ dependencies = [ "cranelift-codegen", "smallvec", "target-lexicon", - "thiserror", ] [[package]] @@ -3315,7 +3312,6 @@ dependencies = [ name = "wasmtime-environ" version = "0.26.0" dependencies = [ - "anyhow", "cfg-if 1.0.0", "cranelift-codegen", "cranelift-entity", @@ -3324,7 +3320,6 @@ dependencies = [ "indexmap", "log", "more-asserts", - "region", "serde", "thiserror", "wasmparser", diff --git a/cranelift/codegen/Cargo.toml b/cranelift/codegen/Cargo.toml index 9eb990f896..5ef650f1b3 100644 --- a/cranelift/codegen/Cargo.toml +++ b/cranelift/codegen/Cargo.toml @@ -23,7 +23,6 @@ serde = { version = "1.0.94", features = ["derive"], optional = true } bincode = { version = "1.2.1", optional = true } gimli = { version = "0.23.0", default-features = false, features = ["write"], optional = true } smallvec = { version = "1.6.1" } -thiserror = "1.0.4" peepmatic = { path = "../peepmatic", optional = true, version = "0.73.0" } peepmatic-traits = { path = "../peepmatic/crates/traits", optional = true, version = "0.73.0" } peepmatic-runtime = { path = "../peepmatic/crates/runtime", optional = true, version = "0.73.0" } diff --git a/cranelift/codegen/src/data_value.rs b/cranelift/codegen/src/data_value.rs index 193607f392..a317c7f394 100644 --- a/cranelift/codegen/src/data_value.rs +++ b/cranelift/codegen/src/data_value.rs @@ -5,7 +5,6 @@ use crate::ir::{types, ConstantData, Type}; use core::convert::TryInto; use core::fmt::{self, Display, Formatter}; use core::ptr; -use thiserror::Error; /// Represent a data value. Where [Value] is an SSA reference, [DataValue] is the type + value /// that would be referred to by a [Value]. @@ -97,15 +96,38 @@ impl DataValue { } /// Record failures to cast [DataValue]. -#[derive(Error, Debug, PartialEq)] +#[derive(Debug, PartialEq)] #[allow(missing_docs)] pub enum DataValueCastFailure { - #[error("unable to cast data value of type {0} to type {1}")] TryInto(Type, Type), - #[error("unable to cast i64({0}) to a data value of type {1}")] FromInteger(i64, Type), } +// This is manually implementing Error and Display instead of using thiserror to reduce the amount +// of dependencies used by Cranelift. +impl std::error::Error for DataValueCastFailure {} + +impl Display for DataValueCastFailure { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + DataValueCastFailure::TryInto(from, to) => { + write!( + f, + "unable to cast data value of type {} to type {}", + from, to + ) + } + DataValueCastFailure::FromInteger(val, to) => { + write!( + f, + "unable to cast i64({}) to a data value of type {}", + val, to + ) + } + } + } +} + /// Helper for creating conversion implementations for [DataValue]. macro_rules! build_conversion_impl { ( $rust_ty:ty, $data_value_ty:ident, $cranelift_ty:ident ) => { diff --git a/cranelift/codegen/src/isa/mod.rs b/cranelift/codegen/src/isa/mod.rs index a24f64a256..fccb46f7a6 100644 --- a/cranelift/codegen/src/isa/mod.rs +++ b/cranelift/codegen/src/isa/mod.rs @@ -69,7 +69,6 @@ use core::fmt; use core::fmt::{Debug, Formatter}; use core::hash::Hasher; use target_lexicon::{triple, Architecture, OperatingSystem, PointerWidth, Triple}; -use thiserror::Error; #[cfg(feature = "riscv")] mod riscv; @@ -178,17 +177,30 @@ pub fn lookup_by_name(name: &str) -> Result { } /// Describes reason for target lookup failure -#[derive(Error, PartialEq, Eq, Copy, Clone, Debug)] +#[derive(PartialEq, Eq, Copy, Clone, Debug)] pub enum LookupError { /// Support for this target was disabled in the current build. - #[error("Support for this target is disabled")] SupportDisabled, /// Support for this target has not yet been implemented. - #[error("Support for this target has not been implemented yet")] Unsupported, } +// This is manually implementing Error and Display instead of using thiserror to reduce the amount +// of dependencies used by Cranelift. +impl std::error::Error for LookupError {} + +impl fmt::Display for LookupError { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + LookupError::SupportDisabled => write!(f, "Support for this target is disabled"), + LookupError::Unsupported => { + write!(f, "Support for this target has not been implemented yet") + } + } + } +} + /// Builder for a `TargetIsa`. /// Modify the ISA-specific settings before creating the `TargetIsa` trait object with `finish`. #[derive(Clone)] diff --git a/cranelift/codegen/src/isa/unwind/systemv.rs b/cranelift/codegen/src/isa/unwind/systemv.rs index 5ceadef93f..da3bfea869 100644 --- a/cranelift/codegen/src/isa/unwind/systemv.rs +++ b/cranelift/codegen/src/isa/unwind/systemv.rs @@ -6,7 +6,6 @@ use crate::isa::unwind::UnwindInst; use crate::result::{CodegenError, CodegenResult}; use alloc::vec::Vec; use gimli::write::{Address, FrameDescriptionEntry}; -use thiserror::Error; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -15,16 +14,32 @@ type Register = u16; /// Enumerate the errors possible in mapping Cranelift registers to their DWARF equivalent. #[allow(missing_docs)] -#[derive(Error, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] pub enum RegisterMappingError { - #[error("unable to find bank for register info")] MissingBank, - #[error("register mapping is currently only implemented for x86_64")] UnsupportedArchitecture, - #[error("unsupported register bank: {0}")] UnsupportedRegisterBank(&'static str), } +// This is manually implementing Error and Display instead of using thiserror to reduce the amount +// of dependencies used by Cranelift. +impl std::error::Error for RegisterMappingError {} + +impl std::fmt::Display for RegisterMappingError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + RegisterMappingError::MissingBank => write!(f, "unable to find bank for register info"), + RegisterMappingError::UnsupportedArchitecture => write!( + f, + "register mapping is currently only implemented for x86_64" + ), + RegisterMappingError::UnsupportedRegisterBank(bank) => { + write!(f, "unsupported register bank: {}", bank) + } + } + } +} + // This mirrors gimli's CallFrameInstruction, but is serializable // This excludes CfaExpression, Expression, ValExpression due to // https://github.com/gimli-rs/gimli/issues/513. diff --git a/cranelift/codegen/src/result.rs b/cranelift/codegen/src/result.rs index 493545c151..3178cd5ba9 100644 --- a/cranelift/codegen/src/result.rs +++ b/cranelift/codegen/src/result.rs @@ -2,19 +2,17 @@ use crate::verifier::VerifierErrors; use std::string::String; -use thiserror::Error; /// A compilation error. /// /// When Cranelift fails to compile a function, it will return one of these error codes. -#[derive(Error, Debug, PartialEq, Eq)] +#[derive(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. - #[error("Verifier errors")] - Verifier(#[from] VerifierErrors), + Verifier(VerifierErrors), /// An implementation limit was exceeded. /// @@ -22,27 +20,57 @@ pub enum CodegenError { /// limits][limits] that cause compilation to fail when they are exceeded. /// /// [limits]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/docs/ir.md#implementation-limits - #[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. - #[error("Code for function is too large")] CodeTooLarge, /// Something is not supported by the code generator. This might be an indication that a /// feature is used without explicitly enabling it, or that something is temporarily /// unsupported by a given target backend. - #[error("Unsupported feature: {0}")] Unsupported(String), /// A failure to map Cranelift register representation to a DWARF register representation. #[cfg(feature = "unwind")] - #[error("Register mapping error")] RegisterMappingError(crate::isa::unwind::systemv::RegisterMappingError), } /// A convenient alias for a `Result` that uses `CodegenError` as the error type. pub type CodegenResult = Result; + +// This is manually implementing Error and Display instead of using thiserror to reduce the amount +// of dependencies used by Cranelift. +impl std::error::Error for CodegenError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + CodegenError::Verifier(source) => Some(source), + CodegenError::ImplLimitExceeded { .. } + | CodegenError::CodeTooLarge { .. } + | CodegenError::Unsupported { .. } => None, + #[cfg(feature = "unwind")] + CodegenError::RegisterMappingError { .. } => None, + } + } +} + +impl std::fmt::Display for CodegenError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + CodegenError::Verifier(_) => write!(f, "Verifier errors"), + CodegenError::ImplLimitExceeded => write!(f, "Implementation limit exceeded"), + CodegenError::CodeTooLarge => write!(f, "Code for function is too large"), + CodegenError::Unsupported(feature) => write!(f, "Unsupported feature: {}", feature), + #[cfg(feature = "unwind")] + CodegenError::RegisterMappingError(_0) => write!(f, "Register mapping error"), + } + } +} + +impl From for CodegenError { + fn from(source: VerifierErrors) -> Self { + CodegenError::Verifier { 0: source } + } +} diff --git a/cranelift/codegen/src/settings.rs b/cranelift/codegen/src/settings.rs index 88a3c62157..0f36db82a9 100644 --- a/cranelift/codegen/src/settings.rs +++ b/cranelift/codegen/src/settings.rs @@ -26,7 +26,6 @@ use alloc::boxed::Box; use alloc::string::{String, ToString}; use core::fmt; use core::str; -use thiserror::Error; /// A string-based configurator for settings groups. /// @@ -261,21 +260,34 @@ impl Configurable for Builder { } /// An error produced when changing a setting. -#[derive(Error, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] pub enum SetError { /// No setting by this name exists. - #[error("No existing setting named '{0}'")] BadName(String), /// Type mismatch for setting (e.g., setting an enum setting as a bool). - #[error("Trying to set a setting with the wrong type")] BadType, /// This is not a valid value for this setting. - #[error("Unexpected value for a setting, expected {0}")] BadValue(String), } +impl std::error::Error for SetError {} + +impl fmt::Display for SetError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + SetError::BadName(name) => write!(f, "No existing setting named '{}'", name), + SetError::BadType => { + write!(f, "Trying to set a setting with the wrong type") + } + SetError::BadValue(value) => { + write!(f, "Unexpected value for a setting, expected {}", value) + } + } + } +} + /// A result returned when changing a setting. pub type SetResult = Result; diff --git a/cranelift/codegen/src/verifier/mod.rs b/cranelift/codegen/src/verifier/mod.rs index e20570c951..1d1801016b 100644 --- a/cranelift/codegen/src/verifier/mod.rs +++ b/cranelift/codegen/src/verifier/mod.rs @@ -80,7 +80,6 @@ use alloc::vec::Vec; use core::cmp::Ordering; use core::fmt::{self, Display, Formatter, Write}; use log::debug; -use thiserror::Error; pub use self::cssa::verify_cssa; pub use self::liveness::verify_liveness; @@ -92,8 +91,7 @@ mod liveness; mod locations; /// A verifier error. -#[derive(Error, Debug, PartialEq, Eq, Clone)] -#[error("{}{}: {}", .location, format_context(.context), .message)] +#[derive(Debug, PartialEq, Eq, Clone)] pub struct VerifierError { /// The entity causing the verifier error. pub location: AnyEntity, @@ -104,11 +102,16 @@ pub struct VerifierError { pub message: String, } -/// Helper for formatting Verifier::Error context. -fn format_context(context: &Option) -> String { - match context { - None => "".to_string(), - Some(c) => format!(" ({})", c), +// This is manually implementing Error and Display instead of using thiserror to reduce the amount +// of dependencies used by Cranelift. +impl std::error::Error for VerifierError {} + +impl Display for VerifierError { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match &self.context { + None => write!(f, "{}: {}", self.location, self.message), + Some(context) => write!(f, "{} ({}): {}", self.location, context, self.message), + } } } @@ -175,9 +178,13 @@ pub type VerifierStepResult = Result; pub type VerifierResult = Result; /// List of verifier errors. -#[derive(Error, Debug, Default, PartialEq, Eq, Clone)] +#[derive(Debug, Default, PartialEq, Eq, Clone)] pub struct VerifierErrors(pub Vec); +// This is manually implementing Error and Display instead of using thiserror to reduce the amount +// of dependencies used by Cranelift. +impl std::error::Error for VerifierErrors {} + impl VerifierErrors { /// Return a new `VerifierErrors` struct. #[inline] diff --git a/cranelift/interpreter/Cargo.toml b/cranelift/interpreter/Cargo.toml index 0439c964d8..c539f70fe1 100644 --- a/cranelift/interpreter/Cargo.toml +++ b/cranelift/interpreter/Cargo.toml @@ -13,13 +13,13 @@ edition = "2018" [dependencies] cranelift-codegen = { path = "../codegen", version = "0.73.0", features = ["all-arch"] } cranelift-entity = { path = "../entity", version = "0.73.0" } -cranelift-reader = { path = "../reader", version = "0.73.0" } log = { version = "0.4.8", default-features = false } smallvec = "1.6.1" thiserror = "1.0.15" [dev-dependencies] cranelift-frontend = { path = "../frontend", version = "0.73.0" } +cranelift-reader = { path = "../reader", version = "0.73.0" } [badges] maintenance = { status = "experimental" } diff --git a/cranelift/module/Cargo.toml b/cranelift/module/Cargo.toml index 6650714cf6..a3fe4a0901 100644 --- a/cranelift/module/Cargo.toml +++ b/cranelift/module/Cargo.toml @@ -15,7 +15,6 @@ cranelift-codegen = { path = "../codegen", version = "0.73.0", default-features cranelift-entity = { path = "../entity", version = "0.73.0" } hashbrown = { version = "0.9.1", optional = true } log = { version = "0.4.6", default-features = false } -thiserror = "1.0.4" anyhow = "1.0" [features] diff --git a/cranelift/module/src/module.rs b/cranelift/module/src/module.rs index 6047dda103..191d468ed7 100644 --- a/cranelift/module/src/module.rs +++ b/cranelift/module/src/module.rs @@ -12,7 +12,6 @@ use cranelift_codegen::entity::{entity_impl, PrimaryMap}; use cranelift_codegen::{ir, isa, CodegenError, Context}; use std::borrow::ToOwned; use std::string::String; -use thiserror::Error; /// A function identifier for use in the `Module` interface. #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -168,30 +167,85 @@ impl FunctionDeclaration { } /// Error messages for all `Module` methods -#[derive(Error, Debug)] +#[derive(Debug)] pub enum ModuleError { /// Indicates an identifier was used before it was declared - #[error("Undeclared identifier: {0}")] Undeclared(String), + /// Indicates an identifier was used as data/function first, but then used as the other - #[error("Incompatible declaration of identifier: {0}")] IncompatibleDeclaration(String), + /// Indicates a function identifier was declared with a /// different signature than declared previously - #[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 - #[error("Duplicate definition of identifier: {0}")] DuplicateDefinition(String), + /// Indicates an identifier was defined, but was declared as an import - #[error("Invalid to define identifier declared as an import: {0}")] InvalidImportDefinition(String), + /// Wraps a `cranelift-codegen` error - #[error("Compilation error: {0}")] - Compilation(#[from] CodegenError), + Compilation(CodegenError), + /// Wraps a generic error from a backend - #[error("Backend error: {0}")] - Backend(#[source] anyhow::Error), + Backend(anyhow::Error), +} + +// This is manually implementing Error and Display instead of using thiserror to reduce the amount +// of dependencies used by Cranelift. +impl std::error::Error for ModuleError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::Undeclared { .. } + | Self::IncompatibleDeclaration { .. } + | Self::IncompatibleSignature { .. } + | Self::DuplicateDefinition { .. } + | Self::InvalidImportDefinition { .. } => None, + Self::Compilation(source) => Some(source), + Self::Backend(source) => Some(&**source), + } + } +} + +impl std::fmt::Display for ModuleError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::Undeclared(name) => { + write!(f, "Undeclared identifier: {}", name) + } + Self::IncompatibleDeclaration(name) => { + write!(f, "Incompatible declaration of identifier: {}", name,) + } + Self::IncompatibleSignature(name, prev_sig, new_sig) => { + write!( + f, + "Function {} signature {:?} is incompatible with previous declaration {:?}", + name, new_sig, prev_sig, + ) + } + Self::DuplicateDefinition(name) => { + write!(f, "Duplicate definition of identifier: {}", name) + } + Self::InvalidImportDefinition(name) => { + write!( + f, + "Invalid to define identifier declared as an import: {}", + name, + ) + } + Self::Compilation(err) => { + write!(f, "Compilation error: {}", err) + } + Self::Backend(err) => write!(f, "Backend error: {}", err), + } + } +} + +impl std::convert::From for ModuleError { + fn from(source: CodegenError) -> Self { + Self::Compilation { 0: source } + } } /// A convenient alias for a `Result` that uses `ModuleError` as the error type. diff --git a/cranelift/reader/Cargo.toml b/cranelift/reader/Cargo.toml index d1d8a29ae3..2d7e93fee0 100644 --- a/cranelift/reader/Cargo.toml +++ b/cranelift/reader/Cargo.toml @@ -13,7 +13,6 @@ edition = "2018" cranelift-codegen = { path = "../codegen", version = "0.73.0" } smallvec = "1.6.1" target-lexicon = "0.12" -thiserror = "1.0.15" [badges] maintenance = { status = "experimental" } diff --git a/crates/environ/Cargo.toml b/crates/environ/Cargo.toml index 751be91cb6..383d030b43 100644 --- a/crates/environ/Cargo.toml +++ b/crates/environ/Cargo.toml @@ -12,8 +12,6 @@ readme = "README.md" edition = "2018" [dependencies] -anyhow = "1.0" -region = "2.2.0" cranelift-codegen = { path = "../../cranelift/codegen", version = "0.73.0", features = ["enable-serde"] } cranelift-entity = { path = "../../cranelift/entity", version = "0.73.0", features = ["enable-serde"] } cranelift-wasm = { path = "../../cranelift/wasm", version = "0.73.0", features = ["enable-serde"] }