mirror of
https://github.com/typst/typst
synced 2025-05-15 09:35:28 +08:00
Non-returning error macro
This commit is contained in:
parent
6f5b721fe5
commit
ae0a56cdff
31
src/diag.rs
31
src/diag.rs
@ -4,14 +4,23 @@ use std::fmt::{self, Display, Formatter};
|
|||||||
|
|
||||||
use crate::syntax::{Span, Spanned};
|
use crate::syntax::{Span, Spanned};
|
||||||
|
|
||||||
/// Early-return with a vec-boxed [`Error`].
|
/// Early-return with a [`TypError`].
|
||||||
|
#[macro_export]
|
||||||
macro_rules! bail {
|
macro_rules! bail {
|
||||||
|
($($tts:tt)*) => {
|
||||||
|
return Err($crate::error!($($tts)*).into())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a [`TypError`].
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! error {
|
||||||
($span:expr, $message:expr $(,)?) => {
|
($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),+ $(,)?) => {
|
($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(),
|
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).
|
/// A part of an error's [trace](Error::trace).
|
||||||
@ -67,8 +70,12 @@ impl Display for Tracepoint {
|
|||||||
Tracepoint::Call(Some(name)) => {
|
Tracepoint::Call(Some(name)) => {
|
||||||
write!(f, "error occured in this call of function `{}`", name)
|
write!(f, "error occured in this call of function `{}`", name)
|
||||||
}
|
}
|
||||||
Tracepoint::Call(None) => f.pad("error occured in this function call"),
|
Tracepoint::Call(None) => {
|
||||||
Tracepoint::Import => f.pad("error occured while importing this module"),
|
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>,
|
S: Into<String>,
|
||||||
{
|
{
|
||||||
fn at(self, span: Span) -> TypResult<T> {
|
fn at(self, span: Span) -> TypResult<T> {
|
||||||
self.map_err(|message| Error::boxed(span, message))
|
self.map_err(|message| error!(span, message))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::{ops, EvalResult, Value};
|
use super::{ops, EvalResult, Value};
|
||||||
use crate::diag::{At, Error, TypError};
|
use crate::diag::{At, TypError};
|
||||||
use crate::syntax::Span;
|
use crate::syntax::Span;
|
||||||
|
|
||||||
/// A control flow event that occurred during evaluation.
|
/// A control flow event that occurred during evaluation.
|
||||||
@ -25,12 +25,14 @@ impl From<TypError> for Control {
|
|||||||
impl From<Control> for TypError {
|
impl From<Control> for TypError {
|
||||||
fn from(control: Control) -> Self {
|
fn from(control: Control) -> Self {
|
||||||
match control {
|
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) => {
|
Control::Continue(_, span) => {
|
||||||
Error::boxed(span, "cannot continue outside of loop")
|
error!(span, "cannot continue outside of loop")
|
||||||
}
|
}
|
||||||
Control::Return(_, _, span) => {
|
Control::Return(_, _, span) => {
|
||||||
Error::boxed(span, "cannot return outside of function")
|
error!(span, "cannot return outside of function")
|
||||||
}
|
}
|
||||||
Control::Err(e) => e,
|
Control::Err(e) => e,
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ pub use value::*;
|
|||||||
|
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
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::geom::{Angle, Fractional, Length, Relative};
|
||||||
use crate::library;
|
use crate::library;
|
||||||
use crate::syntax::ast::*;
|
use crate::syntax::ast::*;
|
||||||
@ -725,11 +725,9 @@ impl Eval for IncludeExpr {
|
|||||||
fn import(ctx: &mut Context, path: &str, span: Span) -> TypResult<Module> {
|
fn import(ctx: &mut Context, path: &str, span: Span) -> TypResult<Module> {
|
||||||
// Load the source file.
|
// Load the source file.
|
||||||
let full = ctx.resolve(path);
|
let full = ctx.resolve(path);
|
||||||
let id = ctx.sources.load(&full).map_err(|err| {
|
let id = ctx.sources.load(&full).map_err(|err| match err.kind() {
|
||||||
Error::boxed(span, match err.kind() {
|
std::io::ErrorKind::NotFound => error!(span, "file not found"),
|
||||||
std::io::ErrorKind::NotFound => "file not found".into(),
|
_ => error!(span, "failed to load source file ({})", err),
|
||||||
_ => format!("failed to load source file ({})", err),
|
|
||||||
})
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Prevent cyclic importing.
|
// Prevent cyclic importing.
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use crate::diag::Error;
|
|
||||||
use crate::image::ImageId;
|
use crate::image::ImageId;
|
||||||
use crate::library::prelude::*;
|
use crate::library::prelude::*;
|
||||||
use crate::library::text::TextNode;
|
use crate::library::text::TextNode;
|
||||||
@ -15,11 +14,9 @@ impl ImageNode {
|
|||||||
fn construct(ctx: &mut Context, args: &mut Args) -> TypResult<Content> {
|
fn construct(ctx: &mut Context, args: &mut Args) -> TypResult<Content> {
|
||||||
let path = args.expect::<Spanned<EcoString>>("path to image file")?;
|
let path = args.expect::<Spanned<EcoString>>("path to image file")?;
|
||||||
let full = ctx.resolve(&path.v);
|
let full = ctx.resolve(&path.v);
|
||||||
let id = ctx.images.load(&full).map_err(|err| {
|
let id = ctx.images.load(&full).map_err(|err| match err.kind() {
|
||||||
Error::boxed(path.span, match err.kind() {
|
std::io::ErrorKind::NotFound => error!(path.span, "file not found"),
|
||||||
std::io::ErrorKind::NotFound => "file not found".into(),
|
_ => error!(path.span, "failed to load image ({})", err),
|
||||||
_ => format!("failed to load image ({})", err),
|
|
||||||
})
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let width = args.named("width")?;
|
let width = args.named("width")?;
|
||||||
|
@ -7,7 +7,7 @@ pub use std::sync::Arc;
|
|||||||
|
|
||||||
pub use typst_macros::node;
|
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::{
|
pub use crate::eval::{
|
||||||
Arg, Args, Array, Cast, Content, Dict, Func, Key, Layout, LayoutNode, Merge, Node,
|
Arg, Args, Array, Cast, Content, Dict, Func, Key, Layout, LayoutNode, Merge, Node,
|
||||||
Regions, Scope, Show, ShowNode, Smart, StyleChain, StyleMap, StyleVec, Value,
|
Regions, Scope, Show, ShowNode, Smart, StyleChain, StyleMap, StyleVec, Value,
|
||||||
|
@ -18,7 +18,7 @@ use typst::loading::FsLoader;
|
|||||||
use typst::parse::Scanner;
|
use typst::parse::Scanner;
|
||||||
use typst::source::SourceFile;
|
use typst::source::SourceFile;
|
||||||
use typst::syntax::Span;
|
use typst::syntax::Span;
|
||||||
use typst::Context;
|
use typst::{bail, Context};
|
||||||
|
|
||||||
const TYP_DIR: &str = "./typ";
|
const TYP_DIR: &str = "./typ";
|
||||||
const REF_DIR: &str = "./ref";
|
const REF_DIR: &str = "./ref";
|
||||||
@ -77,10 +77,7 @@ fn main() {
|
|||||||
let lhs = args.expect::<Value>("left-hand side")?;
|
let lhs = args.expect::<Value>("left-hand side")?;
|
||||||
let rhs = args.expect::<Value>("right-hand side")?;
|
let rhs = args.expect::<Value>("right-hand side")?;
|
||||||
if lhs != rhs {
|
if lhs != rhs {
|
||||||
return Err(Error::boxed(
|
bail!(args.span, "Assertion failed: {:?} != {:?}", lhs, rhs,);
|
||||||
args.span,
|
|
||||||
format!("Assertion failed: {:?} != {:?}", lhs, rhs),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
Ok(Value::None)
|
Ok(Value::None)
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user