Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make less use of thiserror and more unified error handling #496

Merged
merged 1 commit into from
May 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions crates/rune/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ pub(crate) use self::assembly::{Assembly, AssemblyInst};

pub(crate) mod attrs;

mod compile_error;
pub(crate) use self::compile_error::{
mod error;
pub(crate) use self::error::{
CompileErrorKind, HirErrorKind, IrErrorKind, ParseErrorKind, QueryErrorKind, ResolveErrorKind,
};
pub use self::compile_error::{Error, ImportStep};
pub use self::error::{Error, ImportStep};

mod compile_visitor;
pub use self::compile_visitor::CompileVisitor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::fmt;

use crate::no_std as std;
use crate::no_std::io;
use crate::no_std::path::PathBuf;
Expand All @@ -13,14 +15,73 @@ use crate::macros::{SyntheticId, SyntheticKind};
use crate::parse::{Expectation, Id, IntoExpectation, LexerMode};
use crate::runtime::debug::DebugSignature;
use crate::runtime::{AccessError, Label, TypeInfo, TypeOf};
use crate::shared::ScopeError;
use crate::shared::scopes::MissingLocal;
use crate::{Hash, SourceId};

error! {
/// An error raised by the compiler.
#[derive(Debug)]
pub struct Error {
kind: CompileErrorKind,
/// An error raised by the compiler.
#[derive(Debug)]
pub struct Error {
span: Span,
kind: Box<CompileErrorKind>,
}

impl Error {
/// Construct a new compile error.
#[allow(unused)]
pub(crate) fn new<S, K>(spanned: S, kind: K) -> Self
where
S: Spanned,
CompileErrorKind: From<K>,
{
Self {
span: spanned.span(),
kind: Box::new(CompileErrorKind::from(kind)),
}
}

/// Construct an error which is made of a single message.
pub fn msg<S, M>(spanned: S, message: M) -> Self
where
S: Spanned,
M: fmt::Display,
{
Self {
span: Spanned::span(&spanned),
kind: Box::new(CompileErrorKind::Custom {
message: message.to_string().into(),
}),
}
}

/// Get the kind of the error.
#[cfg(feature = "emit")]
pub(crate) fn kind(&self) -> &CompileErrorKind {
&self.kind
}

/// Convert into the kind of the error.
#[cfg(test)]
pub(crate) fn into_kind(self) -> CompileErrorKind {
*self.kind
}
}

impl Spanned for Error {
#[inline]
fn span(&self) -> Span {
self.span
}
}

impl crate::no_std::error::Error for Error {
fn source(&self) -> Option<&(dyn crate::no_std::error::Error + 'static)> {
self.kind.source()
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
::core::fmt::Display::fmt(&self.kind, f)
}
}

Expand All @@ -36,6 +97,13 @@ where
}
}

impl From<MissingLocal<'_>> for CompileErrorKind {
#[inline]
fn from(MissingLocal(name): MissingLocal<'_>) -> Self {
CompileErrorKind::MissingLocal { name: name.into() }
}
}

