Skip to content

Commit 876e973

Browse files
committed
feat: add import errors
1 parent 5383d35 commit 876e973

1 file changed

Lines changed: 50 additions & 10 deletions

File tree

src/error.rs

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::fmt;
22
use std::ops::Range;
3+
use std::path::PathBuf;
34
use std::sync::Arc;
45

56
use chumsky::error::Error as ChumskyError;
@@ -136,9 +137,14 @@ impl<T> WithFile<T> for Result<T, RichError> {
136137
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
137138
pub 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

251257
impl 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)]
400406
pub 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 {
445460
impl 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

Comments
 (0)