1use alloc::boxed::Box;
4use alloc::string::{String, ToString};
5use core::fmt;
6
7use crate::{SourceMap, Span, ast::lex};
8
9pub type ParseResult<T, E = ParseError> = Result<T, E>;
11
12#[non_exhaustive]
14#[derive(Debug, PartialEq, Eq)]
15pub enum ParseErrorKind {
16 Lex(lex::Error),
18 Syntax { span: Span, message: String },
21 ItemNotFound {
24 span: Span,
25 name: String,
26 kind: String,
27 hint: Option<String>,
28 },
29 TypeCycle {
31 span: Span,
32 name: String,
33 kind: String,
34 },
35}
36
37impl ParseErrorKind {
38 pub fn span(&self) -> Span {
40 match self {
41 ParseErrorKind::Lex(e) => Span::new(e.position(), e.position() + 1),
42 ParseErrorKind::Syntax { span, .. }
43 | ParseErrorKind::ItemNotFound { span, .. }
44 | ParseErrorKind::TypeCycle { span, .. } => *span,
45 }
46 }
47}
48
49impl fmt::Display for ParseErrorKind {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 match self {
52 ParseErrorKind::Lex(e) => fmt::Display::fmt(e, f),
53 ParseErrorKind::Syntax { message, .. } => message.fmt(f),
54 ParseErrorKind::ItemNotFound {
55 kind, name, hint, ..
56 } => {
57 write!(f, "{kind} `{name}` does not exist")?;
58 if let Some(hint) = hint {
59 write!(f, "\n{hint}")?;
60 }
61 Ok(())
62 }
63 ParseErrorKind::TypeCycle { kind, name, .. } => {
64 write!(f, "{kind} `{name}` depends on itself")
65 }
66 }
67 }
68}
69
70#[derive(Debug, PartialEq, Eq)]
72pub struct ParseError(Box<ParseErrorKind>);
73
74impl ParseError {
75 pub fn new_syntax(span: Span, message: impl Into<String>) -> Self {
76 ParseErrorKind::Syntax {
77 span,
78 message: message.into(),
79 }
80 .into()
81 }
82
83 pub fn kind(&self) -> &ParseErrorKind {
85 &self.0
86 }
87
88 pub fn kind_mut(&mut self) -> &mut ParseErrorKind {
90 &mut self.0
91 }
92
93 pub fn highlight(&self, source_map: &SourceMap) -> String {
95 let e = self.kind();
96 source_map
97 .highlight_span(e.span(), e)
98 .unwrap_or_else(|| e.to_string())
99 }
100}
101
102impl fmt::Display for ParseError {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 fmt::Display::fmt(self.kind(), f)
105 }
106}
107
108impl core::error::Error for ParseError {}
109
110impl From<ParseErrorKind> for ParseError {
111 fn from(kind: ParseErrorKind) -> Self {
112 ParseError(Box::new(kind))
113 }
114}
115
116impl From<lex::Error> for ParseError {
117 fn from(e: lex::Error) -> Self {
118 ParseErrorKind::Lex(e).into()
119 }
120}