Skip to content

Commit 31056a9

Browse files
committed
feat: add import errors
1 parent 5383d35 commit 31056a9

1 file changed

Lines changed: 46 additions & 10 deletions

File tree

src/error.rs

Lines changed: 46 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,9 @@ pub enum Error {
415423
CannotCompile(String),
416424
JetDoesNotExist(JetName),
417425
InvalidCast(ResolvedType, ResolvedType),
426+
FileNotFound(PathBuf),
427+
UnresolvedItem(String),
428+
PrivateItem(String),
418429
MainNoInputs,
419430
MainNoOutput,
420431
MainRequired,
@@ -431,6 +442,7 @@ pub enum Error {
431442
RedefinedAlias(AliasName),
432443
RedefinedAliasAsBuiltin(AliasName),
433444
UndefinedAlias(AliasName),
445+
DuplicateAlias(String),
434446
VariableReuseInPattern(Identifier),
435447
WitnessReused(WitnessName),
436448
WitnessTypeMismatch(WitnessName, ResolvedType, ResolvedType),
@@ -445,6 +457,14 @@ pub enum Error {
445457
impl fmt::Display for Error {
446458
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
447459
match self {
460+
Error::Internal(err) => write!(
461+
f,
462+
"INTERNAL ERROR: {err}"
463+
),
464+
Error::UnknownLibrary(name) => write!(
465+
f,
466+
"Unknown module or library '{name}'"
467+
),
448468
Error::ArraySizeNonZero(size) => write!(
449469
f,
450470
"Expected a non-negative integer as array size, found {size}"
@@ -465,6 +485,10 @@ impl fmt::Display for Error {
465485
f,
466486
"Grammar error: {description}"
467487
),
488+
Error::FileNotFound(path) => write!(
489+
f,
490+
"File `{}` not found", path.to_string_lossy()
491+
),
468492
Error::Syntax { expected, label, found } => {
469493
let found_text = found.clone().unwrap_or("end of input".to_string());
470494
match (label, expected.len()) {
@@ -516,6 +540,14 @@ impl fmt::Display for Error {
516540
f,
517541
"Function `{name}` was called but not defined"
518542
),
543+
Error::UnresolvedItem(name) => write!(
544+
f,
545+
"Unknown item `{name}`"
546+
),
547+
Error::PrivateItem(name) => write!(
548+
f,
549+
"Item `{name}` is private"
550+
),
519551
Error::InvalidNumberOfArguments(expected, found) => write!(
520552
f,
521553
"Expected {expected} arguments, found {found} arguments"
@@ -560,6 +592,10 @@ impl fmt::Display for Error {
560592
f,
561593
"Type alias `{identifier}` is not defined"
562594
),
595+
Error::DuplicateAlias(name) => write!(
596+
f,
597+
"The alias `{name}` was defined multiple times"
598+
),
563599
Error::VariableReuseInPattern(identifier) => write!(
564600
f,
565601
"Variable `{identifier}` is used twice in the pattern"

0 commit comments

Comments
 (0)