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

Error refactoring and thiserror 2.0 #1588

Merged
merged 12 commits into from
Dec 4, 2024
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- [BREAKING] Updated Winterfell dependency to v0.11 (#1586).
- [BREAKING] resolved flag collision in `--verify` command and added functionality for optional input/output files (#1513).
- [BREAKING] Cleanup benchmarks and examples in the `miden-vm` crate (#1587)
- [BREAKING] Use `thiserror` 2.0 to derive errors and refactor them (#1588).

#### Enhancements
- Added `miden_core::mast::MastForest::advice_map` to load it into the advice provider before the `MastForest` execution (#1574).
Expand Down
38 changes: 10 additions & 28 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ inherits = "release"
debug = true
debug-assertions = true
overflow-checks = true

[workspace.dependencies]
thiserror = { version = "2.0", default-features = false }
2 changes: 1 addition & 1 deletion air/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ std = ["vm-core/std", "winter-air/std", "thiserror/std"]
testing = []

[dependencies]
thiserror = { package = "miden-thiserror", version = "1.0", default-features = false }
thiserror = { workspace = true }
vm-core = { package = "miden-core", path = "../core", version = "0.11", default-features = false }
winter-air = { package = "winter-air", version = "0.11", default-features = false }
winter-prover = { package = "winter-prover", version = "0.11", default-features = false }
Expand Down
31 changes: 5 additions & 26 deletions air/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,12 @@
use alloc::string::String;
use core::fmt::{Display, Formatter};

use crate::trace::MIN_TRACE_LEN;

// EXECUTION ERROR
// EXECUTION OPTIONS ERROR
// ================================================================================================

#[derive(Debug)]
#[derive(Debug, thiserror::Error)]
pub enum ExecutionOptionsError {
ExpectedCyclesTooBig(u32, u32),
#[error("expected number of cycles {expected_cycles} must be smaller than the maximum number of cycles {max_cycles}")]
ExpectedCyclesTooBig { max_cycles: u32, expected_cycles: u32 },
#[error("maximum number of cycles {0} must be greater than the minimum number of cycles {MIN_TRACE_LEN}")]
MaxCycleNumTooSmall(u32),
OtherErrors(String),
}

impl Display for ExecutionOptionsError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
use ExecutionOptionsError::*;

match self {
ExpectedCyclesTooBig(max, expected) => {
write!(f, "The expected number of cycles must be smaller than the maximum number of cycles: maximum is {max}, but expectd is {expected}")
},
MaxCycleNumTooSmall(max) => {
write!(f, "The maximum number of cycles must be greater than the minimum number of cycles: minimum is {MIN_TRACE_LEN}, but maximum is {max}")
},
OtherErrors(error) => write!(f, "{error}"),
}
}
}

#[cfg(feature = "std")]
impl std::error::Error for ExecutionOptionsError {}
5 changes: 4 additions & 1 deletion air/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,10 @@ impl ExecutionOptions {
return Err(ExecutionOptionsError::MaxCycleNumTooSmall(expected_cycles));
}
if max_cycles < expected_cycles {
return Err(ExecutionOptionsError::ExpectedCyclesTooBig(max_cycles, expected_cycles));
return Err(ExecutionOptionsError::ExpectedCyclesTooBig {
max_cycles,
expected_cycles,
});
}

// Round up the expected number of cycles to the next power of two. If it is smaller than
Expand Down
48 changes: 32 additions & 16 deletions air/src/trace/rows.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use alloc::boxed::Box;
use core::{
fmt::{Display, Formatter},
ops::{Add, AddAssign, Bound, Index, IndexMut, Mul, RangeBounds, Sub, SubAssign},
Expand All @@ -7,10 +8,11 @@ use vm_core::Felt;

/// Represents the types of errors that can occur when converting from and into [`RowIndex`] and
/// using its operations.
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum RowIndexError<T> {
#[error("value is too large to be converted into RowIndex: {0}")]
InvalidSize(T),
#[derive(Debug, thiserror::Error)]
pub enum RowIndexError {
// This uses Box<str> rather than String because its stack size is 8 bytes smaller.
#[error("value {0} is larger than u32::MAX so it cannot be converted into a RowIndex")]
InvalidSize(Box<str>),
}

// ROW INDEX
Expand Down Expand Up @@ -71,25 +73,28 @@ impl From<RowIndex> for Felt {
/// # Panics
///
/// This function will panic if the number represented by the usize is greater than the maximum
/// [`RowIndex`] value, `u32::MAX`.
/// [`RowIndex`] value, [`u32::MAX`].
impl From<usize> for RowIndex {
fn from(value: usize) -> Self {
let value = u32::try_from(value).map_err(|_| RowIndexError::InvalidSize(value)).unwrap();
let value = u32::try_from(value)
.map_err(|_| RowIndexError::InvalidSize(format!("{}_usize", value).into()))
.unwrap();
value.into()
}
}

/// Converts a u64 value into a [`RowIndex`].
///
/// # Panics
/// # Errors
///
/// This function will panic if the number represented by the u64 is greater than the maximum
/// [`RowIndex`] value, `u32::MAX`.
/// This function returns an error if the number represented by the u64 is greater than the
/// maximum [`RowIndex`] value, [`u32::MAX`].
impl TryFrom<u64> for RowIndex {
type Error = RowIndexError<u64>;
type Error = RowIndexError;

fn try_from(value: u64) -> Result<Self, Self::Error> {
let value = u32::try_from(value).map_err(|_| RowIndexError::InvalidSize(value))?;
let value = u32::try_from(value)
.map_err(|_| RowIndexError::InvalidSize(format!("{}_u64", value).into()))?;
Ok(RowIndex::from(value))
}
}
Expand All @@ -107,7 +112,9 @@ impl From<u32> for RowIndex {
/// This function will panic if the number represented by the i32 is less than 0.
impl From<i32> for RowIndex {
fn from(value: i32) -> Self {
let value = u32::try_from(value).map_err(|_| RowIndexError::InvalidSize(value)).unwrap();
let value = u32::try_from(value)
.map_err(|_| RowIndexError::InvalidSize(format!("{}_i32", value).into()))
.unwrap();
RowIndex(value)
}
}
Expand All @@ -125,7 +132,9 @@ impl Sub<usize> for RowIndex {
type Output = RowIndex;

fn sub(self, rhs: usize) -> Self::Output {
let rhs = u32::try_from(rhs).map_err(|_| RowIndexError::InvalidSize(rhs)).unwrap();
let rhs = u32::try_from(rhs)
.map_err(|_| RowIndexError::InvalidSize(format!("{}_usize", rhs).into()))
.unwrap();
RowIndex(self.0 - rhs)
}
}
Expand Down Expand Up @@ -164,7 +173,9 @@ impl Add<usize> for RowIndex {
type Output = RowIndex;

fn add(self, rhs: usize) -> Self::Output {
let rhs = u32::try_from(rhs).map_err(|_| RowIndexError::InvalidSize(rhs)).unwrap();
let rhs = u32::try_from(rhs)
.map_err(|_| RowIndexError::InvalidSize(format!("{}_usize", rhs).into()))
.unwrap();
RowIndex(self.0 + rhs)
}
}
Expand Down Expand Up @@ -209,7 +220,10 @@ impl PartialEq<RowIndex> for RowIndex {

impl PartialEq<usize> for RowIndex {
fn eq(&self, rhs: &usize) -> bool {
self.0 == u32::try_from(*rhs).map_err(|_| RowIndexError::InvalidSize(*rhs)).unwrap()
self.0
== u32::try_from(*rhs)
.map_err(|_| RowIndexError::InvalidSize(format!("{}_usize", *rhs).into()))
.unwrap()
}
}

Expand All @@ -221,7 +235,9 @@ impl PartialEq<RowIndex> for i32 {

impl PartialOrd<usize> for RowIndex {
fn partial_cmp(&self, rhs: &usize) -> Option<core::cmp::Ordering> {
let rhs = u32::try_from(*rhs).map_err(|_| RowIndexError::InvalidSize(*rhs)).unwrap();
let rhs = u32::try_from(*rhs)
.map_err(|_| RowIndexError::InvalidSize(format!("{}_usize", *rhs).into()))
.unwrap();
self.0.partial_cmp(&rhs)
}
}
Expand Down
6 changes: 3 additions & 3 deletions assembly/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ doctest = false

[features]
default = ["std"]
std = ["aho-corasick/std", "miette/fancy", "miette/std", "thiserror/std", "vm-core/std"]
std = ["aho-corasick/std", "miette/fancy", "miette/std", "vm-core/std", "thiserror/std"]
testing = ["dep:regex"]

[dependencies]
aho-corasick = { version = "1.1", default-features = false }
lalrpop-util = { version = "0.20", default-features = false }
miette = { package = "miden-miette", version = "7.1", default-features = false, features = [
miette = { package = "miden-miette", version = "8.0", default-features = false, features = [
"fancy-no-syscall",
"derive"
] }
regex = { version = "1.10", optional = true, default-features = false, features = ["unicode", "perf"] }
smallvec = { version = "1.13", features = ["union", "const_generics", "const_new"] }
thiserror = { package = "miden-thiserror", version = "1.0", default-features = false }
thiserror = { workspace = true }
tracing = { version = "0.1", default-features = false, features = ["attributes"] }
unicode-width = { version = "0.2", features = ["no_std"] }
vm-core = { package = "miden-core", path = "../core", version = "0.11", default-features = false, features = [
Expand Down
Loading
Loading