From 1b0a1c73cb0fc1f7b391b3939b48687e23ff960e Mon Sep 17 00:00:00 2001 From: Volodymyr Herashchenko Date: Mon, 18 May 2026 15:46:44 +0300 Subject: [PATCH 1/5] add `UseKeywordIsNotSupported` Error --- src/ast.rs | 2 +- src/error.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) 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..6fefbfe0 100644 --- a/src/error.rs +++ b/src/error.rs @@ -527,6 +527,7 @@ pub enum Error { ModuleRedefined(ModuleName), ArgumentMissing(WitnessName), ArgumentTypeMismatch(WitnessName, ResolvedType, ResolvedType), + UseKeywordIsNotSupported, } #[rustfmt::skip] @@ -728,6 +729,10 @@ 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" + ), } } } From 610747ea9ce604b3e08d098f9170ca2babe0de32 Mon Sep 17 00:00:00 2001 From: Volodymyr Herashchenko Date: Mon, 18 May 2026 15:48:44 +0300 Subject: [PATCH 2/5] remove unused conversion from elements::hex::Error --- src/error.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/error.rs b/src/error.rs index 6fefbfe0..701fc2b0 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; @@ -746,12 +745,6 @@ 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()) From 6bd337bbc52d537d09e333c6523b78d9c93248fb Mon Sep 17 00:00:00 2001 From: Volodymyr Herashchenko Date: Mon, 18 May 2026 15:56:26 +0300 Subject: [PATCH 3/5] remove Hash, Eq and PartialEq derive from an errors In order to wrap the error inside, we need to get rid of these because not all of them implement this. It seems like it was used only in the `UseDecl` hash implementation. --- src/error.rs | 6 +++--- src/parse.rs | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/error.rs b/src/error.rs index 701fc2b0..a80b9030 100644 --- a/src/error.rs +++ b/src/error.rs @@ -149,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. /// @@ -403,7 +403,7 @@ where } } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone)] pub struct ErrorCollector { /// Collected errors. errors: Vec, @@ -471,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), 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] From 6a5099d2b3d9a66309ee9d26d3356fdd667356c5 Mon Sep 17 00:00:00 2001 From: Volodymyr Herashchenko Date: Mon, 18 May 2026 16:03:22 +0300 Subject: [PATCH 4/5] change String to error types where needed --- src/error.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/error.rs b/src/error.rs index a80b9030..b110dacb 100644 --- a/src/error.rs +++ b/src/error.rs @@ -489,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), @@ -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" @@ -747,19 +756,19 @@ impl Error { 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 } } } From 14488985ed74e29ab69e867659c7e847bf1903bb Mon Sep 17 00:00:00 2001 From: Volodymyr Herashchenko Date: Mon, 18 May 2026 16:06:01 +0300 Subject: [PATCH 5/5] add source function to Error trait impl --- src/error.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/error.rs b/src/error.rs index b110dacb..6ae84598 100644 --- a/src/error.rs +++ b/src/error.rs @@ -745,7 +745,16 @@ impl fmt::Display for Error { } } -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.