Non-returning error macro

This commit is contained in:
Laurenz 2022-03-15 11:30:13 +01:00
parent 6f5b721fe5
commit ae0a56cdff
6 changed files with 35 additions and 34 deletions

View File

@ -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<String>) -> Box<Vec<Self>> {
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<String>,
{
fn at(self, span: Span) -> TypResult<T> {
self.map_err(|message| Error::boxed(span, message))
self.map_err(|message| error!(span, message))
}
}

View File

@ -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<TypError> for Control {
impl From<Control> 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,
}

View File

@ -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<Module> {
// 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.

View File

@ -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<Content> {
let path = args.expect::<Spanned<EcoString>>("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")?;

View File

@ -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,

View File

@ -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::<Value>("left-hand side")?;
let rhs = args.expect::<Value>("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)
});