From ae0a56cdffa515ed6bb7cb566c025cc66ff00f33 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Tue, 15 Mar 2022 11:30:13 +0100 Subject: [PATCH] Non-returning error macro --- src/diag.rs | 31 +++++++++++++++++++------------ src/eval/control.rs | 10 ++++++---- src/eval/mod.rs | 10 ++++------ src/library/graphics/image.rs | 9 +++------ src/library/prelude.rs | 2 +- tests/typeset.rs | 7 ++----- 6 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/diag.rs b/src/diag.rs index 9d1ec1603..9e756bfee 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -4,14 +4,23 @@ use std::fmt::{self, Display, Formatter}; use crate::syntax::{Span, Spanned}; -/// Early-return with a vec-boxed [`Error`]. +/// Early-return with a [`TypError`]. +#[macro_export] macro_rules! bail { + ($($tts:tt)*) => { + return Err($crate::error!($($tts)*).into()) + }; +} + +/// Construct a [`TypError`]. +#[macro_export] +macro_rules! error { ($span:expr, $message:expr $(,)?) => { - return Err($crate::diag::Error::boxed($span, $message).into()) + Box::new(vec![$crate::diag::Error::new($span, $message)]) }; ($span:expr, $fmt:expr, $($arg:expr),+ $(,)?) => { - bail!($span, format!($fmt, $($arg),+)) + $crate::error!($span, format!($fmt, $($arg),+)) }; } @@ -44,12 +53,6 @@ impl Error { message: message.into(), } } - - /// Create a boxed vector containing one error. The return value is suitable - /// as the `Err` variant of a [`TypResult`]. - pub fn boxed(span: Span, message: impl Into) -> Box> { - Box::new(vec![Self::new(span, message)]) - } } /// A part of an error's [trace](Error::trace). @@ -67,8 +70,12 @@ impl Display for Tracepoint { Tracepoint::Call(Some(name)) => { write!(f, "error occured in this call of function `{}`", name) } - Tracepoint::Call(None) => f.pad("error occured in this function call"), - Tracepoint::Import => f.pad("error occured while importing this module"), + Tracepoint::Call(None) => { + write!(f, "error occured in this function call") + } + Tracepoint::Import => { + write!(f, "error occured while importing this module") + } } } } @@ -84,7 +91,7 @@ where S: Into, { fn at(self, span: Span) -> TypResult { - self.map_err(|message| Error::boxed(span, message)) + self.map_err(|message| error!(span, message)) } } diff --git a/src/eval/control.rs b/src/eval/control.rs index b310bfb84..166676d49 100644 --- a/src/eval/control.rs +++ b/src/eval/control.rs @@ -1,5 +1,5 @@ use super::{ops, EvalResult, Value}; -use crate::diag::{At, Error, TypError}; +use crate::diag::{At, TypError}; use crate::syntax::Span; /// A control flow event that occurred during evaluation. @@ -25,12 +25,14 @@ impl From for Control { impl From for TypError { fn from(control: Control) -> Self { match control { - Control::Break(_, span) => Error::boxed(span, "cannot break outside of loop"), + Control::Break(_, span) => { + error!(span, "cannot break outside of loop") + } Control::Continue(_, span) => { - Error::boxed(span, "cannot continue outside of loop") + error!(span, "cannot continue outside of loop") } Control::Return(_, _, span) => { - Error::boxed(span, "cannot return outside of function") + error!(span, "cannot return outside of function") } Control::Err(e) => e, } diff --git a/src/eval/mod.rs b/src/eval/mod.rs index e00a40f28..4ccf377b2 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -37,7 +37,7 @@ pub use value::*; use unicode_segmentation::UnicodeSegmentation; -use crate::diag::{At, Error, StrResult, Trace, Tracepoint, TypResult}; +use crate::diag::{At, StrResult, Trace, Tracepoint, TypResult}; use crate::geom::{Angle, Fractional, Length, Relative}; use crate::library; use crate::syntax::ast::*; @@ -725,11 +725,9 @@ impl Eval for IncludeExpr { fn import(ctx: &mut Context, path: &str, span: Span) -> TypResult { // Load the source file. let full = ctx.resolve(path); - let id = ctx.sources.load(&full).map_err(|err| { - Error::boxed(span, match err.kind() { - std::io::ErrorKind::NotFound => "file not found".into(), - _ => format!("failed to load source file ({})", err), - }) + let id = ctx.sources.load(&full).map_err(|err| match err.kind() { + std::io::ErrorKind::NotFound => error!(span, "file not found"), + _ => error!(span, "failed to load source file ({})", err), })?; // Prevent cyclic importing. diff --git a/src/library/graphics/image.rs b/src/library/graphics/image.rs index 54793754d..d11de9d1c 100644 --- a/src/library/graphics/image.rs +++ b/src/library/graphics/image.rs @@ -1,4 +1,3 @@ -use crate::diag::Error; use crate::image::ImageId; use crate::library::prelude::*; use crate::library::text::TextNode; @@ -15,11 +14,9 @@ impl ImageNode { fn construct(ctx: &mut Context, args: &mut Args) -> TypResult { let path = args.expect::>("path to image file")?; let full = ctx.resolve(&path.v); - let id = ctx.images.load(&full).map_err(|err| { - Error::boxed(path.span, match err.kind() { - std::io::ErrorKind::NotFound => "file not found".into(), - _ => format!("failed to load image ({})", err), - }) + let id = ctx.images.load(&full).map_err(|err| match err.kind() { + std::io::ErrorKind::NotFound => error!(path.span, "file not found"), + _ => error!(path.span, "failed to load image ({})", err), })?; let width = args.named("width")?; diff --git a/src/library/prelude.rs b/src/library/prelude.rs index 001798f37..39be5994b 100644 --- a/src/library/prelude.rs +++ b/src/library/prelude.rs @@ -7,7 +7,7 @@ pub use std::sync::Arc; pub use typst_macros::node; -pub use crate::diag::{with_alternative, At, StrResult, TypResult}; +pub use crate::diag::{with_alternative, At, Error, StrResult, TypError, TypResult}; pub use crate::eval::{ Arg, Args, Array, Cast, Content, Dict, Func, Key, Layout, LayoutNode, Merge, Node, Regions, Scope, Show, ShowNode, Smart, StyleChain, StyleMap, StyleVec, Value, diff --git a/tests/typeset.rs b/tests/typeset.rs index dfc8bff9d..5e9b79fea 100644 --- a/tests/typeset.rs +++ b/tests/typeset.rs @@ -18,7 +18,7 @@ use typst::loading::FsLoader; use typst::parse::Scanner; use typst::source::SourceFile; use typst::syntax::Span; -use typst::Context; +use typst::{bail, Context}; const TYP_DIR: &str = "./typ"; const REF_DIR: &str = "./ref"; @@ -77,10 +77,7 @@ fn main() { let lhs = args.expect::("left-hand side")?; let rhs = args.expect::("right-hand side")?; if lhs != rhs { - return Err(Error::boxed( - args.span, - format!("Assertion failed: {:?} != {:?}", lhs, rhs), - )); + bail!(args.span, "Assertion failed: {:?} != {:?}", lhs, rhs,); } Ok(Value::None) });