From 2e03fb34cb9efd3f287b9658a8d84df52ad660dd Mon Sep 17 00:00:00 2001 From: Mathias Fischler Date: Sat, 24 Jun 2023 14:18:21 +0200 Subject: Add infrastructure to enrich errors with hints (#1486) --- src/diag.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src') 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>, + /// Additonal hints to the user, indicating how this error could be avoided or worked around. + pub hints: Vec, } 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) -> Self { + self.hints.append(hints); + self + } } /// A part of an error's [trace](SourceError::trace). @@ -194,6 +203,52 @@ where } } +pub type StrWithHintResult = Result; + +pub struct StrWithHint { + message: EcoString, + hints: Vec, +} + +impl At for Result { + fn at(self, span: Span) -> SourceResult { + 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 +where + S: Into, +{ + fn hint(self, hint: S) -> StrWithHintResult; +} + +impl Hint for StrResult +where + S: Into, +{ + fn hint(self, hint: S) -> StrWithHintResult { + self.map_err(|message| StrWithHint { message, hints: vec![hint.into()] }) + } +} + +impl Hint for StrWithHintResult +where + S: Into, +{ + fn hint(self, hint: S) -> StrWithHintResult { + self.map_err(|mut diags| { + diags.hints.push(hint.into()); + diags + }) + } +} + /// A result type with a file-related error. pub type FileResult = Result; -- cgit v1.2.3