improvements 3
This commit is contained in:
parent
eca34960f0
commit
1e4d453f8b
35 changed files with 402 additions and 117 deletions
|
@ -34,7 +34,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer {
|
|||
) -> Result<ZirAssemblyStatement<'ast, T>, Self::Error> {
|
||||
match s {
|
||||
ZirAssemblyStatement::Assignment(_, _) => Ok(s),
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs) => {
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs, metadata) => {
|
||||
let lhs = self.fold_field_expression(lhs)?;
|
||||
let rhs = self.fold_field_expression(rhs)?;
|
||||
|
||||
|
@ -53,7 +53,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer {
|
|||
};
|
||||
|
||||
match is_quadratic {
|
||||
true => Ok(ZirAssemblyStatement::Constraint(lhs, rhs)),
|
||||
true => Ok(ZirAssemblyStatement::Constraint(lhs, rhs, metadata)),
|
||||
false => {
|
||||
let sub = FieldElementExpression::Sub(box lhs, box rhs);
|
||||
let mut lqc = LinQuadComb::try_from(sub.clone()).map_err(|_| {
|
||||
|
@ -82,18 +82,26 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer {
|
|||
let common_factor = lqc
|
||||
.quadratic
|
||||
.iter()
|
||||
.fold(None, |acc: Option<Vec<Identifier>>, (_, a, b)| {
|
||||
Some(
|
||||
acc.map(|factors| {
|
||||
factors
|
||||
.into_iter()
|
||||
.filter(|f| f == a || f == b)
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_else(|| vec![a.clone(), b.clone()]),
|
||||
)
|
||||
.scan(None, |state: &mut Option<Vec<&Identifier>>, (_, a, b)| {
|
||||
// short circuit if we do not have any common factors anymore
|
||||
if *state == Some(vec![]) {
|
||||
None
|
||||
} else {
|
||||
match state {
|
||||
// only keep factors found in this term
|
||||
Some(factors) => {
|
||||
factors.retain(|&x| x == a || x == b);
|
||||
}
|
||||
// initialisation step, start with the two factors in the first term
|
||||
None => {
|
||||
*state = Some(vec![a, b]);
|
||||
}
|
||||
};
|
||||
state.clone()
|
||||
}
|
||||
})
|
||||
.and_then(|mut v| v.pop());
|
||||
.last()
|
||||
.and_then(|mut v| v.pop().cloned());
|
||||
|
||||
match common_factor {
|
||||
Some(factor) => Ok(FieldElementExpression::Mult(
|
||||
|
@ -150,7 +158,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer {
|
|||
.fold_field_expression(rhs)
|
||||
.map_err(|e| Error(e.to_string()))?;
|
||||
|
||||
Ok(ZirAssemblyStatement::Constraint(lhs, rhs))
|
||||
Ok(ZirAssemblyStatement::Constraint(lhs, rhs, metadata))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,6 +169,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use zokrates_ast::common::SourceMetadata;
|
||||
use zokrates_field::Bn128Field;
|
||||
|
||||
#[test]
|
||||
|
@ -178,9 +187,14 @@ mod tests {
|
|||
box FieldElementExpression::identifier("a".into()),
|
||||
box FieldElementExpression::identifier("b".into()),
|
||||
),
|
||||
SourceMetadata::default(),
|
||||
);
|
||||
let result = AssemblyTransformer
|
||||
.fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs))
|
||||
.fold_assembly_statement(ZirAssemblyStatement::Constraint(
|
||||
lhs,
|
||||
rhs,
|
||||
SourceMetadata::default(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(result, expected);
|
||||
|
@ -198,8 +212,11 @@ mod tests {
|
|||
box FieldElementExpression::identifier("c".into()),
|
||||
);
|
||||
|
||||
let result =
|
||||
AssemblyTransformer.fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs));
|
||||
let result = AssemblyTransformer.fold_assembly_statement(ZirAssemblyStatement::Constraint(
|
||||
lhs,
|
||||
rhs,
|
||||
SourceMetadata::default(),
|
||||
));
|
||||
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
@ -228,10 +245,15 @@ mod tests {
|
|||
),
|
||||
box FieldElementExpression::identifier("b".into()),
|
||||
),
|
||||
SourceMetadata::default(),
|
||||
);
|
||||
|
||||
let result = AssemblyTransformer
|
||||
.fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs))
|
||||
.fold_assembly_statement(ZirAssemblyStatement::Constraint(
|
||||
lhs,
|
||||
rhs,
|
||||
SourceMetadata::default(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(result, expected);
|
||||
|
@ -261,9 +283,14 @@ mod tests {
|
|||
),
|
||||
box FieldElementExpression::identifier("b".into()),
|
||||
),
|
||||
SourceMetadata::default(),
|
||||
);
|
||||
let result = AssemblyTransformer
|
||||
.fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs))
|
||||
.fold_assembly_statement(ZirAssemblyStatement::Constraint(
|
||||
lhs,
|
||||
rhs,
|
||||
SourceMetadata::default(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(result, expected);
|
||||
|
@ -363,9 +390,14 @@ mod tests {
|
|||
box FieldElementExpression::identifier("a".into()),
|
||||
);
|
||||
|
||||
let expected = ZirAssemblyStatement::Constraint(lhs_expected, rhs_expected);
|
||||
let expected =
|
||||
ZirAssemblyStatement::Constraint(lhs_expected, rhs_expected, SourceMetadata::default());
|
||||
let result = AssemblyTransformer
|
||||
.fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs))
|
||||
.fold_assembly_statement(ZirAssemblyStatement::Constraint(
|
||||
lhs,
|
||||
rhs,
|
||||
SourceMetadata::default(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(result, expected);
|
||||
|
|
|
@ -559,10 +559,10 @@ fn fold_assembly_statement<'ast, T: Field>(
|
|||
|
||||
zir::ZirAssemblyStatement::Assignment(a, function)
|
||||
}
|
||||
typed::TypedAssemblyStatement::Constraint(lhs, rhs) => {
|
||||
typed::TypedAssemblyStatement::Constraint(lhs, rhs, metadata) => {
|
||||
let lhs = f.fold_field_expression(statements_buffer, lhs);
|
||||
let rhs = f.fold_field_expression(statements_buffer, rhs);
|
||||
zir::ZirAssemblyStatement::Constraint(lhs, rhs)
|
||||
zir::ZirAssemblyStatement::Constraint(lhs, rhs, metadata)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -596,10 +596,11 @@ fn fold_statement<'ast, T: Field>(
|
|||
let e = f.fold_boolean_expression(statements_buffer, e);
|
||||
let error = match error {
|
||||
typed::RuntimeError::SourceAssertion(metadata) => {
|
||||
zir::RuntimeError::SourceAssertion(metadata.to_string())
|
||||
zir::RuntimeError::SourceAssertion(metadata)
|
||||
}
|
||||
typed::RuntimeError::SelectRangeCheck => zir::RuntimeError::SelectRangeCheck,
|
||||
typed::RuntimeError::DivisionByZero => zir::RuntimeError::DivisionByZero,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
vec![zir::ZirStatement::Assertion(e, error)]
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ pub type Constants<'ast, T> = HashMap<Identifier<'ast>, TypedExpression<'ast, T>
|
|||
pub enum Error {
|
||||
Type(String),
|
||||
AssertionFailed(String),
|
||||
ValueTooLarge(String),
|
||||
InvalidValue(String),
|
||||
OutOfBounds(u128, u128),
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ impl fmt::Display for Error {
|
|||
match self {
|
||||
Error::Type(s) => write!(f, "{}", s),
|
||||
Error::AssertionFailed(s) => write!(f, "{}", s),
|
||||
Error::ValueTooLarge(s) => write!(f, "{}", s),
|
||||
Error::InvalidValue(s) => write!(f, "{}", s),
|
||||
Error::OutOfBounds(index, size) => write!(
|
||||
f,
|
||||
"Out of bounds index ({} >= {}) found during static analysis",
|
||||
|
@ -401,8 +401,27 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
match embed_call.arguments.iter().all(|a| a.is_constant()) {
|
||||
true => {
|
||||
let r: Option<TypedExpression<'ast, T>> = match embed_call.embed {
|
||||
FlatEmbed::FieldToBoolUnsafe => Ok(None), // todo
|
||||
FlatEmbed::BitArrayLe => Ok(None), // todo
|
||||
FlatEmbed::BitArrayLe => Ok(None), // todo
|
||||
FlatEmbed::FieldToBoolUnsafe => {
|
||||
match FieldElementExpression::try_from_typed(
|
||||
embed_call.arguments[0].clone(),
|
||||
) {
|
||||
Ok(FieldElementExpression::Number(n)) if n == T::from(0) => {
|
||||
Ok(Some(BooleanExpression::Value(false).into()))
|
||||
}
|
||||
Ok(FieldElementExpression::Number(n)) if n == T::from(1) => {
|
||||
Ok(Some(BooleanExpression::Value(true).into()))
|
||||
}
|
||||
Ok(FieldElementExpression::Number(n)) => {
|
||||
Err(Error::InvalidValue(format!(
|
||||
"Cannot call `{}` with value `{}`: should be 0 or 1",
|
||||
embed_call.embed.id(),
|
||||
n
|
||||
)))
|
||||
}
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
FlatEmbed::U64FromBits => Ok(Some(process_u_from_bits(
|
||||
&embed_call.arguments,
|
||||
UBitwidth::B64,
|
||||
|
@ -460,7 +479,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
}
|
||||
|
||||
if acc != T::zero() {
|
||||
Err(Error::ValueTooLarge(format!(
|
||||
Err(Error::InvalidValue(format!(
|
||||
"Cannot unpack `{}` to `{}`: value is too large",
|
||||
num,
|
||||
assignee.get_type()
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use crate::common::SourceMetadata;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use std::fmt::Write;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
|
||||
pub enum RuntimeError {
|
||||
SourceAssemblyConstraint,
|
||||
BellmanConstraint,
|
||||
BellmanOneBinding,
|
||||
BellmanInputBinding,
|
||||
|
@ -26,7 +27,8 @@ pub enum RuntimeError {
|
|||
Euclidean,
|
||||
ShaXor,
|
||||
Division,
|
||||
SourceAssertion(String),
|
||||
SourceAssertion(SourceMetadata),
|
||||
SourceAssemblyConstraint(SourceMetadata),
|
||||
ArgumentBitness,
|
||||
SelectRangeCheck,
|
||||
}
|
||||
|
@ -34,7 +36,9 @@ pub enum RuntimeError {
|
|||
impl From<crate::zir::RuntimeError> for RuntimeError {
|
||||
fn from(error: crate::zir::RuntimeError) -> Self {
|
||||
match error {
|
||||
crate::zir::RuntimeError::SourceAssertion(s) => RuntimeError::SourceAssertion(s),
|
||||
crate::zir::RuntimeError::SourceAssertion(metadata) => {
|
||||
RuntimeError::SourceAssertion(metadata)
|
||||
}
|
||||
crate::zir::RuntimeError::SelectRangeCheck => RuntimeError::SelectRangeCheck,
|
||||
crate::zir::RuntimeError::DivisionByZero => RuntimeError::Inverse,
|
||||
crate::zir::RuntimeError::IncompleteDynamicRange => {
|
||||
|
@ -50,7 +54,7 @@ impl RuntimeError {
|
|||
|
||||
!matches!(
|
||||
self,
|
||||
SourceAssemblyConstraint
|
||||
SourceAssemblyConstraint(_)
|
||||
| SourceAssertion(_)
|
||||
| Inverse
|
||||
| SelectRangeCheck
|
||||
|
@ -64,8 +68,8 @@ impl fmt::Display for RuntimeError {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use RuntimeError::*;
|
||||
|
||||
let mut buf = String::new();
|
||||
let msg = match self {
|
||||
SourceAssemblyConstraint => "Source constraint is unsatisfied",
|
||||
BellmanConstraint => "Bellman constraint is unsatisfied",
|
||||
BellmanOneBinding => "Bellman ~one binding is unsatisfied",
|
||||
BellmanInputBinding => "Bellman input binding is unsatisfied",
|
||||
|
@ -90,7 +94,14 @@ impl fmt::Display for RuntimeError {
|
|||
Euclidean => "Euclidean check failed",
|
||||
ShaXor => "Internal Sha check failed",
|
||||
Division => "Division check failed",
|
||||
SourceAssertion(m) => m.as_str(),
|
||||
SourceAssertion(m) => {
|
||||
write!(&mut buf, "Assertion failed at {}", m).unwrap();
|
||||
buf.as_str()
|
||||
}
|
||||
SourceAssemblyConstraint(m) => {
|
||||
write!(&mut buf, "Unsatisfied constraint at {}", m).unwrap();
|
||||
buf.as_str()
|
||||
}
|
||||
ArgumentBitness => "Argument bitness check failed",
|
||||
SelectRangeCheck => "Out of bounds array access",
|
||||
};
|
||||
|
|
34
zokrates_ast/src/common/metadata.rs
Normal file
34
zokrates_ast/src/common/metadata.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use crate::untyped::Position;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Hash, Eq, Default, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct SourceMetadata {
|
||||
pub file: String,
|
||||
pub position: Position,
|
||||
pub message: Option<String>,
|
||||
}
|
||||
|
||||
impl SourceMetadata {
|
||||
pub fn new(file: String, position: Position) -> Self {
|
||||
Self {
|
||||
file,
|
||||
position,
|
||||
message: None,
|
||||
}
|
||||
}
|
||||
pub fn message(mut self, message: Option<String>) -> Self {
|
||||
self.message = message;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for SourceMetadata {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}:{}", self.file, self.position)?;
|
||||
match &self.message {
|
||||
Some(m) => write!(f, ": \"{}\"", m),
|
||||
None => write!(f, ""),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
pub mod embed;
|
||||
mod error;
|
||||
mod format_string;
|
||||
mod metadata;
|
||||
mod parameter;
|
||||
mod solvers;
|
||||
mod variable;
|
||||
|
||||
pub use self::embed::FlatEmbed;
|
||||
pub use self::error::RuntimeError;
|
||||
pub use self::metadata::SourceMetadata;
|
||||
pub use self::parameter::Parameter;
|
||||
pub use self::solvers::Solver;
|
||||
pub use self::variable::Variable;
|
||||
|
|
|
@ -20,11 +20,22 @@ pub enum Solver<'ast, T> {
|
|||
SnarkVerifyBls12377(usize),
|
||||
}
|
||||
|
||||
impl<'ast, T: fmt::Debug> fmt::Display for Solver<'ast, T> {
|
||||
impl<'ast, T> fmt::Display for Solver<'ast, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Solver::ConditionEq => write!(f, "ConditionEq"),
|
||||
Solver::Bits(n) => write!(f, "Bits({})", n),
|
||||
Solver::Div => write!(f, "Div"),
|
||||
Solver::Xor => write!(f, "Xor"),
|
||||
Solver::Or => write!(f, "Or"),
|
||||
Solver::ShaAndXorAndXorAnd => write!(f, "ShaAndXorAndXorAnd"),
|
||||
Solver::ShaCh => write!(f, "ShaCh"),
|
||||
Solver::EuclideanDiv => write!(f, "EuclideanDiv"),
|
||||
Solver::Zir(_) => write!(f, "Zir(..)"),
|
||||
_ => write!(f, "{:?}", self),
|
||||
#[cfg(feature = "bellman")]
|
||||
Solver::Sha256Round => write!(f, "Sha256Round"),
|
||||
#[cfg(feature = "ark")]
|
||||
Solver::SnarkVerifyBls12377(n) => write!(f, "SnarkVerifyBls12377({})", n),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -530,10 +530,13 @@ pub fn fold_assembly_statement<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
TypedAssemblyStatement::Assignment(a, e) => {
|
||||
TypedAssemblyStatement::Assignment(f.fold_assignee(a), f.fold_field_expression(e))
|
||||
}
|
||||
TypedAssemblyStatement::Constraint(lhs, rhs) => TypedAssemblyStatement::Constraint(
|
||||
f.fold_field_expression(lhs),
|
||||
f.fold_field_expression(rhs),
|
||||
),
|
||||
TypedAssemblyStatement::Constraint(lhs, rhs, metadata) => {
|
||||
TypedAssemblyStatement::Constraint(
|
||||
f.fold_field_expression(lhs),
|
||||
f.fold_field_expression(rhs),
|
||||
metadata,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,9 +27,7 @@ pub use self::types::{
|
|||
UBitwidth,
|
||||
};
|
||||
use self::types::{ConcreteArrayType, ConcreteStructType};
|
||||
|
||||
use crate::typed::types::{ConcreteGenericsAssignment, IntoType};
|
||||
use crate::untyped::Position;
|
||||
|
||||
pub use self::variable::{ConcreteVariable, DeclarationVariable, GVariable, Variable};
|
||||
use std::marker::PhantomData;
|
||||
|
@ -38,7 +36,7 @@ use std::path::{Path, PathBuf};
|
|||
pub use crate::typed::integer::IntExpression;
|
||||
pub use crate::typed::uint::{bitwidth, UExpression, UExpressionInner, UMetadata};
|
||||
|
||||
use crate::common::{FlatEmbed, FormatString};
|
||||
use crate::common::{FlatEmbed, FormatString, SourceMetadata};
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
|
@ -569,26 +567,10 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedAssignee<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Hash, Eq, Default, PartialOrd, Ord)]
|
||||
pub struct AssertionMetadata {
|
||||
pub file: String,
|
||||
pub position: Position,
|
||||
pub message: Option<String>,
|
||||
}
|
||||
|
||||
impl fmt::Display for AssertionMetadata {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Assertion failed at {}:{}", self.file, self.position)?;
|
||||
match &self.message {
|
||||
Some(m) => write!(f, ": \"{}\"", m),
|
||||
None => write!(f, ""),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
|
||||
pub enum RuntimeError {
|
||||
SourceAssertion(AssertionMetadata),
|
||||
SourceAssertion(SourceMetadata),
|
||||
SourceAssemblyConstraint(SourceMetadata),
|
||||
SelectRangeCheck,
|
||||
DivisionByZero,
|
||||
}
|
||||
|
@ -596,7 +578,12 @@ pub enum RuntimeError {
|
|||
impl fmt::Display for RuntimeError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
RuntimeError::SourceAssertion(metadata) => write!(f, "{}", metadata),
|
||||
RuntimeError::SourceAssertion(metadata) => {
|
||||
write!(f, "Assertion failed at {}", metadata)
|
||||
}
|
||||
RuntimeError::SourceAssemblyConstraint(metadata) => {
|
||||
write!(f, "Unsatisfied constraint at {}", metadata)
|
||||
}
|
||||
RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"),
|
||||
RuntimeError::DivisionByZero => write!(f, "Division by zero"),
|
||||
}
|
||||
|
@ -683,6 +670,7 @@ pub enum TypedAssemblyStatement<'ast, T> {
|
|||
Constraint(
|
||||
FieldElementExpression<'ast, T>,
|
||||
FieldElementExpression<'ast, T>,
|
||||
SourceMetadata,
|
||||
),
|
||||
}
|
||||
|
||||
|
@ -692,7 +680,7 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedAssemblyStatement<'ast, T> {
|
|||
TypedAssemblyStatement::Assignment(ref lhs, ref rhs) => {
|
||||
write!(f, "{} <-- {}", lhs, rhs)
|
||||
}
|
||||
TypedAssemblyStatement::Constraint(ref lhs, ref rhs) => {
|
||||
TypedAssemblyStatement::Constraint(ref lhs, ref rhs, _) => {
|
||||
write!(f, "{} === {}", lhs, rhs)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -531,10 +531,13 @@ pub fn fold_assembly_statement<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
TypedAssemblyStatement::Assignment(a, e) => {
|
||||
TypedAssemblyStatement::Assignment(f.fold_assignee(a)?, f.fold_field_expression(e)?)
|
||||
}
|
||||
TypedAssemblyStatement::Constraint(lhs, rhs) => TypedAssemblyStatement::Constraint(
|
||||
f.fold_field_expression(lhs)?,
|
||||
f.fold_field_expression(rhs)?,
|
||||
),
|
||||
TypedAssemblyStatement::Constraint(lhs, rhs, metadata) => {
|
||||
TypedAssemblyStatement::Constraint(
|
||||
f.fold_field_expression(lhs)?,
|
||||
f.fold_field_expression(rhs)?,
|
||||
metadata,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Copy, Hash, Default, PartialOrd, Ord)]
|
||||
#[derive(Clone, PartialEq, Eq, Copy, Hash, Default, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct Position {
|
||||
pub line: usize,
|
||||
pub col: usize,
|
||||
|
|
|
@ -152,10 +152,10 @@ pub fn fold_assembly_statement<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
let function = f.fold_function(function);
|
||||
ZirAssemblyStatement::Assignment(assignees, function)
|
||||
}
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs) => {
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs, metadata) => {
|
||||
let lhs = f.fold_field_expression(lhs);
|
||||
let rhs = f.fold_field_expression(rhs);
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs)
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs, metadata)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ mod variable;
|
|||
pub use self::parameter::Parameter;
|
||||
pub use self::types::{Type, UBitwidth};
|
||||
pub use self::variable::Variable;
|
||||
use crate::common::{FlatEmbed, FormatString};
|
||||
use crate::common::{FlatEmbed, FormatString, SourceMetadata};
|
||||
use crate::typed::ConcreteType;
|
||||
pub use crate::zir::uint::{ShouldReduce, UExpression, UExpressionInner, UMetadata};
|
||||
|
||||
|
@ -94,7 +94,7 @@ pub type ZirAssignee<'ast> = Variable<'ast>;
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)]
|
||||
pub enum RuntimeError {
|
||||
SourceAssertion(String),
|
||||
SourceAssertion(SourceMetadata),
|
||||
SelectRangeCheck,
|
||||
DivisionByZero,
|
||||
IncompleteDynamicRange,
|
||||
|
@ -103,7 +103,9 @@ pub enum RuntimeError {
|
|||
impl fmt::Display for RuntimeError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
RuntimeError::SourceAssertion(message) => write!(f, "{}", message),
|
||||
RuntimeError::SourceAssertion(metadata) => {
|
||||
write!(f, "Assertion failed at {}", metadata)
|
||||
}
|
||||
RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"),
|
||||
RuntimeError::DivisionByZero => write!(f, "Division by zero"),
|
||||
RuntimeError::IncompleteDynamicRange => write!(f, "Dynamic comparison is incomplete"),
|
||||
|
@ -113,7 +115,7 @@ impl fmt::Display for RuntimeError {
|
|||
|
||||
impl RuntimeError {
|
||||
pub fn mock() -> Self {
|
||||
RuntimeError::SourceAssertion(String::default())
|
||||
RuntimeError::SourceAssertion(SourceMetadata::default())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,6 +128,7 @@ pub enum ZirAssemblyStatement<'ast, T> {
|
|||
Constraint(
|
||||
FieldElementExpression<'ast, T>,
|
||||
FieldElementExpression<'ast, T>,
|
||||
SourceMetadata,
|
||||
),
|
||||
}
|
||||
|
||||
|
@ -143,7 +146,7 @@ impl<'ast, T: fmt::Display> fmt::Display for ZirAssemblyStatement<'ast, T> {
|
|||
rhs
|
||||
)
|
||||
}
|
||||
ZirAssemblyStatement::Constraint(ref lhs, ref rhs) => {
|
||||
ZirAssemblyStatement::Constraint(ref lhs, ref rhs, _) => {
|
||||
write!(f, "{} === {}", lhs, rhs)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,10 +172,10 @@ pub fn fold_assembly_statement<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
let function = f.fold_function(function)?;
|
||||
ZirAssemblyStatement::Assignment(assignees, function)
|
||||
}
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs) => {
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs, metadata) => {
|
||||
let lhs = f.fold_field_expression(lhs)?;
|
||||
let rhs = f.fold_field_expression(rhs)?;
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs)
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs, metadata)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2248,13 +2248,13 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
let directive = FlatDirective::new(outputs, Solver::Zir(function), inputs);
|
||||
statements_flattened.push_back(FlatStatement::Directive(directive));
|
||||
}
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs) => {
|
||||
ZirAssemblyStatement::Constraint(lhs, rhs, metadata) => {
|
||||
let lhs = self.flatten_field_expression(statements_flattened, lhs);
|
||||
let rhs = self.flatten_field_expression(statements_flattened, rhs);
|
||||
statements_flattened.push_back(FlatStatement::Condition(
|
||||
lhs,
|
||||
rhs,
|
||||
RuntimeError::SourceAssemblyConstraint,
|
||||
RuntimeError::SourceAssemblyConstraint(metadata),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use num_bigint::BigUint;
|
|||
use std::collections::{btree_map::Entry, BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
use zokrates_ast::common::FormatString;
|
||||
use zokrates_ast::common::{FormatString, SourceMetadata};
|
||||
use zokrates_ast::typed::types::{GGenericsAssignment, GTupleType, GenericsAssignment};
|
||||
use zokrates_ast::typed::SourceIdentifier;
|
||||
use zokrates_ast::typed::*;
|
||||
|
@ -1811,7 +1811,11 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
match assignee.get_type() {
|
||||
Type::FieldElement => Ok(vec![
|
||||
TypedAssemblyStatement::Assignment(assignee.clone(), e.clone()),
|
||||
TypedAssemblyStatement::Constraint(assignee.into(), e),
|
||||
TypedAssemblyStatement::Constraint(
|
||||
assignee.into(),
|
||||
e,
|
||||
SourceMetadata::new(module_id.display().to_string(), pos.0),
|
||||
),
|
||||
]),
|
||||
ty => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
|
@ -1853,7 +1857,11 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
}),
|
||||
}?;
|
||||
|
||||
Ok(vec![TypedAssemblyStatement::Constraint(lhs, rhs)])
|
||||
Ok(vec![TypedAssemblyStatement::Constraint(
|
||||
lhs,
|
||||
rhs,
|
||||
SourceMetadata::new(module_id.display().to_string(), pos.0),
|
||||
)])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2097,11 +2105,10 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
match e {
|
||||
TypedExpression::Boolean(e) => Ok(TypedStatement::Assertion(
|
||||
e,
|
||||
RuntimeError::SourceAssertion(AssertionMetadata {
|
||||
file: module_id.display().to_string(),
|
||||
position: pos.0,
|
||||
message,
|
||||
}),
|
||||
RuntimeError::SourceAssertion(
|
||||
SourceMetadata::new(module_id.display().to_string(), pos.0)
|
||||
.message(message),
|
||||
),
|
||||
)),
|
||||
e => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
|
|
|
@ -29,7 +29,15 @@
|
|||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": "SourceAssemblyConstraint"
|
||||
"error": {
|
||||
"SourceAssemblyConstraint": {
|
||||
"file": "tests/tests/assembly/binary_check.zok",
|
||||
"position": {
|
||||
"line": 3,
|
||||
"col": 9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,15 @@
|
|||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": "SourceAssemblyConstraint"
|
||||
"error": {
|
||||
"SourceAssemblyConstraint": {
|
||||
"file": "tests/tests/assembly/bitify.zok",
|
||||
"position": {
|
||||
"line": 14,
|
||||
"col": 9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,15 @@
|
|||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": "SourceAssemblyConstraint"
|
||||
"error": {
|
||||
"SourceAssemblyConstraint": {
|
||||
"file": "tests/tests/assembly/division.zok",
|
||||
"position": {
|
||||
"line": 6,
|
||||
"col": 9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,13 @@
|
|||
"left": "0",
|
||||
"right": "1",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/assert_array_equality.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/assert_array_equality.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,13 @@
|
|||
"left": "0",
|
||||
"right": "1",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/assert_one.zok:2:2"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/assert_one.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,15 @@
|
|||
"output": {
|
||||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": "SourceAssemblyConstraint"
|
||||
"error": {
|
||||
"SourceAssemblyConstraint": {
|
||||
"file": "tests/tests/embed/field_to_bool.zok",
|
||||
"position": {
|
||||
"line": 5,
|
||||
"col": 9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,13 @@
|
|||
"left": "0",
|
||||
"right": "1",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/conditional_bound_throw.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/panics/conditional_bound_throw.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +34,13 @@
|
|||
"left": "1",
|
||||
"right": "0",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/conditional_bound_throw.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/panics/conditional_bound_throw.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +56,13 @@
|
|||
"left": "2",
|
||||
"right": "0",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/conditional_bound_throw.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/panics/conditional_bound_throw.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,13 @@
|
|||
"left": "0",
|
||||
"right": "1",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/deep_branch.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/panics/deep_branch.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,13 @@
|
|||
"left": "0",
|
||||
"right": "1",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/loop_bound.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/panics/loop_bound.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,13 @@
|
|||
"left": "1",
|
||||
"right": "21888242871839275222246405745257275088548364400416034343698204186575808495577",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/panic_isolation.zok:22:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/panics/panic_isolation.zok",
|
||||
"position": {
|
||||
"line": 22,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,13 @@
|
|||
"left": "1",
|
||||
"right": "0",
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/panics/panic_isolation.zok:17:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/panics/panic_isolation.zok",
|
||||
"position": {
|
||||
"line": 17,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_ge.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_ge.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +31,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_ge.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_ge.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_gt.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +31,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_gt.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +51,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_gt.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt_big_constant.zok:4:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_gt_big_constant.zok",
|
||||
"position": {
|
||||
"line": 4,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +33,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt_big_constant.zok:4:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_gt_big_constant.zok",
|
||||
"position": {
|
||||
"line": 4,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_le.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_le.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +51,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_le.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_le.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_lt.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +51,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_lt.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt_big_constant.zok:4:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_lt_big_constant.zok",
|
||||
"position": {
|
||||
"line": 4,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt_u8.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_lt_u8.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +51,13 @@
|
|||
"Err": {
|
||||
"UnsatisfiedConstraint": {
|
||||
"error": {
|
||||
"SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt_u8.zok:2:5"
|
||||
"SourceAssertion": {
|
||||
"file": "./tests/tests/range_check/assert_lt_u8.zok",
|
||||
"position": {
|
||||
"line": 2,
|
||||
"col": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -440,11 +440,11 @@ mod ast {
|
|||
AssignConstrain(AssignConstrainOperator),
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[derive(Debug, FromPest, PartialEq, Eq, Clone)]
|
||||
#[pest_ast(rule(Rule::op_asm_assign))]
|
||||
pub struct AssignOperator;
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[derive(Debug, FromPest, PartialEq, Eq, Clone)]
|
||||
#[pest_ast(rule(Rule::op_asm_assign_constrain))]
|
||||
pub struct AssignConstrainOperator;
|
||||
|
||||
|
|
Loading…
Reference in a new issue