diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-08-13 12:21:14 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-08-13 14:33:58 +0200 |
| commit | 144f20882136ef81b79d77bd8a68f42b76c66676 (patch) | |
| tree | 7a452ab2a092f674d93cd994d80b88cc6808e540 /src/diag.rs | |
| parent | d002cdf451e1c6efbf7cd7f2303264526b6f8a92 (diff) | |
Add file information to spans
Diffstat (limited to 'src/diag.rs')
| -rw-r--r-- | src/diag.rs | 104 |
1 files changed, 57 insertions, 47 deletions
diff --git a/src/diag.rs b/src/diag.rs index 1905d480..154de24b 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -2,8 +2,18 @@ use serde::{Deserialize, Serialize}; -use crate::source::SourceId; -use crate::syntax::Span; +use crate::syntax::{Span, Spanned}; + +/// Early-return with a vec-boxed [`Error`]. +macro_rules! bail { + ($span:expr, $message:expr $(,)?) => { + return Err($crate::diag::Error::boxed($span, $message,)); + }; + + ($span:expr, $fmt:expr, $($arg:expr),+ $(,)?) => { + bail!($span, format!($fmt, $($arg),+)); + }; +} /// The result type for typesetting and all its subpasses. pub type TypResult<T> = Result<T, Box<Vec<Error>>>; @@ -14,35 +24,19 @@ pub type StrResult<T> = Result<T, String>; /// An error in a source file. #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] pub struct Error { - /// The id of the source file that contains the error. - pub source: SourceId, /// The erroneous location in the source code. pub span: Span, /// A diagnostic message describing the problem. pub message: String, /// The trace of function calls leading to the error. - pub trace: Vec<(SourceId, Span, Tracepoint)>, -} - -/// A part of an error's [trace](Error::trace). -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] -pub enum Tracepoint { - /// A function call. - Call(Option<String>), - /// A module import. - Import, + pub trace: Vec<Spanned<Tracepoint>>, } impl Error { /// Create a new, bare error. - pub fn new( - source: SourceId, - span: impl Into<Span>, - message: impl Into<String>, - ) -> Self { + pub fn new(span: Span, message: impl Into<String>) -> Self { Self { - source, - span: span.into(), + span, trace: vec![], message: message.into(), } @@ -50,36 +44,52 @@ impl Error { /// Create a boxed vector containing one error. The return value is suitable /// as the `Err` variant of a [`TypResult`]. - pub fn boxed( - source: SourceId, - span: impl Into<Span>, - message: impl Into<String>, - ) -> Box<Vec<Self>> { - Box::new(vec![Self::new(source, span, message)]) + pub fn boxed(span: Span, message: impl Into<String>) -> Box<Vec<Self>> { + Box::new(vec![Self::new(span, message)]) } +} - /// Create a closure that contains the positional information for an error - /// and just needs the message to yield a vec-boxed error. - /// - /// This is useful in to convert from [`StrResult`] to a [`TypResult`] using - /// [`map_err`](Result::map_err). - pub fn at<S: Into<String>>( - source: SourceId, - span: impl Into<Span>, - ) -> impl FnOnce(S) -> Box<Vec<Self>> { - move |message| Self::boxed(source, span, message) +/// A part of an error's [trace](Error::trace). +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] +pub enum Tracepoint { + /// A function call. + Call(Option<String>), + /// A module import. + Import, +} + +/// Convert a [`StrResult`] to a [`TypResult`] by adding span information. +pub trait At<T> { + /// Add the span information. + fn at(self, span: Span) -> TypResult<T>; +} + +impl<T> At<T> for StrResult<T> { + fn at(self, span: Span) -> TypResult<T> { + self.map_err(|message| Error::boxed(span, message)) } } -/// Early-return with a vec-boxed [`Error`]. -macro_rules! bail { - ($source:expr, $span:expr, $message:expr $(,)?) => { - return Err(Box::new(vec![$crate::diag::Error::new( - $source, $span, $message, - )])); - }; +/// Enrich a [`TypResult`] with a tracepoint. +pub trait Trace<T> { + /// Add the tracepoint to all errors that lie outside the `span`. + fn trace<F>(self, make_point: F, span: Span) -> Self + where + F: Fn() -> Tracepoint; +} - ($source:expr, $span:expr, $fmt:expr, $($arg:expr),+ $(,)?) => { - bail!($source, $span, format!($fmt, $($arg),+)); - }; +impl<T> Trace<T> for TypResult<T> { + fn trace<F>(self, make_point: F, span: Span) -> Self + where + F: Fn() -> Tracepoint, + { + self.map_err(|mut errors| { + for error in errors.iter_mut() { + if !span.contains(error.span) { + error.trace.push(Spanned::new(make_point(), span)); + } + } + errors + }) + } } |
