use std::fmt::Display;
use leo_errors::Formatted;
use leo_span::Span;
use super::Value;
use crate::{BinaryOperation, UnaryOperation};
const CODE_PREFIX: &str = "CEV";
const CODE_MASK: i32 = 8000;
pub(crate) fn binary_op_failure(
lhs: &Value,
op: BinaryOperation,
rhs: &Value,
reason: impl Display,
span: Span,
) -> Formatted {
Formatted::error(
CODE_PREFIX,
CODE_MASK,
format!("binary operation `{lhs} {op} {rhs}` failed at compile time: {reason}"),
span,
)
.with_help(
"The operands are constant, so this operation was evaluated at compile time and would also fail at runtime. \
Adjust the operands to avoid the failure (e.g. division by zero or integer overflow).",
)
}
pub(crate) fn unary_op_failure(value: &Value, op: UnaryOperation, reason: impl Display, span: Span) -> Formatted {
Formatted::error(
CODE_PREFIX,
CODE_MASK + 1,
format!("unary operation `{value}.{op}()` failed at compile time: {reason}"),
span,
)
.with_help(
"The operand is constant, so this operation was evaluated at compile time and would also fail at runtime. \
Adjust the operand to avoid the failure (e.g. negating the minimum signed integer).",
)
}
pub(crate) fn intrinsic_failure(reason: impl Display, span: Span) -> Formatted {
Formatted::error(
CODE_PREFIX,
CODE_MASK + 2,
format!("compile-time evaluation of this intrinsic failed: {reason}"),
span,
)
.with_note("Reaching this error indicates an internal inconsistency: the type checker should have rejected this call. Please file an issue.")
}