Skip to content

Commit

Permalink
feat(sol-diagnostic): add bail and other eyre functions
Browse files Browse the repository at this point in the history
  • Loading branch information
aripiprazole committed May 29, 2024
1 parent 25db558 commit 22e95de
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 2 deletions.
163 changes: 162 additions & 1 deletion sol-diagnostic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<T> IntoSolDiagnostic<T> for Result<T, sol_eyre::Report> {
}

#[derive(Clone, Debug)]
pub struct Diagnostic(Arc<sol_eyre::Report>);
pub struct Diagnostic(pub Arc<sol_eyre::Report>);

impl Eq for Diagnostic {}

Expand Down Expand Up @@ -147,3 +147,164 @@ impl miette::SourceCode for TextSource {
)))
}
}

/// Return early with an error.
///
/// This macro is equivalent to `return Err(From::from($err))`.
///
/// # Example
///
/// ```
/// # use sol_eyre::{bail, Result};
/// #
/// # fn has_permission(user: usize, resource: usize) -> bool {
/// # true
/// # }
/// #
/// # fn main() -> Result<()> {
/// # let user = 0;
/// # let resource = 0;
/// #
/// if !has_permission(user, resource) {
/// bail!("permission denied for accessing {}", resource);
/// }
/// # Ok(())
/// # }
/// ```
///
/// ```
/// # use sol_diagnostic::{bail, Result};
/// # use thiserror::Error;
/// #
/// # const MAX_DEPTH: usize = 1;
/// #
/// #[derive(Error, Debug)]
/// enum ScienceError {
/// #[error("recursion limit exceeded")]
/// RecursionLimitExceeded,
/// # #[error("...")]
/// # More = (stringify! {
/// ...
/// # }, 1).1,
/// }
///
/// # fn main() -> Result<()> {
/// # let depth = 0;
/// # let err: &'static dyn std::error::Error = &ScienceError::RecursionLimitExceeded;
/// #
/// if depth > MAX_DEPTH {
/// bail!(ScienceError::RecursionLimitExceeded);
/// }
/// # Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! bail {
($msg:literal $(,)?) => {
return Err($crate::Diagnostic(std::sync::Arc::new(sol_eyre::eyre!($msg))));
};
($err:expr $(,)?) => {
return Err($crate::Diagnostic(std::sync::Arc::new(sol_eyre::eyre!($err))));
};
($fmt:expr, $($arg:tt)*) => {
return Err($crate::Diagnostic(std::sync::Arc::new(sol_eyre::eyre!($fmt, $($arg)*))));
};
}

/// Return early with an error if a condition is not satisfied.
///
/// This macro is equivalent to `if !$cond { return Err(From::from($err)); }`.
///
/// Analogously to `assert!`, `ensure!` takes a condition and exits the function
/// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
/// rather than panicking.
///
/// # Example
///
/// ```
/// # use sol_diagnostic::{ensure, Result};
/// #
/// # fn main() -> Result<()> {
/// # let user = 0;
/// #
/// ensure!(user == 0, "only user 0 is allowed");
/// # Ok(())
/// # }
/// ```
///
/// ```
/// # use sol_diagnostic::{ensure, Result};
/// # use thiserror::Error;
/// #
/// # const MAX_DEPTH: usize = 1;
/// #
/// #[derive(Error, Debug)]
/// enum ScienceError {
/// #[error("recursion limit exceeded")]
/// RecursionLimitExceeded,
/// # #[error("...")]
/// # More = (stringify! {
/// ...
/// # }, 1).1,
/// }
///
/// # fn main() -> Result<()> {
/// # let depth = 0;
/// #
/// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
/// # Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! ensure {
($cond:expr, $msg:literal $(,)?) => {
if !$cond {
return Err($crate::Diagnostic(std::sync::Arc::new(sol_eyre::eyre!($msg))));
}
};
($cond:expr, $err:expr $(,)?) => {
if !$cond {
return Err($crate::Diagnostic(std::sync::Arc::new(sol_eyre::eyre!($err))));
}
};
($cond:expr, $fmt:expr, $($arg:tt)*) => {
if !$cond {
return Err($crate::Diagnostic(std::sync::Arc::new(sol_eyre::eyre!($fmt, $($arg)*))));
}
};
}

/// Construct an ad-hoc error from a string.
///
/// This evaluates to an `Error`. It can take either just a string, or a format
/// string with arguments. It also can take any custom type which implements
/// `Debug` and `Display`.
///
/// # Example
///
/// ```
/// # type V = ();
/// #
/// use sol_diagnostic::{eyre, Result};
///
/// fn lookup(key: &str) -> Result<V> {
/// if key.len() != 16 {
/// return Err(eyre!("key length must be 16 characters, got {:?}", key));
/// }
///
/// // ...
/// # Ok(())
/// }
/// ```
#[macro_export]
macro_rules! eyre {
($msg:literal $(,)?) => ({
$crate::Diagnostic(std::sync::Arc::new(sol_eyre::eyre!($msg)))
});
($err:expr $(,)?) => ({
$crate::Diagnostic(std::sync::Arc::new(sol_eyre::eyre!($err)))
});
($fmt:expr, $($arg:tt)*) => ({
$crate::Diagnostic(std::sync::Arc::new(sol_eyre::eyre!($fmt, $($arg)*)))
});
}
3 changes: 2 additions & 1 deletion sol-thir-lowering/src/infer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use sol_diagnostic::bail;
use sol_thir::{
shared::{Constructor, ConstructorKind},
ElaboratedTerm,
Expand Down Expand Up @@ -61,7 +62,7 @@ pub fn thir_infer(
Call(_) => todo!(),
Lam(_) => todo!(),
Pi(_) => todo!(),
Sigma(_) => todo!(),
Sigma(_) => bail!("sigma types are not supported yet"),
Hole(_) => {
let meta = MetaVar::new(None);
let term = Term::InsertedMeta(meta.clone());
Expand Down

0 comments on commit 22e95de

Please sign in to comment.