11use std:: fmt;
22use std:: ops:: Range ;
3+ use std:: path:: PathBuf ;
34use std:: sync:: Arc ;
45
56use chumsky:: error:: Error as ChumskyError ;
@@ -136,9 +137,14 @@ impl<T> WithFile<T> for Result<T, RichError> {
136137#[ derive( Debug , Clone , Eq , PartialEq , Hash ) ]
137138pub struct RichError {
138139 /// The error that occurred.
139- error : Error ,
140+ ///
141+ /// Wrapped in a `Box` to keep the `RichError` struct small on the stack,
142+ /// ensuring cheap moves when returning errors inside a `Result`.
143+ error : Box < Error > ,
144+
140145 /// Area that the error spans inside the file.
141146 span : Span ,
147+
142148 /// File in which the error occurred.
143149 ///
144150 /// Required to print pretty errors.
@@ -149,7 +155,7 @@ impl RichError {
149155 /// Create a new error with context.
150156 pub fn new ( error : Error , span : Span ) -> RichError {
151157 RichError {
152- error,
158+ error : Box :: new ( error ) ,
153159 span,
154160 file : None ,
155161 }
@@ -170,7 +176,7 @@ impl RichError {
170176 /// a problem on the parsing side.
171177 pub fn parsing_error ( reason : & str ) -> Self {
172178 Self {
173- error : Error :: CannotParse ( reason. to_string ( ) ) ,
179+ error : Box :: new ( Error :: CannotParse ( reason. to_string ( ) ) ) ,
174180 span : Span :: new ( 0 , 0 ) ,
175181 file : None ,
176182 }
@@ -250,7 +256,7 @@ impl std::error::Error for RichError {}
250256
251257impl From < RichError > for Error {
252258 fn from ( error : RichError ) -> Self {
253- error. error
259+ * error. error
254260 }
255261}
256262
@@ -266,7 +272,7 @@ where
266272 I : ValueInput < ' tokens , Token = Token < ' src > , Span = Span > ,
267273{
268274 fn merge ( self , other : Self ) -> Self {
269- match ( & self . error , & other. error ) {
275+ match ( self . error . as_ref ( ) , other. error . as_ref ( ) ) {
270276 ( Error :: Grammar ( _) , Error :: Grammar ( _) ) => other,
271277 ( Error :: Grammar ( _) , _) => other,
272278 ( _, Error :: Grammar ( _) ) => self ,
@@ -302,11 +308,11 @@ where
302308 let found_string = found. map ( |t| t. to_string ( ) ) ;
303309
304310 Self {
305- error : Error :: Syntax {
311+ error : Box :: new ( Error :: Syntax {
306312 expected : expected_tokens,
307313 label : None ,
308314 found : found_string,
309- } ,
315+ } ) ,
310316 span,
311317 file : None ,
312318 }
@@ -329,11 +335,11 @@ where
329335 let found_string = found. map ( |t| t. to_string ( ) ) ;
330336
331337 Self {
332- error : Error :: Syntax {
338+ error : Box :: new ( Error :: Syntax {
333339 expected : expected_strings,
334340 label : None ,
335341 found : found_string,
336- } ,
342+ } ) ,
337343 span,
338344 file : None ,
339345 }
@@ -342,7 +348,7 @@ where
342348 fn label_with ( & mut self , label : & ' tokens str ) {
343349 if let Error :: Syntax {
344350 label : ref mut l, ..
345- } = & mut self . error
351+ } = self . error . as_mut ( )
346352 {
347353 * l = Some ( label. to_string ( ) ) ;
348354 }
@@ -398,6 +404,8 @@ impl fmt::Display for ErrorCollector {
398404/// Records _what_ happened but not where.
399405#[ derive( Debug , Clone , Eq , PartialEq , Hash ) ]
400406pub enum Error {
407+ Internal ( String ) ,
408+ UnknownLibrary ( String ) ,
401409 ArraySizeNonZero ( usize ) ,
402410 ListBoundPow2 ( usize ) ,
403411 BitStringPow2 ( usize ) ,
@@ -415,6 +423,12 @@ pub enum Error {
415423 CannotCompile ( String ) ,
416424 JetDoesNotExist ( JetName ) ,
417425 InvalidCast ( ResolvedType , ResolvedType ) ,
426+ FileNotFound ( PathBuf ) ,
427+ UnresolvedItem {
428+ name : String ,
429+ target_file : PathBuf ,
430+ } ,
431+ PrivateItem ( String ) ,
418432 MainNoInputs ,
419433 MainNoOutput ,
420434 MainRequired ,
@@ -431,6 +445,7 @@ pub enum Error {
431445 RedefinedAlias ( AliasName ) ,
432446 RedefinedAliasAsBuiltin ( AliasName ) ,
433447 UndefinedAlias ( AliasName ) ,
448+ DuplicateAlias ( String ) ,
434449 VariableReuseInPattern ( Identifier ) ,
435450 WitnessReused ( WitnessName ) ,
436451 WitnessTypeMismatch ( WitnessName , ResolvedType , ResolvedType ) ,
@@ -445,6 +460,14 @@ pub enum Error {
445460impl fmt:: Display for Error {
446461 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
447462 match self {
463+ Error :: Internal ( err) => write ! (
464+ f,
465+ "INTERNAL ERROR: {err}"
466+ ) ,
467+ Error :: UnknownLibrary ( name) => write ! (
468+ f,
469+ "Unknown module or library '{name}'"
470+ ) ,
448471 Error :: ArraySizeNonZero ( size) => write ! (
449472 f,
450473 "Expected a non-negative integer as array size, found {size}"
@@ -465,6 +488,10 @@ impl fmt::Display for Error {
465488 f,
466489 "Grammar error: {description}"
467490 ) ,
491+ Error :: FileNotFound ( path) => write ! (
492+ f,
493+ "File `{}` not found" , path. to_string_lossy( )
494+ ) ,
468495 Error :: Syntax { expected, label, found } => {
469496 let found_text = found. clone ( ) . unwrap_or ( "end of input" . to_string ( ) ) ;
470497 match ( label, expected. len ( ) ) {
@@ -516,6 +543,15 @@ impl fmt::Display for Error {
516543 f,
517544 "Function `{name}` was called but not defined"
518545 ) ,
546+ Error :: UnresolvedItem { name, target_file } => write ! (
547+ f,
548+ "Item `{}` could not be fouhnd in the file `{}`" ,
549+ name, target_file. to_string_lossy( )
550+ ) ,
551+ Error :: PrivateItem ( name) => write ! (
552+ f,
553+ "Item `{name}` is private"
554+ ) ,
519555 Error :: InvalidNumberOfArguments ( expected, found) => write ! (
520556 f,
521557 "Expected {expected} arguments, found {found} arguments"
@@ -560,6 +596,10 @@ impl fmt::Display for Error {
560596 f,
561597 "Type alias `{identifier}` is not defined"
562598 ) ,
599+ Error :: DuplicateAlias ( name) => write ! (
600+ f,
601+ "The alias `{name}` was defined multiple times"
602+ ) ,
563603 Error :: VariableReuseInPattern ( identifier) => write ! (
564604 f,
565605 "Variable `{identifier}` is used twice in the pattern"
0 commit comments