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

chore(ssa refactor): Implement acir_gen errors #2071

Merged
merged 16 commits into from
Jul 31, 2023
39 changes: 21 additions & 18 deletions crates/noirc_evaluator/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//! Noir Evaluator has two types of errors
//!
//! [RuntimeError] that should be displayed to the user
//! [RuntimeError]s that should be displayed to the user
//!
//! Internal Consistency Evaluators Errors [ICEError]
//! that are used for checking internal logics of the SSA
//! [InternalError]s that are used for checking internal logics of the SSA
//!
//! An Error of the former is a user Error
//! An Error of the former is an user Error
jfecher marked this conversation as resolved.
Show resolved Hide resolved
//!
//! An Error of the latter is an error in the implementation of the compiler
use acvm::FieldElement;
Expand All @@ -20,7 +19,7 @@ pub enum RuntimeError {
#[error("Failed constraint")]
FailedConstraint { lhs: FieldElement, rhs: FieldElement, location: Option<Location> },
#[error(transparent)]
ICEError(#[from] ICEError),
InternalError(#[from] InternalError),
#[error("Index out of bounds, array has size {index:?}, but index was {array_size:?}")]
IndexOutOfBounds { index: usize, array_size: usize, location: Option<Location> },
#[error("All Witnesses are by default u{num_bits:?} Applying this type does not apply any constraints.\n We also currently do not allow integers of size more than {num_bits:?}, this will be handled by BigIntegers.")]
Expand All @@ -34,16 +33,18 @@ pub enum RuntimeError {
}

#[derive(Debug, PartialEq, Eq, Clone, Error)]
pub enum ICEError {
#[error("ICE: Both expressions are reduced to be degree<=1")]
pub enum InternalError {
#[error("ICE: Both expressions should have degree<=1")]
DegreeNotReduced { location: Option<Location> },
#[error("Try to get element from empty array")]
EmptyArray { location: Option<Location> },
#[error("ICE: {message:?}")]
General { message: String, location: Option<Location> },
#[error("ICE: {name:?} missing {arg:?} arg")]
MissingArg { name: String, arg: String, location: Option<Location> },
#[error("ICE: {name:?} should be a constant")]
NotAConstant { name: String, location: Option<Location> },
#[error("{name:?} is not implmented yet")]
#[error("{name:?} is not implemented yet")]
NotImplemented { name: String, location: Option<Location> },
#[error("ICE: Undeclared AcirVar")]
UndeclaredAcirVar { location: Option<Location> },
Expand All @@ -54,14 +55,15 @@ pub enum ICEError {
impl From<RuntimeError> for FileDiagnostic {
fn from(error: RuntimeError) -> Self {
match error {
RuntimeError::ICEError(ref ice_error) => match ice_error {
ICEError::DegreeNotReduced { location }
| ICEError::General { location, .. }
| ICEError::MissingArg { location, .. }
| ICEError::NotAConstant { location, .. }
| ICEError::NotImplemented { location, .. }
| ICEError::UndeclaredAcirVar { location }
| ICEError::UnExpected { location, .. } => {
RuntimeError::InternalError(ref ice_error) => match ice_error {
InternalError::DegreeNotReduced { location }
| InternalError::EmptyArray { location }
| InternalError::General { location, .. }
| InternalError::MissingArg { location, .. }
| InternalError::NotAConstant { location, .. }
| InternalError::NotImplemented { location, .. }
| InternalError::UndeclaredAcirVar { location }
| InternalError::UnExpected { location, .. } => {
let file_id = location.map(|loc| loc.file).unwrap();
FileDiagnostic { file_id, diagnostic: error.into() }
}
Expand All @@ -82,8 +84,9 @@ impl From<RuntimeError> for FileDiagnostic {
impl From<RuntimeError> for Diagnostic {
fn from(error: RuntimeError) -> Diagnostic {
match error {
RuntimeError::ICEError(_) => Diagnostic::simple_error(
"Internal Consistency Evaluators Errors \n This is likely a bug. Consider Openning an issue at https://github.com/noir-lang/noir/issues".to_owned(),
RuntimeError::InternalError(_) => Diagnostic::simple_error(
"Internal Consistency Evaluators Errors: \n
This is likely a bug. Consider Opening an issue at https://github.com/noir-lang/noir/issues".to_owned(),
"".to_string(),
noirc_errors::Span::new(0..0)
),
Expand Down
2 changes: 1 addition & 1 deletion crates/noirc_evaluator/src/ssa_refactor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use noirc_frontend::monomorphization::ast::Program;
use self::{abi_gen::gen_abi, acir_gen::GeneratedAcir, ir::function::RuntimeType, ssa_gen::Ssa};

mod abi_gen;
pub(crate) mod acir_gen;
mod acir_gen;
pub mod ir;
mod opt;
mod ssa_builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::generated_acir::GeneratedAcir;
use crate::brillig::brillig_gen::brillig_directive;
use crate::errors::{ICEError, RuntimeError};
use crate::errors::{InternalError, RuntimeError};
use crate::ssa_refactor::acir_gen::{AcirDynamicArray, AcirValue};
use crate::ssa_refactor::ir::types::Type as SsaType;
use crate::ssa_refactor::ir::{instruction::Endian, types::NumericType};
Expand Down Expand Up @@ -474,7 +474,7 @@
/// Returns the quotient and remainder such that lhs = rhs * quotient + remainder
/// and |remainder| < |rhs|
/// and remainder has the same sign than lhs
/// Note that this is not the euclidian division, where we have instead remainder < |rhs|

Check warning on line 477 in crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (euclidian)
///
///
///
Expand Down Expand Up @@ -545,10 +545,10 @@

/// Converts the `AcirVar` to a `Witness` if it hasn't been already, and appends it to the
/// `GeneratedAcir`'s return witnesses.
pub(crate) fn return_var(&mut self, acir_var: AcirVar) -> Result<(), ICEError> {
pub(crate) fn return_var(&mut self, acir_var: AcirVar) -> Result<(), InternalError> {
let acir_var_data = match self.vars.get(&acir_var) {
Some(acir_var_data) => acir_var_data,
None => return Err(ICEError::UndeclaredAcirVar { location: self.get_location() }),
None => return Err(InternalError::UndeclaredAcirVar { location: self.get_location() }),
};
// TODO: Add caching to prevent expressions from being needlessly duplicated
let witness = match acir_var_data {
Expand Down Expand Up @@ -583,7 +583,7 @@
}

/// Returns an `AcirVar` which will be constrained to be lhs mod 2^{rhs}
/// In order to do this, we simply perform euclidian division of lhs by 2^{rhs}

Check warning on line 586 in crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (euclidian)
/// The remainder of the division is then lhs mod 2^{rhs}
pub(crate) fn truncate_var(
&mut self,
Expand Down Expand Up @@ -663,11 +663,11 @@
BlackBoxFunc::Pedersen => {
// The last argument of pedersen is the domain separator, which must be a constant
let domain_var = match inputs.pop() {
Some(domian_var) => domian_var.into_var()?,
Some(domain_var) => domain_var.into_var()?,
None => {
return Err(RuntimeError::ICEError(ICEError::MissingArg {
return Err(RuntimeError::InternalError(InternalError::MissingArg {
name: "pedersen call".to_string(),
arg: "domain seperator".to_string(),
arg: "domain separator".to_string(),
location: self.get_location(),
}))
}
Expand All @@ -676,7 +676,7 @@
let domain_constant = match self.vars[&domain_var].as_constant() {
Some(domain_constant) => domain_constant,
None => {
return Err(RuntimeError::ICEError(ICEError::NotAConstant {
return Err(RuntimeError::InternalError(InternalError::NotAConstant {
name: "domain separator".to_string(),
location: self.get_location(),
}))
Expand Down Expand Up @@ -743,7 +743,7 @@
let radix = match self.vars[&radix_var].as_constant() {
Some(radix) => radix.to_u128() as u32,
None => {
return Err(RuntimeError::ICEError(ICEError::NotAConstant {
return Err(RuntimeError::InternalError(InternalError::NotAConstant {
name: "radix".to_string(),
location: self.get_location(),
}));
Expand All @@ -753,7 +753,7 @@
let limb_count = match self.vars[&limb_count_var].as_constant() {
Some(limb_count) => limb_count.to_u128() as u32,
None => {
return Err(RuntimeError::ICEError(ICEError::NotAConstant {
return Err(RuntimeError::InternalError(InternalError::NotAConstant {
name: "limb_size".to_string(),
location: self.get_location(),
}));
Expand Down Expand Up @@ -858,7 +858,7 @@
code: Vec<BrilligOpcode>,
inputs: Vec<AcirValue>,
outputs: Vec<AcirType>,
) -> Result<Vec<AcirValue>, ICEError> {
) -> Result<Vec<AcirValue>, InternalError> {
let b_inputs = try_vecmap(inputs, |i| match i {
AcirValue::Var(var, _) => {
Ok(BrilligInputs::Single(self.vars[&var].to_expression().into_owned()))
Expand Down Expand Up @@ -901,7 +901,7 @@
&mut self,
var_expressions: &mut Vec<Expression>,
input: AcirValue,
) -> Result<(), ICEError> {
) -> Result<(), InternalError> {
match input {
AcirValue::Var(var, _) => {
var_expressions.push(self.vars[&var].to_expression().into_owned());
Expand Down Expand Up @@ -934,7 +934,7 @@
}

/// Recursively create acir values for returned arrays. This is necessary because a brillig returned array can have nested arrays as elements.
/// A singular array of witnesses is collected for a top level array, by deflattening the assigned witnesses at each level.

Check warning on line 937 in crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (deflattening)
fn brillig_array_output(
&mut self,
element_types: &[AcirType],
Expand Down Expand Up @@ -995,10 +995,10 @@
Ok(outputs_var)
}
/// Converts an AcirVar to a Witness
fn var_to_witness(&mut self, var: AcirVar) -> Result<Witness, ICEError> {
fn var_to_witness(&mut self, var: AcirVar) -> Result<Witness, InternalError> {
let var_data = match self.vars.get(&var) {
Some(var_data) => var_data,
None => return Err(ICEError::UndeclaredAcirVar { location: self.get_location() }),
None => return Err(InternalError::UndeclaredAcirVar { location: self.get_location() }),
};
Ok(self.acir_ir.get_or_create_witness(&var_data.to_expression()))
}
Expand All @@ -1021,7 +1021,7 @@
&mut self,
block_id: BlockId,
index: &AcirVar,
) -> Result<AcirVar, ICEError> {
) -> Result<AcirVar, InternalError> {
// Fetch the witness corresponding to the index
let index_witness = self.var_to_witness(*index)?;

Expand All @@ -1042,7 +1042,7 @@
block_id: BlockId,
index: &AcirVar,
value: &AcirVar,
) -> Result<(), ICEError> {
) -> Result<(), InternalError> {
// Fetch the witness corresponding to the index
//
let index_witness = self.var_to_witness(*index)?;
Expand All @@ -1063,7 +1063,7 @@
block_id: BlockId,
len: usize,
optional_values: Option<&[AcirValue]>,
) -> Result<(), ICEError> {
) -> Result<(), InternalError> {
// If the optional values are supplied, then we fill the initialized
// array with those values. If not, then we fill it with zeros.
let initialized_values = match optional_values {
Expand Down
Loading
Loading