impl From<&'static str> for CompileErrorKind {
fn from(value: &'static str) -> Self {
CompileErrorKind::Custom {
Expand Down Expand Up @@ -132,8 +200,6 @@ pub(crate) enum CompileErrorKind {
AccessError(#[from] AccessError),
#[error("{0}")]
HirError(#[from] HirErrorKind),
#[error("{0}")]
ScopeError(#[from] ScopeError),
#[error("Failed to load `{path}`: {error}")]
FileError {
path: PathBuf,
Expand Down Expand Up @@ -498,12 +564,6 @@ pub(crate) enum IrErrorKind {
/// The field that was missing.
field: Box<str>,
},
/// Missing local with the given name.
#[error("Missing local `{name}`")]
MissingLocal {
/// Name of the missing local.
name: Box<str>,
},
/// Missing const or local with the given name.
#[error("No constant or local matching `{name}`")]
MissingConst {
Expand Down
2 changes: 1 addition & 1 deletion crates/rune/src/compile/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ impl IrPat {
match self {
IrPat::Ignore => Ok(true),
IrPat::Binding(name) => {
interp.scopes.decl(name, value, spanned)?;
interp.scopes.decl(name, value).with_span(spanned)?;
Ok(true)
}
}
Expand Down
10 changes: 5 additions & 5 deletions crates/rune/src/compile/ir/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ fn eval_ir_branches(
None
};

interp.scopes.pop(branch, guard)?;
interp.scopes.pop(guard).with_span(branch)?;

if let Some(output) = output {
return Ok(output);
Expand Down Expand Up @@ -228,7 +228,7 @@ fn eval_ir_decl(
) -> Result<IrValue, IrEvalOutcome> {
interp.budget.take(ir)?;
let value = eval_ir(&ir.value, interp, used)?;
interp.scopes.decl(&ir.name, value, ir)?;
interp.scopes.decl(&ir.name, value).with_span(ir)?;
Ok(IrValue::Unit)
}

Expand All @@ -244,7 +244,7 @@ fn eval_ir_loop(

loop {
if let Some(condition) = &ir.condition {
interp.scopes.clear_current(condition)?;
interp.scopes.clear_current().with_span(condition)?;

let value = eval_ir_condition(condition, interp, used)?;

Expand Down Expand Up @@ -281,7 +281,7 @@ fn eval_ir_loop(
};
}

interp.scopes.pop(ir, guard)?;
interp.scopes.pop(guard).with_span(ir)?;
Ok(IrValue::Unit)
}

Expand Down Expand Up @@ -317,7 +317,7 @@ fn eval_ir_scope(
IrValue::Unit
};

interp.scopes.pop(ir, guard)?;
interp.scopes.pop(guard).with_span(ir)?;
Ok(value)
}

Expand Down
18 changes: 8 additions & 10 deletions crates/rune/src/compile/ir/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use crate::compile::{self, IrErrorKind, IrEvalOutcome, IrValue, ItemId, ModId, W
use crate::compile::{ir, meta};
use crate::query::{Query, Used};
use crate::runtime::{ConstValue, Object, Tuple};
use crate::shared::scopes::MissingLocal;

/// Ir Scopes.
pub(crate) type IrScopes = crate::shared::Scopes<IrValue>;
pub(crate) type IrScopes = crate::shared::scopes::Scopes<IrValue>;

/// The interpreter that executed [Ir][crate::ir::Ir].
pub struct IrInterpreter<'a> {
Expand Down Expand Up @@ -129,10 +130,7 @@ impl IrInterpreter<'_> {
}

if name.starts_with(char::is_lowercase) {
Err(compile::Error::new(
spanned,
IrErrorKind::MissingLocal { name: name.into() },
))
Err(compile::Error::new(spanned, MissingLocal(name)))
} else {
Err(compile::Error::new(
spanned,
Expand Down Expand Up @@ -174,17 +172,17 @@ impl IrInterpreter<'_> {
}

if base.is_empty() {
return Err(compile::Error::new(spanned, IrErrorKind::FnNotFound));
return Err(compile::Error::new(span, IrErrorKind::FnNotFound));
}

base.pop();
};

let const_fn = self.q.const_fn_for((spanned.span(), id))?;
let const_fn = self.q.const_fn_for((span, id))?;

if const_fn.ir_fn.args.len() != args.len() {
return Err(compile::Error::new(
spanned,
span,
IrErrorKind::ArgumentCountMismatch {
actual: args.len(),
expected: const_fn.ir_fn.args.len(),
Expand All @@ -195,11 +193,11 @@ impl IrInterpreter<'_> {
let guard = self.scopes.isolate();

for (name, value) in const_fn.ir_fn.args.iter().zip(args) {
self.scopes.decl(name, value, spanned)?;
self.scopes.decl(name, value).with_span(span)?;
}

let value = self.eval_value(&const_fn.ir_fn.ir, used)?;
self.scopes.pop(spanned, guard)?;
self.scopes.pop(guard).with_span(span)?;
Ok(value)
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/rune/src/compile/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::compile::ir;
use crate::compile::meta;
use crate::compile::{
self, Assembly, CompileErrorKind, IrBudget, IrCompiler, IrInterpreter, ItemId, ItemMeta,
Location, Options,
Location, Options, WithSpan,
};
use crate::hir;
use crate::query::{Named, Query, QueryConstFn, Used};
Expand Down Expand Up @@ -202,7 +202,7 @@ impl<'a> Assembler<'a> {

for (ir, name) in compiled {
let value = interpreter.eval_value(&ir, Used::Used)?;
interpreter.scopes.decl(name, value, span)?;
interpreter.scopes.decl(name, value).with_span(span)?;
}

interpreter.module = query_const_fn.item_meta.module;
Expand Down
17 changes: 12 additions & 5 deletions crates/rune/src/compile/v1/assemble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ fn pat_lit_inst(
.resolve(resolve_context!(c.q))?
.as_i64(true)
.with_span(span)?;

return Ok(Some(Inst::EqInteger { integer }));
}
hir::ExprKind::Lit(lit) => match lit {
Expand Down Expand Up @@ -955,7 +956,8 @@ fn block(hir: &hir::Block<'_>, c: &mut Assembler<'_>, needs: Needs) -> compile::

c.contexts
.pop()
.ok_or_else(|| compile::Error::msg(span, "missing parent context"))?;
.ok_or("Missing parent context")
.with_span(span)?;

Ok(Asm::top(span))
}
Expand Down Expand Up @@ -1236,7 +1238,9 @@ fn expr_assign(
let segment = path
.first
.try_as_ident()
.ok_or_else(|| compile::Error::msg(path, "unsupported path"))?;
.ok_or("Unsupported path")
.with_span(path)?;

let ident = segment.resolve(resolve_context!(c.q))?;
let var = c.scopes.get_var(c.q.visitor, ident, c.source_id, span)?;
c.asm.push(Inst::Replace { offset: var.offset }, span);
Expand Down Expand Up @@ -1654,7 +1658,8 @@ fn expr_break(
.scopes
.total_var_count(span)?
.checked_sub(last_loop.break_var_count)
.ok_or_else(|| compile::Error::msg(span, "var count should be larger"))?;
.ok_or("Var count should be larger")
.with_span(span)?;

if last_loop.needs.value() {
if has_value {
Expand Down Expand Up @@ -2097,7 +2102,8 @@ fn expr_continue(
.scopes
.total_var_count(span)?
.checked_sub(last_loop.continue_var_count)
.ok_or_else(|| compile::Error::msg(span, "var count should be larger"))?;
.ok_or("Var count should be larger")
.with_span(span)?;

c.locals_pop(vars, span);

Expand Down Expand Up @@ -2998,7 +3004,8 @@ fn expr_select(

c.contexts
.pop()
.ok_or_else(|| compile::Error::msg(span, "missing parent context"))?;
.ok_or("Missing parent context")
.with_span(span)?;

Ok(Asm::top(span))
}
Expand Down
6 changes: 3 additions & 3 deletions crates/rune/src/diagnostics/fatal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,19 @@ impl crate::no_std::error::Error for FatalDiagnostic {
#[allow(missing_docs)]
#[non_exhaustive]
pub enum FatalDiagnosticKind {
#[error("compile error")]
#[error("Compile error")]
CompileError(
#[from]
#[source]
compile::Error,
),
#[error("linker error")]
#[error("Linker error")]
LinkError(
#[from]
#[source]
LinkerError,
),
/// An internal error.
#[error("internal error: {0}")]
#[error("Internal error: {0}")]
Internal(&'static str),
}
Loading