Skip to main content

cairo_vm/types/errors/
math_errors.rs

1// The `(*.0).0` syntax of thiserror falsely triggers this clippy warning
2#![allow(clippy::explicit_auto_deref)]
3
4use crate::Felt252;
5use num_bigint::{BigInt, BigUint};
6use thiserror::Error;
7
8use crate::types::relocatable::{MaybeRelocatable, Relocatable};
9
10#[derive(Debug, Error, PartialEq)]
11pub enum MathError {
12    // Math functions
13    #[error("{} is not divisible by {}", (*.0).0, (*.0).1)]
14    SafeDivFail(Box<(Felt252, Felt252)>),
15    #[error("{} is not divisible by {}", (*.0).0, (*.0).1)]
16    SafeDivFailBigInt(Box<(BigInt, BigInt)>),
17    #[error("{0} is not divisible by {1}")]
18    SafeDivFailU32(u32, u32),
19    #[error("{} is not divisible by {}", (*.0).0, (*.0).1)]
20    SafeDivFailUsize(Box<(usize, usize)>),
21    #[error("Attempted to divide by zero")]
22    DividedByZero,
23    #[error("Failed to calculate the square root of: {0})")]
24    FailedToGetSqrt(Box<BigUint>),
25    #[error("is_quad_residue: p must be > 0")]
26    IsQuadResidueZeroPrime,
27    // Relocatable Operations
28    #[error("Cant convert felt: {0} to Relocatable")]
29    Felt252ToRelocatable(Box<Felt252>),
30    #[error("Operation failed: {} - {}, offsets cant be negative", (*.0).0, (*.0).1)]
31    RelocatableSubFelt252NegOffset(Box<(Relocatable, Felt252)>),
32    #[error("Operation failed: {} - {}, offsets cant be negative", (*.0).0, (*.0).1)]
33    RelocatableSubUsizeNegOffset(Box<(Relocatable, usize)>),
34    #[error("Operation failed: {} + {}, maximum offset value exceeded", (*.0).0, (*.0).1)]
35    RelocatableAddFelt252OffsetExceeded(Box<(Relocatable, Felt252)>),
36    #[error("Operation failed: {} + {}, maximum offset value exceeded", (*.0).0, (*.0).1)]
37    RelocatableAddUsizeOffsetExceeded(Box<(Relocatable, usize)>),
38    #[error("Operation failed: {} + {}, can't add two relocatable values", (*.0).0, (*.0).1)]
39    RelocatableAdd(Box<(Relocatable, Relocatable)>),
40    #[error("Operation failed: {} - {}, can't add a relocatable value as a QM31 element", (*.0).0, (*.0).1)]
41    RelocatableQM31Add(Box<(MaybeRelocatable, MaybeRelocatable)>),
42    #[error("Operation failed: {} - {}, can't subtract a relocatable value or from a relocatable value as a QM31 element", (*.0).0, (*.0).1)]
43    RelocatableQM31Sub(Box<(MaybeRelocatable, MaybeRelocatable)>),
44    #[error("Operation failed: {} - {}, can't subtract two relocatable values with different segment indexes", (*.0).0, (*.0).1)]
45    RelocatableSubDiffIndex(Box<(Relocatable, Relocatable)>),
46    #[error(
47        "Operation failed: {}.divmod({}, divmod can only be performed between two integer values", (*.0).0, (*.0).1
48    )]
49    DivModWrongType(Box<(MaybeRelocatable, MaybeRelocatable)>),
50    #[error("Operation failed {} - {}, can't subtract a relocatable value from an integer", (*.0).0, (*.0).1)]
51    SubRelocatableFromInt(Box<(Felt252, Relocatable)>),
52    // Type conversions
53    #[error("Conversion to i32 failed for Felt252 {0}")]
54    Felt252ToI32Conversion(Box<Felt252>),
55    #[error("Conversion to u32 failed for Felt252 {0}")]
56    Felt252ToU32Conversion(Box<Felt252>),
57    #[error("Conversion to usize failed for Felt252 {0}")]
58    Felt252ToUsizeConversion(Box<Felt252>),
59    #[error("Conversion to u64 failed for Felt252 {0}")]
60    Felt252ToU64Conversion(Box<Felt252>),
61    #[error("Byte conversion error")]
62    ByteConversionError,
63    #[error(
64        "Operation failed: divmod({}, {}, {}), igcdex({}, {}) != 1 ", (*.0).0, (*.0).1, (*.0).2, (*.0).1, (*.0).2
65    )]
66    DivModIgcdexNotZero(Box<(BigInt, BigInt, BigInt)>),
67    #[error("Number is not a packing of a QM31 in reduced form: {0})")]
68    QM31UnreducedError(Box<Felt252>),
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[test]
76    // Test to catch possible enum size regressions
77    fn test_math_error_size() {
78        let size = std::mem::size_of::<MathError>();
79        assert!(size <= 16, "{size}")
80    }
81}