diff --git a/changelogs/unreleased/1032-schaeff b/changelogs/unreleased/1032-schaeff new file mode 100644 index 00000000..3ee32845 --- /dev/null +++ b/changelogs/unreleased/1032-schaeff @@ -0,0 +1 @@ +Fail at compile time when complex types are known not to be equal \ No newline at end of file diff --git a/zokrates_cli/examples/compile_errors/assertion_unequal_arrays.zok b/zokrates_cli/examples/compile_errors/assertion_unequal_arrays.zok new file mode 100644 index 00000000..dc06d4a5 --- /dev/null +++ b/zokrates_cli/examples/compile_errors/assertion_unequal_arrays.zok @@ -0,0 +1,3 @@ +def main(): + assert([1f] == [2f]) + return \ No newline at end of file diff --git a/zokrates_core/src/static_analysis/zir_propagation.rs b/zokrates_core/src/static_analysis/zir_propagation.rs index 138a9c21..8971b2c1 100644 --- a/zokrates_core/src/static_analysis/zir_propagation.rs +++ b/zokrates_core/src/static_analysis/zir_propagation.rs @@ -2,8 +2,8 @@ use crate::zir::result_folder::fold_statement; use crate::zir::result_folder::ResultFolder; use crate::zir::types::UBitwidth; use crate::zir::{ - BooleanExpression, FieldElementExpression, Identifier, UExpression, UExpressionInner, - ZirExpression, ZirProgram, ZirStatement, + BooleanExpression, FieldElementExpression, Identifier, RuntimeError, UExpression, + UExpressionInner, ZirExpression, ZirProgram, ZirStatement, }; use std::collections::HashMap; use std::fmt; @@ -15,6 +15,7 @@ type Constants<'ast, T> = HashMap, ZirExpression<'ast, T>>; pub enum Error { OutOfBounds(u128, u128), DivisionByZero, + AssertionFailed(RuntimeError), } impl fmt::Display for Error { @@ -28,6 +29,7 @@ impl fmt::Display for Error { Error::DivisionByZero => { write!(f, "Division by zero detected in zir during static analysis",) } + Error::AssertionFailed(err) => write!(f, "{}", err), } } } @@ -53,6 +55,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { match s { ZirStatement::Assertion(e, error) => match self.fold_boolean_expression(e)? { BooleanExpression::Value(true) => Ok(vec![]), + BooleanExpression::Value(false) => Err(Error::AssertionFailed(error)), e => Ok(vec![ZirStatement::Assertion(e, error)]), }, ZirStatement::Definition(a, e) => { diff --git a/zokrates_core_test/tests/tests/assert_array_equality.json b/zokrates_core_test/tests/tests/assert_array_equality.json new file mode 100644 index 00000000..4eaf5a60 --- /dev/null +++ b/zokrates_core_test/tests/tests/assert_array_equality.json @@ -0,0 +1,32 @@ +{ + "entry_point": "./tests/tests/assert_array_equality.zok", + "curves": ["Bn128", "Bls12_381", "Bls12_377", "Bw6_761"], + "tests": [ + { + "input": { + "values": ["1", "2"] + }, + "output": { + "Ok": { + "values": [] + } + } + }, + { + "input": { + "values": ["1", "1"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "left": "0", + "right": "1", + "error": { + "SourceAssertion": "Assertion failed at ./tests/tests/assert_array_equality.zok:2:2" + } + } + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assert_array_equality.zok b/zokrates_core_test/tests/tests/assert_array_equality.zok new file mode 100644 index 00000000..c359ba58 --- /dev/null +++ b/zokrates_core_test/tests/tests/assert_array_equality.zok @@ -0,0 +1,3 @@ +def main(field[2] a): + assert(a == [1, 2]) + return \ No newline at end of file