diff options
| author | Mathias Fischler <Mafii@users.noreply.github.com> | 2023-06-24 14:18:21 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-24 14:18:21 +0200 |
| commit | 2e03fb34cb9efd3f287b9658a8d84df52ad660dd (patch) | |
| tree | 92c4fd41d98e8242cccf24aa1f34be0b0f020c7e /src | |
| parent | 0de7860118d0906f26accba51f4fe83e524836d8 (diff) | |
Add infrastructure to enrich errors with hints (#1486)
Diffstat (limited to 'src')
| -rw-r--r-- | src/diag.rs | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/diag.rs b/src/diag.rs index 4fb9ecc0..0f669f64 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -82,6 +82,8 @@ pub struct SourceError { pub message: EcoString, /// The trace of function calls leading to the error. pub trace: Vec<Spanned<Tracepoint>>, + /// Additonal hints to the user, indicating how this error could be avoided or worked around. + pub hints: Vec<EcoString>, } impl SourceError { @@ -92,6 +94,7 @@ impl SourceError { pos: ErrorPos::Full, trace: vec![], message: message.into(), + hints: vec![], } } @@ -112,6 +115,12 @@ impl SourceError { ErrorPos::End => full.end..full.end, } } + + /// Adds a user-facing hint to the error. + pub fn with_hints(mut self, hints: &mut Vec<EcoString>) -> Self { + self.hints.append(hints); + self + } } /// A part of an error's [trace](SourceError::trace). @@ -194,6 +203,52 @@ where } } +pub type StrWithHintResult<T> = Result<T, StrWithHint>; + +pub struct StrWithHint { + message: EcoString, + hints: Vec<EcoString>, +} + +impl<T> At<T> for Result<T, StrWithHint> { + fn at(self, span: Span) -> SourceResult<T> { + self.map_err(|mut diags| { + Box::new(vec![ + SourceError::new(span, diags.message).with_hints(&mut diags.hints) + ]) + }) + } +} + +/// Allows adding a user-facing hint in addition to the error. +pub trait Hint<T, S> +where + S: Into<EcoString>, +{ + fn hint(self, hint: S) -> StrWithHintResult<T>; +} + +impl<T, S> Hint<T, S> for StrResult<T> +where + S: Into<EcoString>, +{ + fn hint(self, hint: S) -> StrWithHintResult<T> { + self.map_err(|message| StrWithHint { message, hints: vec![hint.into()] }) + } +} + +impl<T, S> Hint<T, S> for StrWithHintResult<T> +where + S: Into<EcoString>, +{ + fn hint(self, hint: S) -> StrWithHintResult<T> { + self.map_err(|mut diags| { + diags.hints.push(hint.into()); + diags + }) + } +} + /// A result type with a file-related error. pub type FileResult<T> = Result<T, FileError>; |
