diff --git a/src/ast.rs b/src/ast.rs index 0ab29779..0adcf21d 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -896,7 +896,7 @@ impl AbstractSyntaxTree for Item { Function::analyze(function, ty, scope).map(Self::Function) } parse::Item::Use(use_decl) => Err(RichError::new( - Error::CannotCompile("The `use` keyword is not supported yet.".to_string()), + Error::UseKeywordIsNotSupported, *use_decl.span(), )), parse::Item::Module => Ok(Self::Module), diff --git a/src/error.rs b/src/error.rs index bbd36836..6ae84598 100644 --- a/src/error.rs +++ b/src/error.rs @@ -11,7 +11,6 @@ use chumsky::util::MaybeRef; use chumsky::DefaultExpected; use itertools::Itertools; -use simplicity::elements; use crate::lexer::Token; use crate::parse::MatchPattern; @@ -150,7 +149,7 @@ impl WithSource for Result { /// An error enriched with context. /// /// Records _what_ happened and _where_. -#[derive(Debug, Clone, Eq, PartialEq, Hash)] +#[derive(Debug, Clone)] pub struct RichError { /// The error that occurred. /// @@ -404,7 +403,7 @@ where } } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone)] pub struct ErrorCollector { /// Collected errors. errors: Vec, @@ -472,7 +471,7 @@ impl fmt::Display for ErrorCollector { /// An individual error. /// /// Records _what_ happened but not where. -#[derive(Debug, Clone, Eq, PartialEq, Hash)] +#[derive(Debug, Clone)] pub enum Error { Internal(String), UnknownLibrary(String), @@ -490,7 +489,15 @@ pub enum Error { // TODO: Remove CompileError once SimplicityHL has a type system // The SimplicityHL compiler should never produce ill-typed Simplicity code // The compiler can only be this precise if it knows a type system at least as expressive as Simplicity's - CannotCompile(String), + CannotCompile { + source: simplicity::types::Error, + }, + ParseInt { + source: std::num::ParseIntError, + }, + ParseCrateInt { + source: crate::num::ParseIntError, + }, JetDoesNotExist(JetName), InvalidCast(ResolvedType, ResolvedType), FileNotFound(PathBuf), @@ -527,6 +534,7 @@ pub enum Error { ModuleRedefined(ModuleName), ArgumentMissing(WitnessName), ArgumentTypeMismatch(WitnessName, ResolvedType, ResolvedType), + UseKeywordIsNotSupported, } #[rustfmt::skip] @@ -592,10 +600,11 @@ impl fmt::Display for Error { f, "Match arm `{pattern1}` is incompatible with arm `{pattern2}`" ), - Error::CannotCompile(description) => write!( + Error::CannotCompile{ .. } => write!( f, - "Failed to compile to Simplicity: {description}" + "Failed to compile to Simplicity" ), + Error::ParseInt { .. } | Error::ParseCrateInt { .. } => write!(f, "Integer parsing error"), Error::JetDoesNotExist(name) => write!( f, "Jet `{name}` does not exist" @@ -728,11 +737,24 @@ impl fmt::Display for Error { f, "Parameter `{name}` was declared with type `{declared}` but its assigned argument is of type `{assigned}`" ), + Error::UseKeywordIsNotSupported => write!( + f, + "The `use` keyword is not supported yet" + ), } } } -impl std::error::Error for Error {} +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Error::ParseInt { source } => Some(source), + Error::ParseCrateInt { source } => Some(source), + Error::CannotCompile { source } => Some(source), + _ => None, + } + } +} impl Error { /// Update the error with the affected span. @@ -741,27 +763,21 @@ impl Error { } } -impl From for Error { - fn from(error: elements::hex::Error) -> Self { - Self::CannotParse(error.to_string()) - } -} - impl From for Error { fn from(error: std::num::ParseIntError) -> Self { - Self::CannotParse(error.to_string()) + Self::ParseInt { source: error } } } impl From for Error { fn from(error: crate::num::ParseIntError) -> Self { - Self::CannotParse(error.to_string()) + Self::ParseCrateInt { source: error } } } impl From for Error { fn from(error: simplicity::types::Error) -> Self { - Self::CannotCompile(error.to_string()) + Self::CannotCompile { source: error } } } diff --git a/src/parse.rs b/src/parse.rs index cff32f5f..9588c801 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -136,7 +136,7 @@ impl UseDecl { } } -impl_eq_hash!(UseDecl; visibility, path, drp_name, items); +impl_eq_hash!(UseDecl; visibility, path, items); #[cfg(feature = "arbitrary")] impl<'a> arbitrary::Arbitrary<'a> for UseDecl { @@ -2529,12 +2529,12 @@ mod test { #[test] fn test_reject_redefined_builtin_type() { let ty = TypeAlias::parse_from_str("type Ctx8 = u32") - .expect_err("Redifining built-in alias should be rejected"); + .expect_err("Redefining built-in alias should be rejected"); - assert_eq!( - ty.error(), - &Error::RedefinedAliasAsBuiltin(AliasName::from_str_unchecked("Ctx8")) - ); + assert!(ty + .error() + .to_string() + .contains("Type alias `Ctx8` is already exists as built-in alias")); } #[test]