mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-23 23:23:50 +03:00
Merge branch 'master' into pest_test
This commit is contained in:
commit
93f0f8a17b
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use leo_ast::{errors::ParserError, files::File, LeoAst};
|
||||
use leo_ast::LeoAst;
|
||||
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#![allow(clippy::module_inception)]
|
||||
|
||||
pub mod access;
|
||||
pub use access::*;
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#![allow(clippy::module_inception)]
|
||||
|
||||
pub mod annotations;
|
||||
pub use annotations::*;
|
||||
|
||||
|
@ -39,20 +39,17 @@ pub enum ParserError {
|
||||
|
||||
impl ParserError {
|
||||
pub fn set_path(&mut self, path: PathBuf) {
|
||||
match self {
|
||||
ParserError::SyntaxError(error) => {
|
||||
let new_error: Error<Rule> = match error {
|
||||
SyntaxError::Error(error) => {
|
||||
let new_error = error.clone();
|
||||
new_error.with_path(path.to_str().unwrap())
|
||||
}
|
||||
};
|
||||
if let ParserError::SyntaxError(error) = self {
|
||||
let new_error: Error<Rule> = match error {
|
||||
SyntaxError::Error(error) => {
|
||||
let new_error = error.clone();
|
||||
new_error.with_path(path.to_str().unwrap())
|
||||
}
|
||||
};
|
||||
|
||||
tracing::error!("{}", new_error);
|
||||
tracing::error!("{}", new_error);
|
||||
|
||||
*error = SyntaxError::Error(new_error);
|
||||
}
|
||||
_ => {}
|
||||
*error = SyntaxError::Error(new_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#![allow(clippy::module_inception)]
|
||||
|
||||
pub mod function_input;
|
||||
pub use function_input::*;
|
||||
|
||||
|
@ -39,11 +39,11 @@ pub struct ConditionalStatement<'ast> {
|
||||
|
||||
impl<'ast> fmt::Display for ConditionalStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "if ({}) {{\n", self.condition)?;
|
||||
write!(f, "\t{:#?}\n", self.statements)?;
|
||||
writeln!(f, "if ({}) {{", self.condition)?;
|
||||
writeln!(f, "\t{:#?}", self.statements)?;
|
||||
self.next
|
||||
.as_ref()
|
||||
.map(|n_or_e| write!(f, "}} {}", n_or_e))
|
||||
.unwrap_or(write!(f, "}}"))
|
||||
.unwrap_or_else(|| write!(f, "}}"))
|
||||
}
|
||||
}
|
||||
|
@ -135,6 +135,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
|
||||
/// Parses the Leo program file, constructs a syntax tree, and generates a program.
|
||||
#[allow(deprecated)]
|
||||
pub(crate) fn parse_program(&mut self) -> Result<(), CompilerError> {
|
||||
// Use the parser to construct the abstract syntax tree.
|
||||
let program_string = LeoAst::load_file(&self.main_file_path)?;
|
||||
|
@ -53,9 +53,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
// Unwrap assertion value and handle errors
|
||||
let result_option = match assert_expression {
|
||||
ConstrainedValue::Boolean(boolean) => boolean.get_value(),
|
||||
_ => return Err(ConsoleError::assertion_must_be_boolean(expression_string, span.clone())),
|
||||
_ => return Err(ConsoleError::assertion_must_be_boolean(expression_string, span)),
|
||||
};
|
||||
let result_bool = result_option.ok_or(ConsoleError::assertion_depends_on_input(span.clone()))?;
|
||||
let result_bool = result_option.ok_or_else(|| ConsoleError::assertion_depends_on_input(span.clone()))?;
|
||||
|
||||
if !result_bool {
|
||||
return Err(ConsoleError::assertion_failed(expression_string, span));
|
||||
|
@ -37,16 +37,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
return Err(ConsoleError::length(
|
||||
formatted.containers.len(),
|
||||
formatted.parameters.len(),
|
||||
formatted.span.clone(),
|
||||
formatted.span,
|
||||
));
|
||||
}
|
||||
|
||||
// Trim starting double quote `"`
|
||||
let mut string = formatted.string.as_str();
|
||||
string = string.trim_start_matches("\"");
|
||||
string = string.trim_start_matches('\"');
|
||||
|
||||
// Trim everything after the ending double quote `"`
|
||||
let parts: Vec<&str> = string.split("\"").collect();
|
||||
let parts: Vec<&str> = string.split('\"').collect();
|
||||
string = parts[0];
|
||||
|
||||
// Insert the parameter for each container `{}`
|
||||
|
@ -32,7 +32,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
mutable: bool,
|
||||
identifier: Identifier,
|
||||
mut value: ConstrainedValue<F, G>,
|
||||
) -> () {
|
||||
) {
|
||||
// Store with given mutability
|
||||
if mutable {
|
||||
value = ConstrainedValue::Mutable(Box::new(value));
|
||||
|
@ -50,7 +50,8 @@ impl ConsoleError {
|
||||
}
|
||||
|
||||
pub fn assertion_depends_on_input(span: Span) -> Self {
|
||||
let message = format!("console.assert() failed to evaluate. This error is caused by empty input file values");
|
||||
let message =
|
||||
"console.assert() failed to evaluate. This error is caused by empty input file values".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ impl ExpressionError {
|
||||
}
|
||||
|
||||
pub fn self_keyword(span: Span) -> Self {
|
||||
let message = format!("cannot call keyword `Self` outside of a circuit function");
|
||||
let message = "cannot call keyword `Self` outside of a circuit function".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ impl ImportError {
|
||||
}
|
||||
|
||||
pub fn convert_os_string(span: Span) -> Self {
|
||||
let message = format!("failed to convert file string name, maybe an illegal character?");
|
||||
let message = "failed to convert file string name, maybe an illegal character?".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ impl OutputBytesError {
|
||||
}
|
||||
|
||||
pub fn not_enough_registers(span: Span) -> Self {
|
||||
let message = format!("number of input registers must be greater than or equal to output registers");
|
||||
let message = "number of input registers must be greater than or equal to output registers".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
@ -67,13 +67,13 @@ impl StatementError {
|
||||
}
|
||||
|
||||
pub fn array_assign_index(span: Span) -> Self {
|
||||
let message = format!("Cannot assign single index to array of values");
|
||||
let message = "Cannot assign single index to array of values".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn array_assign_range(span: Span) -> Self {
|
||||
let message = format!("Cannot assign range of array values to single value");
|
||||
let message = "Cannot assign range of array values to single value".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
@ -145,7 +145,7 @@ impl StatementError {
|
||||
}
|
||||
|
||||
pub fn tuple_assign_index(span: Span) -> Self {
|
||||
let message = format!("Cannot assign single index to tuple of values");
|
||||
let message = "Cannot assign single index to tuple of values".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ impl AddressError {
|
||||
}
|
||||
|
||||
pub fn missing_address(span: Span) -> Self {
|
||||
let message = format!("expected address input not found");
|
||||
let message = "expected address input not found".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
@ -88,13 +88,13 @@ impl GroupError {
|
||||
}
|
||||
|
||||
pub fn x_recover(span: Span) -> Self {
|
||||
let message = format!("could not recover group element from x coordinate");
|
||||
let message = "could not recover group element from x coordinate".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn y_recover(span: Span) -> Self {
|
||||
let message = format!("could not recover group element from y coordinate");
|
||||
let message = "could not recover group element from y coordinate".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ impl IntegerError {
|
||||
}
|
||||
|
||||
pub fn negate_operation(span: Span) -> Self {
|
||||
let message = format!("integer negation can only be enforced on signed integers");
|
||||
let message = "integer negation can only be enforced on signed integers".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
@ -83,9 +83,9 @@ impl IntegerError {
|
||||
}
|
||||
|
||||
pub fn invalid_index(span: Span) -> Self {
|
||||
let message = format!(
|
||||
let message =
|
||||
"index must be a constant value unsigned integer. allocated indices produce a circuit of unknown size"
|
||||
);
|
||||
.to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ impl ValueError {
|
||||
}
|
||||
|
||||
pub fn implicit_group(span: Span) -> Self {
|
||||
let message = format!("group coordinates should be in (x, y)group format");
|
||||
let message = "group coordinates should be in (x, y)group format".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
@ -45,11 +45,9 @@ pub fn enforce_div<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
enforce_div(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(ExpressionError::incompatible_types(
|
||||
format!("{} / {}", val_1, val_2,),
|
||||
span,
|
||||
));
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
||||
format!("{} / {}", val_1, val_2,),
|
||||
span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
@ -45,11 +45,9 @@ pub fn enforce_mul<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
|
||||
enforce_mul(cs, val_1, val_2, span)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(ExpressionError::incompatible_types(
|
||||
format!("{} * {}", val_1, val_2),
|
||||
span,
|
||||
));
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::incompatible_types(
|
||||
format!("{} * {}", val_1, val_2),
|
||||
span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_array_access<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -56,9 +57,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
None => 0usize, // Array slice starts at index 0
|
||||
};
|
||||
let to_resolved = match to {
|
||||
Some(to_index) => {
|
||||
self.enforce_index(cs, file_scope.clone(), function_scope.clone(), to_index, span.clone())?
|
||||
}
|
||||
Some(to_index) => self.enforce_index(cs, file_scope, function_scope, to_index, span)?,
|
||||
None => array.len(), // Array slice ends at array length
|
||||
};
|
||||
Ok(ConstrainedValue::Array(array[from_resolved..to_resolved].to_owned()))
|
||||
|
@ -37,7 +37,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
mut expected_type: Option<Type>,
|
||||
array: Vec<Box<SpreadOrExpression>>,
|
||||
array: Vec<SpreadOrExpression>,
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
// Check explicit array type dimension if given
|
||||
@ -47,12 +47,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
match type_ {
|
||||
Type::Array(ref type_, ref dimensions) => {
|
||||
let number = match dimensions.first() {
|
||||
Some(number) => number.clone(),
|
||||
Some(number) => *number,
|
||||
None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)),
|
||||
};
|
||||
|
||||
expected_dimensions.push(number);
|
||||
expected_type = Some(type_.outer_dimension(dimensions).clone());
|
||||
expected_type = Some(type_.outer_dimension(dimensions));
|
||||
}
|
||||
ref type_ => {
|
||||
return Err(ExpressionError::unexpected_array(type_.to_string(), span));
|
||||
@ -62,7 +62,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
let mut result = vec![];
|
||||
for element in array.into_iter() {
|
||||
match *element {
|
||||
match element {
|
||||
SpreadOrExpression::Spread(spread) => match spread {
|
||||
Expression::Identifier(identifier) => {
|
||||
let array_name = new_scope(function_scope.clone(), identifier.to_string());
|
||||
@ -89,14 +89,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
}
|
||||
|
||||
// Check expected_dimensions if given
|
||||
if !expected_dimensions.is_empty() {
|
||||
if expected_dimensions[expected_dimensions.len() - 1] != result.len() {
|
||||
return Err(ExpressionError::invalid_length(
|
||||
expected_dimensions[expected_dimensions.len() - 1],
|
||||
result.len(),
|
||||
span,
|
||||
));
|
||||
}
|
||||
if !expected_dimensions.is_empty() && expected_dimensions[expected_dimensions.len() - 1] != result.len() {
|
||||
return Err(ExpressionError::invalid_length(
|
||||
expected_dimensions[expected_dimensions.len() - 1],
|
||||
result.len(),
|
||||
span,
|
||||
));
|
||||
}
|
||||
|
||||
Ok(ConstrainedValue::Array(result))
|
||||
|
@ -34,15 +34,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
span: Span,
|
||||
) -> Result<usize, ExpressionError> {
|
||||
let expected_type = Some(Type::IntegerType(IntegerType::U32));
|
||||
match self.enforce_operand(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
expected_type,
|
||||
index,
|
||||
span.clone(),
|
||||
)? {
|
||||
ConstrainedValue::Integer(number) => Ok(number.to_usize(span.clone())?),
|
||||
match self.enforce_operand(cs, file_scope, function_scope, expected_type, index, span.clone())? {
|
||||
ConstrainedValue::Integer(number) => Ok(number.to_usize(span)?),
|
||||
value => Err(ExpressionError::invalid_index(value.to_string(), span)),
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,10 @@ use snarkos_models::{
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
type ConstrainedValuePair<T, U> = (ConstrainedValue<T, U>, ConstrainedValue<T, U>);
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_binary_expression<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -34,7 +37,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
left: Expression,
|
||||
right: Expression,
|
||||
span: Span,
|
||||
) -> Result<(ConstrainedValue<F, G>, ConstrainedValue<F, G>), ExpressionError> {
|
||||
) -> Result<ConstrainedValuePair<F, G>, ExpressionError> {
|
||||
let mut resolved_left = self.enforce_operand(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
@ -45,8 +48,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
)?;
|
||||
let mut resolved_right = self.enforce_operand(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
file_scope,
|
||||
function_scope,
|
||||
expected_type.clone(),
|
||||
right,
|
||||
span.clone(),
|
||||
|
@ -29,9 +29,10 @@ use snarkos_models::{
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
static SELF_KEYWORD: &'static str = "self";
|
||||
static SELF_KEYWORD: &str = "self";
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_circuit_access<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -45,11 +46,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
// access a circuit member using the `self` keyword
|
||||
if let Expression::Identifier(ref identifier) = *circuit_identifier {
|
||||
if identifier.is_self() {
|
||||
let self_file_scope = new_scope(file_scope.clone(), identifier.name.to_string());
|
||||
let self_file_scope = new_scope(file_scope, identifier.name.to_string());
|
||||
let self_function_scope = new_scope(self_file_scope.clone(), identifier.name.to_string());
|
||||
|
||||
let member_value =
|
||||
self.evaluate_identifier(self_file_scope, self_function_scope, None, circuit_member.clone())?;
|
||||
self.evaluate_identifier(self_file_scope, self_function_scope, None, circuit_member)?;
|
||||
|
||||
return Ok(member_value);
|
||||
}
|
||||
@ -58,9 +59,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
let (circuit_name, members) = match self.enforce_operand(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
function_scope,
|
||||
expected_type,
|
||||
*circuit_identifier.clone(),
|
||||
*circuit_identifier,
|
||||
span.clone(),
|
||||
)? {
|
||||
ConstrainedValue::CircuitExpression(name, members) => (name, members),
|
||||
|
@ -40,7 +40,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
// Circuit definitions are located at the minimum file scope
|
||||
let scopes: Vec<&str> = file_scope.split("_").collect();
|
||||
let scopes: Vec<&str> = file_scope.split('_').collect();
|
||||
let mut program_identifier = new_scope(scopes[0].to_string(), identifier.to_string());
|
||||
|
||||
if identifier.is_self() {
|
||||
@ -53,9 +53,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
};
|
||||
|
||||
let circuit_identifier = circuit.circuit_name.clone();
|
||||
let mut resolved_members = vec![];
|
||||
let mut resolved_members = Vec::with_capacity(circuit.members.len());
|
||||
|
||||
for member in circuit.members.clone().into_iter() {
|
||||
for member in circuit.members.into_iter() {
|
||||
match member {
|
||||
CircuitMember::CircuitVariable(is_mutable, identifier, type_) => {
|
||||
let matched_variable = members
|
||||
@ -98,7 +98,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
}
|
||||
|
||||
Ok(ConstrainedValue::CircuitExpression(
|
||||
circuit_identifier.clone(),
|
||||
circuit_identifier,
|
||||
resolved_members,
|
||||
))
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_circuit_static_access<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -36,26 +37,20 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
// Get defined circuit
|
||||
let circuit = match *circuit_identifier.clone() {
|
||||
let circuit = match *circuit_identifier {
|
||||
Expression::Identifier(identifier) => {
|
||||
// Use the "Self" keyword to access a static circuit function
|
||||
if identifier.is_self() {
|
||||
let circuit = self
|
||||
.get(&file_scope)
|
||||
.ok_or(ExpressionError::self_keyword(identifier.span.clone()))?;
|
||||
.ok_or_else(|| ExpressionError::self_keyword(identifier.span))?;
|
||||
|
||||
circuit.to_owned()
|
||||
} else {
|
||||
self.evaluate_identifier(file_scope.clone(), function_scope.clone(), expected_type, identifier)?
|
||||
self.evaluate_identifier(file_scope, function_scope, expected_type, identifier)?
|
||||
}
|
||||
}
|
||||
expression => self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
expected_type,
|
||||
expression,
|
||||
)?,
|
||||
expression => self.enforce_expression(cs, file_scope, function_scope, expected_type, expression)?,
|
||||
}
|
||||
.extract_circuit(span.clone())?;
|
||||
|
||||
|
@ -26,6 +26,7 @@ use snarkos_models::{
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
/// Enforce ternary conditional expression
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_conditional_expression<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -57,14 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
span.clone(),
|
||||
)?;
|
||||
|
||||
let second_value = self.enforce_operand(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
expected_type,
|
||||
second,
|
||||
span.clone(),
|
||||
)?;
|
||||
let second_value = self.enforce_operand(cs, file_scope, function_scope, expected_type, second, span.clone())?;
|
||||
|
||||
let unique_namespace = cs.ns(|| {
|
||||
format!(
|
||||
@ -74,6 +68,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
});
|
||||
|
||||
ConstrainedValue::conditionally_select(unique_namespace, &conditional_value, &first_value, &second_value)
|
||||
.map_err(|e| ExpressionError::cannot_enforce(format!("conditional select"), e, span))
|
||||
.map_err(|e| ExpressionError::cannot_enforce("conditional select".to_string(), e, span))
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Expression::Address(address, span) => Ok(ConstrainedValue::Address(Address::constant(address, span)?)),
|
||||
Expression::Boolean(boolean, span) => Ok(ConstrainedValue::Boolean(new_bool_constant(boolean, span)?)),
|
||||
Expression::Field(field, span) => Ok(ConstrainedValue::Field(FieldType::constant(field, span)?)),
|
||||
Expression::Group(group_element) => Ok(ConstrainedValue::Group(G::constant(group_element)?)),
|
||||
Expression::Group(group_element) => Ok(ConstrainedValue::Group(G::constant(*group_element)?)),
|
||||
Expression::Implicit(value, span) => Ok(enforce_number_implicit(expected_type, value, span)?),
|
||||
Expression::Integer(type_, integer, span) => {
|
||||
Ok(ConstrainedValue::Integer(Integer::new_constant(&type_, integer, span)?))
|
||||
@ -70,8 +70,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Expression::Add(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
file_scope,
|
||||
function_scope,
|
||||
expected_type,
|
||||
*left,
|
||||
*right,
|
||||
@ -83,8 +83,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Expression::Sub(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
file_scope,
|
||||
function_scope,
|
||||
expected_type,
|
||||
*left,
|
||||
*right,
|
||||
@ -96,8 +96,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Expression::Mul(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
file_scope,
|
||||
function_scope,
|
||||
expected_type,
|
||||
*left,
|
||||
*right,
|
||||
@ -109,8 +109,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Expression::Div(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
file_scope,
|
||||
function_scope,
|
||||
expected_type,
|
||||
*left,
|
||||
*right,
|
||||
@ -122,8 +122,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Expression::Pow(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
file_scope,
|
||||
function_scope,
|
||||
expected_type,
|
||||
*left,
|
||||
*right,
|
||||
@ -141,8 +141,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Expression::Or(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
file_scope,
|
||||
function_scope,
|
||||
expected_type,
|
||||
*left,
|
||||
*right,
|
||||
@ -154,8 +154,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Expression::And(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
file_scope,
|
||||
function_scope,
|
||||
expected_type,
|
||||
*left,
|
||||
*right,
|
||||
@ -165,67 +165,32 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(enforce_and(cs, resolved_left, resolved_right, span)?)
|
||||
}
|
||||
Expression::Eq(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
None,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
let (resolved_left, resolved_right) =
|
||||
self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
|
||||
|
||||
Ok(evaluate_eq(cs, resolved_left, resolved_right, span)?)
|
||||
}
|
||||
Expression::Ge(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
None,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
let (resolved_left, resolved_right) =
|
||||
self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
|
||||
|
||||
Ok(evaluate_ge(cs, resolved_left, resolved_right, span)?)
|
||||
}
|
||||
Expression::Gt(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
None,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
let (resolved_left, resolved_right) =
|
||||
self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
|
||||
|
||||
Ok(evaluate_gt(cs, resolved_left, resolved_right, span)?)
|
||||
}
|
||||
Expression::Le(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
None,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
let (resolved_left, resolved_right) =
|
||||
self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
|
||||
|
||||
Ok(evaluate_le(cs, resolved_left, resolved_right, span)?)
|
||||
}
|
||||
Expression::Lt(left, right, span) => {
|
||||
let (resolved_left, resolved_right) = self.enforce_binary_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
None,
|
||||
*left,
|
||||
*right,
|
||||
span.clone(),
|
||||
)?;
|
||||
let (resolved_left, resolved_right) =
|
||||
self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
|
||||
|
||||
Ok(evaluate_lt(cs, resolved_left, resolved_right, span)?)
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ use snarkos_models::{
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
/// Call a default core circuit function with arguments
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_core_circuit_call_expression<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -36,7 +37,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
// Get the value of each core function argument
|
||||
let mut argument_values = vec![];
|
||||
let mut argument_values = Vec::with_capacity(arguments.len());
|
||||
for argument in arguments.into_iter() {
|
||||
let argument_value =
|
||||
self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), None, argument)?;
|
||||
@ -49,10 +50,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
let res = call_core_circuit(cs, core_circuit, argument_values, span.clone())?;
|
||||
|
||||
// Convert the core function returns into constrained values
|
||||
let returns = res
|
||||
.into_iter()
|
||||
.map(|value| ConstrainedValue::from(value))
|
||||
.collect::<Vec<_>>();
|
||||
let returns = res.into_iter().map(ConstrainedValue::from).collect::<Vec<_>>();
|
||||
|
||||
let return_value = if returns.len() == 1 {
|
||||
// The function has a single return
|
||||
@ -72,6 +70,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(return_value);
|
||||
Ok(return_value)
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_function_call_expression<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -35,7 +36,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
arguments: Vec<Expression>,
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let (declared_circuit_reference, function_value) = match *function.clone() {
|
||||
let (declared_circuit_reference, function_value) = match *function {
|
||||
Expression::CircuitMemberAccess(circuit_identifier, circuit_member, span) => {
|
||||
// Call a circuit function that can mutate self.
|
||||
|
||||
@ -62,7 +63,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
),
|
||||
};
|
||||
|
||||
let (outer_scope, function_call) = function_value.extract_function(file_scope.clone(), span.clone())?;
|
||||
let (outer_scope, function_call) = function_value.extract_function(file_scope, span.clone())?;
|
||||
|
||||
let name_unique = format!(
|
||||
"function call {} {}:{}",
|
||||
|
@ -37,7 +37,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
unresolved_identifier: Identifier,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
// Evaluate the identifier name in the current function scope
|
||||
let variable_name = new_scope(function_scope.clone(), unresolved_identifier.to_string());
|
||||
let variable_name = new_scope(function_scope, unresolved_identifier.to_string());
|
||||
let identifier_name = new_scope(file_scope, unresolved_identifier.to_string());
|
||||
|
||||
let mut result_value = if let Some(value) = self.get(&variable_name) {
|
||||
@ -58,7 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
return Err(ExpressionError::undefined_identifier(unresolved_identifier));
|
||||
};
|
||||
|
||||
result_value.resolve_type(expected_type, unresolved_identifier.span.clone())?;
|
||||
result_value.resolve_type(expected_type, unresolved_identifier.span)?;
|
||||
|
||||
Ok(result_value)
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ pub fn enforce_and<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) {
|
||||
let name_unique = format!("{} {}:{}", name, span.line, span.start);
|
||||
let result = Boolean::and(cs.ns(|| name_unique), &left_bool, &right_bool)
|
||||
.map_err(|e| BooleanError::cannot_enforce(format!("&&"), e, span))?;
|
||||
.map_err(|e| BooleanError::cannot_enforce("&&".to_string(), e, span))?;
|
||||
|
||||
return Ok(ConstrainedValue::Boolean(result));
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ pub fn enforce_or<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F
|
||||
if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) {
|
||||
let name_unique = format!("{} {}:{}", name, span.line, span.start);
|
||||
let result = Boolean::or(cs.ns(|| name_unique), &left_bool, &right_bool)
|
||||
.map_err(|e| BooleanError::cannot_enforce(format!("||"), e, span))?;
|
||||
.map_err(|e| BooleanError::cannot_enforce("||".to_string(), e, span))?;
|
||||
|
||||
return Ok(ConstrainedValue::Boolean(result));
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ pub fn evaluate_eq<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
}
|
||||
};
|
||||
|
||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(format!("=="), span))?;
|
||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("==".to_string(), span))?;
|
||||
|
||||
Ok(ConstrainedValue::Boolean(boolean))
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ pub fn evaluate_ge<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
}
|
||||
};
|
||||
|
||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(format!(">="), span))?;
|
||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(">=".to_string(), span))?;
|
||||
|
||||
Ok(ConstrainedValue::Boolean(boolean))
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ pub fn evaluate_gt<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
}
|
||||
};
|
||||
|
||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(format!(">"), span))?;
|
||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(">".to_string(), span))?;
|
||||
|
||||
Ok(ConstrainedValue::Boolean(boolean))
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ pub fn evaluate_le<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
}
|
||||
};
|
||||
|
||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(format!("<="), span))?;
|
||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("<=".to_string(), span))?;
|
||||
|
||||
Ok(ConstrainedValue::Boolean(boolean))
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ pub fn evaluate_lt<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
}
|
||||
};
|
||||
|
||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate(format!("<"), span))?;
|
||||
let boolean = constraint_result.map_err(|_| ExpressionError::cannot_evaluate("<".to_string(), span))?;
|
||||
|
||||
Ok(ConstrainedValue::Boolean(boolean))
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_tuple_access<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -35,16 +36,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
index: usize,
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let tuple = match self.enforce_operand(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
expected_type,
|
||||
*tuple,
|
||||
span.clone(),
|
||||
)? {
|
||||
let tuple = match self.enforce_operand(cs, file_scope, function_scope, expected_type, *tuple, span.clone())? {
|
||||
ConstrainedValue::Tuple(tuple) => tuple,
|
||||
value => return Err(ExpressionError::undefined_array(value.to_string(), span.clone())),
|
||||
value => return Err(ExpressionError::undefined_array(value.to_string(), span)),
|
||||
};
|
||||
|
||||
if index > tuple.len() - 1 {
|
||||
|
@ -38,22 +38,21 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
// Check explicit tuple type dimension if given
|
||||
let mut expected_types = vec![];
|
||||
|
||||
if expected_type.is_some() {
|
||||
match expected_type.unwrap() {
|
||||
Type::Tuple(ref types) => {
|
||||
expected_types = types.clone();
|
||||
}
|
||||
ref type_ => {
|
||||
return Err(ExpressionError::unexpected_tuple(
|
||||
type_.to_string(),
|
||||
format!("{:?}", tuple),
|
||||
span,
|
||||
));
|
||||
}
|
||||
match expected_type {
|
||||
Some(Type::Tuple(ref types)) => {
|
||||
expected_types = types.clone();
|
||||
}
|
||||
Some(ref type_) => {
|
||||
return Err(ExpressionError::unexpected_tuple(
|
||||
type_.to_string(),
|
||||
format!("{:?}", tuple),
|
||||
span,
|
||||
));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
let mut result = vec![];
|
||||
let mut result = Vec::with_capacity(tuple.len());
|
||||
for (i, expression) in tuple.into_iter().enumerate() {
|
||||
let type_ = if expected_types.is_empty() {
|
||||
None
|
||||
|
@ -55,7 +55,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
check_arguments_length(function.input.len(), input.len(), function.span.clone())?;
|
||||
|
||||
// Store input values as new variables in resolved program
|
||||
for (input_model, input_expression) in function.input.clone().iter().zip(input.into_iter()) {
|
||||
for (input_model, input_expression) in function.input.iter().zip(input.into_iter()) {
|
||||
let (name, value) = match input_model {
|
||||
InputVariable::InputKeyword(identifier) => {
|
||||
let input_value = self.enforce_function_input(
|
||||
|
@ -62,14 +62,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
// Allocate each input variable as a circuit expression
|
||||
|
||||
let mut sections = vec![];
|
||||
let mut sections = Vec::with_capacity(4);
|
||||
|
||||
sections.push((registers_name, registers_values));
|
||||
sections.push((record_name, record_values));
|
||||
sections.push((state_name, state_values));
|
||||
sections.push((state_leaf_name, state_leaf_values));
|
||||
|
||||
let mut members = vec![];
|
||||
let mut members = Vec::with_capacity(sections.len());
|
||||
|
||||
for (name, values) in sections {
|
||||
let member_name = name.clone();
|
||||
|
@ -30,7 +30,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
identifier: Identifier,
|
||||
section: HashMap<Parameter, Option<InputValue>>,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let mut members = vec![];
|
||||
let mut members = Vec::with_capacity(section.len());
|
||||
|
||||
// Allocate each section definition as a circuit member value
|
||||
|
||||
|
@ -42,7 +42,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
let registers = input.get_registers();
|
||||
|
||||
// Iterate over main function input variables and allocate new values
|
||||
let mut input_variables = vec![];
|
||||
let mut input_variables = Vec::with_capacity(function.input.len());
|
||||
for input_model in function.input.clone().into_iter() {
|
||||
let (identifier, value) = match input_model {
|
||||
InputVariable::InputKeyword(identifier) => {
|
||||
@ -54,7 +54,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
let name = input_model.identifier.name.clone();
|
||||
let input_option = input
|
||||
.get(&name)
|
||||
.ok_or(FunctionError::input_not_found(name.clone(), function.span.clone()))?;
|
||||
.ok_or_else(|| FunctionError::input_not_found(name.clone(), function.span.clone()))?;
|
||||
let input_value = self.allocate_main_function_input(
|
||||
cs,
|
||||
input_model.type_,
|
||||
|
@ -37,14 +37,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
span: Span,
|
||||
) -> Result<(), StatementError> {
|
||||
// if there are no results, continue
|
||||
if results.len() == 0 {
|
||||
if results.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// If all indicators are none, then there are no branch conditions in the function.
|
||||
// We simply return the last result.
|
||||
|
||||
if let None = results.iter().find(|(indicator, _res)| indicator.is_some()) {
|
||||
if results.iter().all(|(indicator, _res)| indicator.is_none()) {
|
||||
let result = &results[results.len() - 1].1;
|
||||
|
||||
*return_value = result.clone();
|
||||
|
@ -21,7 +21,7 @@ use std::{collections::HashMap, env::current_dir};
|
||||
|
||||
/// Parses all relevant import files for a program.
|
||||
/// Stores compiled program structs.
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ImportParser {
|
||||
imports: HashMap<String, Program>,
|
||||
core_packages: Vec<Package>,
|
||||
@ -29,10 +29,7 @@ pub struct ImportParser {
|
||||
|
||||
impl ImportParser {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
imports: HashMap::new(),
|
||||
core_packages: vec![],
|
||||
}
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub(crate) fn insert_import(&mut self, file_name: String, program: Program) {
|
||||
@ -44,7 +41,7 @@ impl ImportParser {
|
||||
let _res = self.core_packages.push(package.clone());
|
||||
}
|
||||
|
||||
pub fn get_import(&self, file_name: &String) -> Option<&Program> {
|
||||
pub fn get_import(&self, file_name: &str) -> Option<&Program> {
|
||||
self.imports.get(file_name)
|
||||
}
|
||||
|
||||
@ -56,7 +53,7 @@ impl ImportParser {
|
||||
let mut imports = Self::new();
|
||||
|
||||
// Find all imports relative to current directory
|
||||
let path = current_dir().map_err(|error| ImportError::current_directory_error(error))?;
|
||||
let path = current_dir().map_err(ImportError::current_directory_error)?;
|
||||
|
||||
// Parse each imported file
|
||||
program
|
||||
|
@ -70,14 +70,12 @@ impl ImportParser {
|
||||
|
||||
let entries = fs::read_dir(path)
|
||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<_>, std::io::Error>>()
|
||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?;
|
||||
|
||||
let matched_source_entry = entries.into_iter().find(|entry| {
|
||||
entry
|
||||
.file_name()
|
||||
.to_os_string()
|
||||
.into_string()
|
||||
.unwrap()
|
||||
.trim_end_matches(SOURCE_FILE_EXTENSION)
|
||||
@ -90,7 +88,6 @@ impl ImportParser {
|
||||
} else if imports_directory.exists() {
|
||||
let entries = fs::read_dir(imports_directory)
|
||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<_>, std::io::Error>>()
|
||||
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?;
|
||||
|
||||
|
@ -30,11 +30,10 @@ fn parse_import_file(entry: &DirEntry, span: &Span) -> Result<Program, ImportErr
|
||||
.map_err(|error| ImportError::directory_error(error, span.clone(), entry.path()))?;
|
||||
let file_name = entry
|
||||
.file_name()
|
||||
.to_os_string()
|
||||
.into_string()
|
||||
.map_err(|_| ImportError::convert_os_string(span.clone()))?;
|
||||
|
||||
let mut file_path = entry.path().to_path_buf();
|
||||
let mut file_path = entry.path();
|
||||
if file_type.is_dir() {
|
||||
file_path.push(LIBRARY_FILE);
|
||||
|
||||
@ -62,7 +61,7 @@ impl ImportParser {
|
||||
.extension()
|
||||
.map_or(false, |ext| ext.eq(&OsString::from(FILE_EXTENSION)));
|
||||
|
||||
let mut package_path = path.to_path_buf();
|
||||
let mut package_path = path;
|
||||
package_path.push(LIBRARY_FILE);
|
||||
|
||||
let is_package = is_dir && package_path.exists();
|
||||
@ -93,7 +92,7 @@ impl ImportParser {
|
||||
Ok(())
|
||||
} else {
|
||||
// importing * from a directory or non-leo file in `package/src/` is illegal
|
||||
Err(ImportError::star(entry.path().to_path_buf(), span.clone()))
|
||||
Err(ImportError::star(entry.path(), span.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
.find(|package| import.package.eq(package));
|
||||
|
||||
if let Some(package) = core_dependency {
|
||||
self.store_core_package(scope.clone(), package.clone())?;
|
||||
self.store_core_package(scope, package.clone())?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
@ -45,7 +45,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
// Find imported program
|
||||
let program = imported_programs
|
||||
.get_import(&package)
|
||||
.ok_or(ImportError::unknown_package(import.package.name.clone()))?;
|
||||
.ok_or_else(|| ImportError::unknown_package(import.package.name.clone()))?;
|
||||
|
||||
// Parse imported program
|
||||
self.store_definitions(program.clone(), imported_programs)?;
|
||||
|
@ -59,7 +59,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
let value = match matched_circuit {
|
||||
Some((_circuit_name, circuit)) => ConstrainedValue::Import(
|
||||
program_name.clone(),
|
||||
program_name,
|
||||
Box::new(ConstrainedValue::CircuitDefinition(circuit.clone())),
|
||||
),
|
||||
None => {
|
||||
@ -71,7 +71,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
match matched_function {
|
||||
Some((_function_name, function)) => ConstrainedValue::Import(
|
||||
program_name.clone(),
|
||||
program_name,
|
||||
Box::new(ConstrainedValue::Function(None, function.clone())),
|
||||
),
|
||||
None => return Err(ImportError::unknown_symbol(symbol.to_owned(), program_name)),
|
||||
@ -80,7 +80,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
};
|
||||
|
||||
// take the alias if it is present
|
||||
let id = symbol.alias.clone().unwrap_or(symbol.symbol.clone());
|
||||
let id = symbol.alias.clone().unwrap_or_else(|| symbol.symbol.clone());
|
||||
let name = new_scope(scope, id.to_string());
|
||||
|
||||
// store imported circuit under imported name
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
//! Module containing structs and types that make up a Leo program.
|
||||
|
||||
#![allow(clippy::module_inception)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate thiserror;
|
||||
|
||||
|
@ -71,8 +71,7 @@ impl OutputBytes {
|
||||
string.push_str(&format);
|
||||
}
|
||||
|
||||
let mut bytes: Vec<u8> = vec![];
|
||||
bytes.extend_from_slice(string.as_bytes());
|
||||
let bytes = string.into_bytes();
|
||||
|
||||
Ok(Self(bytes))
|
||||
}
|
||||
|
@ -27,30 +27,36 @@ pub struct ConstrainedProgram<F: Field + PrimeField, G: GroupType<F>> {
|
||||
pub identifiers: HashMap<String, ConstrainedValue<F, G>>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> Default for ConstrainedProgram<F, G> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
identifiers: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_scope(outer: String, inner: String) -> String {
|
||||
format!("{}_{}", outer, inner)
|
||||
}
|
||||
|
||||
pub fn is_in_scope(current_scope: &String, desired_scope: &String) -> bool {
|
||||
pub fn is_in_scope(current_scope: &str, desired_scope: &str) -> bool {
|
||||
current_scope.ends_with(desired_scope)
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
identifiers: HashMap::new(),
|
||||
}
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub(crate) fn store(&mut self, name: String, value: ConstrainedValue<F, G>) {
|
||||
self.identifiers.insert(name, value);
|
||||
}
|
||||
|
||||
pub(crate) fn get(&self, name: &String) -> Option<&ConstrainedValue<F, G>> {
|
||||
pub(crate) fn get(&self, name: &str) -> Option<&ConstrainedValue<F, G>> {
|
||||
self.identifiers.get(name)
|
||||
}
|
||||
|
||||
pub(crate) fn get_mut(&mut self, name: &String) -> Option<&mut ConstrainedValue<F, G>> {
|
||||
pub(crate) fn get_mut(&mut self, name: &str) -> Option<&mut ConstrainedValue<F, G>> {
|
||||
self.identifiers.get_mut(name)
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn assign_array<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -44,7 +45,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
// Resolve index so we know if we are assigning to a single value or a range of values
|
||||
match range_or_expression {
|
||||
RangeOrExpression::Expression(index) => {
|
||||
let index = self.enforce_index(cs, file_scope.clone(), function_scope.clone(), index, span.clone())?;
|
||||
let index = self.enforce_index(cs, file_scope, function_scope, index, span.clone())?;
|
||||
|
||||
// Modify the single value of the array in place
|
||||
match self.get_mutable_assignee(name, span.clone())? {
|
||||
@ -75,13 +76,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
None => 0usize,
|
||||
};
|
||||
let to_index_option = match to {
|
||||
Some(integer) => Some(self.enforce_index(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
integer,
|
||||
span.clone(),
|
||||
)?),
|
||||
Some(integer) => Some(self.enforce_index(cs, file_scope, function_scope, integer, span.clone())?),
|
||||
None => None,
|
||||
};
|
||||
|
||||
|
@ -35,6 +35,7 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_assign_statement<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -57,7 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
match assignee {
|
||||
Assignee::Identifier(_identifier) => {
|
||||
let condition = indicator.unwrap_or(Boolean::Constant(true));
|
||||
let old_value = self.get_mutable_assignee(variable_name.clone(), span.clone())?;
|
||||
let old_value = self.get_mutable_assignee(variable_name, span.clone())?;
|
||||
|
||||
new_value.resolve_type(Some(old_value.to_type(span.clone())?), span.clone())?;
|
||||
|
||||
@ -76,7 +77,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
function_scope,
|
||||
indicator,
|
||||
variable_name,
|
||||
range_or_expression,
|
||||
*range_or_expression,
|
||||
new_value,
|
||||
span,
|
||||
),
|
||||
|
@ -43,7 +43,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
match self.get_mutable_assignee(circuit_name, span.clone())? {
|
||||
ConstrainedValue::CircuitExpression(_variable, members) => {
|
||||
// Modify the circuit variable in place
|
||||
let matched_variable = members.into_iter().find(|member| member.0 == variable_name);
|
||||
let matched_variable = members.iter_mut().find(|member| member.0 == variable_name);
|
||||
|
||||
match matched_variable {
|
||||
Some(member) => match &member.1 {
|
||||
@ -81,7 +81,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
member.1 = selected_value.to_owned();
|
||||
|
||||
Ok(selected_value.to_owned())
|
||||
Ok(selected_value)
|
||||
}
|
||||
_ => {
|
||||
// Throw an error if we try to mutate an immutable circuit variable
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
//! Enforces a branch of a conditional or iteration statement in a compiled Leo program.
|
||||
|
||||
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use crate::{program::ConstrainedProgram, GroupType, IndicatorAndConstrainedValue, StatementResult};
|
||||
use leo_typed::{Statement, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
@ -33,16 +33,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
indicator: Option<Boolean>,
|
||||
statements: Vec<Statement>,
|
||||
return_type: Option<Type>,
|
||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
||||
let mut results = vec![];
|
||||
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||
let mut results = Vec::with_capacity(statements.len());
|
||||
// Evaluate statements. Only allow a single return argument to be returned.
|
||||
for statement in statements.iter() {
|
||||
for statement in statements.into_iter() {
|
||||
let mut value = self.enforce_statement(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
indicator.clone(),
|
||||
statement.clone(),
|
||||
indicator,
|
||||
statement,
|
||||
return_type.clone(),
|
||||
"".to_owned(),
|
||||
)?;
|
||||
|
@ -16,7 +16,14 @@
|
||||
|
||||
//! Methods to enforce constraints on statements in a compiled Leo program.
|
||||
|
||||
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use crate::{
|
||||
errors::StatementError,
|
||||
program::ConstrainedProgram,
|
||||
value::ConstrainedValue,
|
||||
GroupType,
|
||||
IndicatorAndConstrainedValue,
|
||||
StatementResult,
|
||||
};
|
||||
use leo_typed::{ConditionalNestedOrEndStatement, ConditionalStatement, Span, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
@ -28,7 +35,7 @@ fn indicator_to_string(indicator: &Boolean) -> String {
|
||||
indicator
|
||||
.get_value()
|
||||
.map(|b| b.to_string())
|
||||
.unwrap_or(format!("[input]"))
|
||||
.unwrap_or_else(|| "[input]".to_string())
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
@ -36,6 +43,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
/// Due to R1CS constraints, we must evaluate every branch to properly construct the circuit.
|
||||
/// At program execution, we will pass an `indicator` bit down to all child statements within each branch.
|
||||
/// The `indicator` bit will select that branch while keeping the constraint system satisfied.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_conditional_statement<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -45,7 +53,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
statement: ConditionalStatement,
|
||||
return_type: Option<Type>,
|
||||
span: Span,
|
||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
||||
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||
let statement_string = statement.to_string();
|
||||
|
||||
// Inherit the indicator from a previous conditional statement or assume that we are the outer parent
|
||||
|
@ -56,20 +56,20 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
) -> Result<Vec<ConstrainedValue<F, G>>, StatementError> {
|
||||
let types = match type_ {
|
||||
Some(Type::Tuple(types)) => types,
|
||||
Some(type_) => return Err(StatementError::tuple_type(type_.to_string(), span.clone())),
|
||||
Some(type_) => return Err(StatementError::tuple_type(type_.to_string(), span)),
|
||||
None => vec![],
|
||||
};
|
||||
|
||||
let implicit_types = types.is_empty();
|
||||
let mut expected_types = vec![];
|
||||
let mut expected_types = Vec::with_capacity(expressions.len());
|
||||
|
||||
for i in 0..expressions.len() {
|
||||
let expected_type = if implicit_types { None } else { Some(types[i].clone()) };
|
||||
for ty in types.iter().take(expressions.len()) {
|
||||
let expected_type = if implicit_types { None } else { Some(ty.clone()) };
|
||||
|
||||
expected_types.push(expected_type);
|
||||
}
|
||||
|
||||
let mut values = vec![];
|
||||
let mut values = Vec::with_capacity(expressions.len());
|
||||
|
||||
for (expression, expected_type) in expressions.into_iter().zip(expected_types.into_iter()) {
|
||||
let value = self.enforce_expression(
|
||||
@ -86,6 +86,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(values)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn enforce_tuple_definition<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -135,6 +136,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_definition_statement<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -157,7 +159,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
let variable = variables.names[0].clone();
|
||||
let expression = self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
file_scope,
|
||||
function_scope.clone(),
|
||||
variables.type_,
|
||||
expressions[0].clone(),
|
||||
@ -181,14 +183,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
let values = match self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
file_scope,
|
||||
function_scope.clone(),
|
||||
variables.type_.clone(),
|
||||
expressions[0].clone(),
|
||||
)? {
|
||||
// ConstrainedValue::Return(values) => values,
|
||||
ConstrainedValue::Tuple(values) => values,
|
||||
value => return Err(StatementError::multiple_definition(value.to_string(), span.clone())),
|
||||
value => return Err(StatementError::multiple_definition(value.to_string(), span)),
|
||||
};
|
||||
|
||||
self.enforce_multiple_definition(cs, function_scope, is_constant, variables, values, span)
|
||||
|
@ -17,12 +17,13 @@
|
||||
//! Enforces an iteration statement in a compiled Leo program.
|
||||
|
||||
use crate::{
|
||||
errors::StatementError,
|
||||
new_scope,
|
||||
program::ConstrainedProgram,
|
||||
value::ConstrainedValue,
|
||||
GroupType,
|
||||
IndicatorAndConstrainedValue,
|
||||
Integer,
|
||||
StatementResult,
|
||||
};
|
||||
use leo_typed::{Expression, Identifier, Span, Statement, Type};
|
||||
|
||||
@ -35,6 +36,7 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_iteration_statement<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -47,7 +49,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
statements: Vec<Statement>,
|
||||
return_type: Option<Type>,
|
||||
span: Span,
|
||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
||||
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||
let mut results = vec![];
|
||||
|
||||
let from = self.enforce_index(cs, file_scope.clone(), function_scope.clone(), start, span.clone())?;
|
||||
|
@ -28,9 +28,7 @@ fn check_return_type(expected: Option<Type>, actual: Type, span: Span) -> Result
|
||||
match expected {
|
||||
Some(expected) => {
|
||||
if expected.ne(&actual) {
|
||||
if expected.is_self() && actual.is_circuit() {
|
||||
return Ok(());
|
||||
} else if expected.match_array_types(&actual) {
|
||||
if (expected.is_self() && actual.is_circuit()) || expected.match_array_types(&actual) {
|
||||
return Ok(());
|
||||
} else {
|
||||
return Err(StatementError::arguments_type(&expected, &actual, span));
|
||||
@ -56,8 +54,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
let result = self.enforce_operand(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
file_scope,
|
||||
function_scope,
|
||||
return_type.clone(),
|
||||
expression,
|
||||
span.clone(),
|
||||
|
@ -24,12 +24,16 @@ use snarkos_models::{
|
||||
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean},
|
||||
};
|
||||
|
||||
pub type StatementResult<T> = Result<T, StatementError>;
|
||||
pub type IndicatorAndConstrainedValue<T, U> = (Option<Boolean>, ConstrainedValue<T, U>);
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
/// Enforce a program statement.
|
||||
/// Returns a Vector of (indicator, value) tuples.
|
||||
/// Each evaluated statement may execute of one or more statements that may return early.
|
||||
/// To indicate which of these return values to take we conditionally select the value according
|
||||
/// to the `indicator` bit that evaluates to true.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_statement<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -39,7 +43,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
statement: Statement,
|
||||
return_type: Option<Type>,
|
||||
declared_circuit_reference: String,
|
||||
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
|
||||
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
|
||||
let mut results = vec![];
|
||||
|
||||
match statement {
|
||||
@ -70,7 +74,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
declared_circuit_reference,
|
||||
indicator,
|
||||
variable,
|
||||
expression,
|
||||
*expression,
|
||||
span,
|
||||
)?;
|
||||
}
|
||||
@ -94,8 +98,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
function_scope,
|
||||
indicator,
|
||||
index,
|
||||
start,
|
||||
stop,
|
||||
*start,
|
||||
*stop,
|
||||
statements,
|
||||
return_type,
|
||||
span,
|
||||
|
@ -153,7 +153,7 @@ impl<F: Field + PrimeField> AllocGadget<String, F> for Address {
|
||||
impl<F: Field + PrimeField> EvaluateEqGadget<F> for Address {
|
||||
fn evaluate_equal<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
||||
if self.is_constant() && other.is_constant() {
|
||||
return Ok(Boolean::Constant(self.eq(other)));
|
||||
Ok(Boolean::Constant(self.eq(other)))
|
||||
} else {
|
||||
let mut result = Boolean::constant(true);
|
||||
|
||||
|
@ -79,7 +79,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
||||
let result = self_value
|
||||
.add(cs, other_value)
|
||||
.map_err(|e| FieldError::binary_operation(format!("+"), e, span))?;
|
||||
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?;
|
||||
|
||||
Ok(FieldType::Allocated(result))
|
||||
}
|
||||
@ -88,7 +88,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
||||
allocated_value
|
||||
.add_constant(cs, constant_value)
|
||||
.map_err(|e| FieldError::binary_operation(format!("+"), e, span))?,
|
||||
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
@ -102,7 +102,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
||||
let result = self_value
|
||||
.sub(cs, other_value)
|
||||
.map_err(|e| FieldError::binary_operation(format!("-"), e, span))?;
|
||||
.map_err(|e| FieldError::binary_operation("-".to_string(), e, span))?;
|
||||
|
||||
Ok(FieldType::Allocated(result))
|
||||
}
|
||||
@ -111,7 +111,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
||||
allocated_value
|
||||
.sub_constant(cs, constant_value)
|
||||
.map_err(|e| FieldError::binary_operation(format!("+"), e, span))?,
|
||||
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
@ -125,7 +125,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
|
||||
let result = self_value
|
||||
.mul(cs, other_value)
|
||||
.map_err(|e| FieldError::binary_operation(format!("*"), e, span))?;
|
||||
.map_err(|e| FieldError::binary_operation("*".to_string(), e, span))?;
|
||||
|
||||
Ok(FieldType::Allocated(result))
|
||||
}
|
||||
@ -134,7 +134,7 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
||||
allocated_value
|
||||
.mul_by_constant(cs, constant_value)
|
||||
.map_err(|e| FieldError::binary_operation(format!("*"), e, span))?,
|
||||
.map_err(|e| FieldError::binary_operation("*".to_string(), e, span))?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
@ -144,14 +144,14 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
FieldType::Constant(constant) => {
|
||||
let constant_inverse = constant
|
||||
.inverse()
|
||||
.ok_or(FieldError::no_inverse(constant.to_string(), span.clone()))?;
|
||||
.ok_or_else(|| FieldError::no_inverse(constant.to_string(), span.clone()))?;
|
||||
|
||||
FieldType::Constant(constant_inverse)
|
||||
}
|
||||
FieldType::Allocated(allocated) => {
|
||||
let allocated_inverse = allocated
|
||||
.inverse(&mut cs)
|
||||
.map_err(|e| FieldError::binary_operation(format!("+"), e, span.clone()))?;
|
||||
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span.clone()))?;
|
||||
|
||||
FieldType::Allocated(allocated_inverse)
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ use std::{
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum EdwardsGroupType {
|
||||
Constant(EdwardsAffine),
|
||||
Allocated(EdwardsBlsGadget),
|
||||
Allocated(Box<EdwardsBlsGadget>),
|
||||
}
|
||||
|
||||
impl GroupType<Fq> for EdwardsGroupType {
|
||||
@ -60,7 +60,7 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
|
||||
fn to_allocated<CS: ConstraintSystem<Fq>>(&self, mut cs: CS, span: Span) -> Result<Self, GroupError> {
|
||||
self.allocated(cs.ns(|| format!("allocate affine point {}:{}", span.line, span.start)))
|
||||
.map(|result| EdwardsGroupType::Allocated(result))
|
||||
.map(|ebg| EdwardsGroupType::Allocated(Box::new(ebg)))
|
||||
.map_err(|error| GroupError::synthesis_error(error, span))
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
let result = <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::negate(group, cs)
|
||||
.map_err(|e| GroupError::negate_operation(e, span))?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(result))
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(result)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,18 +88,18 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
cs,
|
||||
other_value,
|
||||
)
|
||||
.map_err(|e| GroupError::binary_operation(format!("+"), e, span))?;
|
||||
.map_err(|e| GroupError::binary_operation("+".to_string(), e, span))?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(result))
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(result)))
|
||||
}
|
||||
|
||||
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
|
||||
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
|
||||
Ok(EdwardsGroupType::Allocated(
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(
|
||||
allocated_value
|
||||
.add_constant(cs, constant_value)
|
||||
.map_err(|e| GroupError::binary_operation(format!("+"), e, span))?,
|
||||
))
|
||||
.map_err(|e| GroupError::binary_operation("+".to_string(), e, span))?,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,18 +116,18 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
cs,
|
||||
other_value,
|
||||
)
|
||||
.map_err(|e| GroupError::binary_operation(format!("-"), e, span))?;
|
||||
.map_err(|e| GroupError::binary_operation("-".to_string(), e, span))?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(result))
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(result)))
|
||||
}
|
||||
|
||||
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
|
||||
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
|
||||
Ok(EdwardsGroupType::Allocated(
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(
|
||||
allocated_value
|
||||
.sub_constant(cs, constant_value)
|
||||
.map_err(|e| GroupError::binary_operation(format!("-"), e, span))?,
|
||||
))
|
||||
.map_err(|e| GroupError::binary_operation("-".to_string(), e, span))?,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -143,13 +143,13 @@ impl EdwardsGroupType {
|
||||
|
||||
pub fn edwards_affine_from_single(number: String, span: Span) -> Result<EdwardsAffine, GroupError> {
|
||||
if number.eq("0") {
|
||||
return Ok(EdwardsAffine::zero());
|
||||
Ok(EdwardsAffine::zero())
|
||||
} else {
|
||||
let one = edwards_affine_one();
|
||||
let number_value = Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span))?;
|
||||
let result: EdwardsAffine = one.mul(&number_value);
|
||||
|
||||
return Ok(result);
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,11 +201,13 @@ impl EdwardsGroupType {
|
||||
let x = Fq::from_str(&x_string).map_err(|_| GroupError::x_invalid(x_string, x_span))?;
|
||||
match greatest {
|
||||
// Sign provided
|
||||
Some(greatest) => EdwardsAffine::from_x_coordinate(x, greatest).ok_or(GroupError::x_recover(element_span)),
|
||||
Some(greatest) => {
|
||||
EdwardsAffine::from_x_coordinate(x, greatest).ok_or_else(|| GroupError::x_recover(element_span))
|
||||
}
|
||||
// Sign inferred
|
||||
None => {
|
||||
// Attempt to recover with a sign_low bit.
|
||||
if let Some(element) = EdwardsAffine::from_x_coordinate(x.clone(), false) {
|
||||
if let Some(element) = EdwardsAffine::from_x_coordinate(x, false) {
|
||||
return Ok(element);
|
||||
}
|
||||
|
||||
@ -230,11 +232,13 @@ impl EdwardsGroupType {
|
||||
|
||||
match greatest {
|
||||
// Sign provided
|
||||
Some(greatest) => EdwardsAffine::from_y_coordinate(y, greatest).ok_or(GroupError::y_recover(element_span)),
|
||||
Some(greatest) => {
|
||||
EdwardsAffine::from_y_coordinate(y, greatest).ok_or_else(|| GroupError::y_recover(element_span))
|
||||
}
|
||||
// Sign inferred
|
||||
None => {
|
||||
// Attempt to recover with a sign_low bit.
|
||||
if let Some(element) = EdwardsAffine::from_y_coordinate(y.clone(), false) {
|
||||
if let Some(element) = EdwardsAffine::from_y_coordinate(y, false) {
|
||||
return Ok(element);
|
||||
}
|
||||
|
||||
@ -294,12 +298,8 @@ impl EdwardsGroupType {
|
||||
let x_value = allocated.x.get_value();
|
||||
let y_value = allocated.y.get_value();
|
||||
|
||||
let x_allocated = FpGadget::alloc(cs.ns(|| format!("x")), || {
|
||||
x_value.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?;
|
||||
let y_allocated = FpGadget::alloc(cs.ns(|| format!("y")), || {
|
||||
y_value.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?;
|
||||
let x_allocated = FpGadget::alloc(cs.ns(|| "x"), || x_value.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
let y_allocated = FpGadget::alloc(cs.ns(|| "y"), || y_value.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
|
||||
Ok(EdwardsBlsGadget::new(x_allocated, y_allocated))
|
||||
}
|
||||
@ -316,7 +316,7 @@ impl AllocGadget<GroupValue, Fq> for EdwardsGroupType {
|
||||
Self::alloc_helper(value_gen)
|
||||
})?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(value))
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(value)))
|
||||
}
|
||||
|
||||
fn alloc_input<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<GroupValue>, CS: ConstraintSystem<Fq>>(
|
||||
@ -327,7 +327,7 @@ impl AllocGadget<GroupValue, Fq> for EdwardsGroupType {
|
||||
Self::alloc_helper(value_gen)
|
||||
})?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(value))
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(value)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -454,7 +454,7 @@ impl CondSelectGadget<Fq> for EdwardsGroupType {
|
||||
let second_gadget = second.allocated(cs.ns(|| "second"))?;
|
||||
let result = EdwardsBlsGadget::conditionally_select(cs, cond, &first_gadget, &second_gadget)?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(result))
|
||||
Ok(EdwardsGroupType::Allocated(Box::new(result)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ impl Integer {
|
||||
let unsigned_integer = self;
|
||||
let value_option: Option<String> = match_unsigned_integer!(unsigned_integer => unsigned_integer.get_value());
|
||||
|
||||
let value = value_option.ok_or(IntegerError::invalid_index(span.clone()))?;
|
||||
let value = value_option.ok_or_else(|| IntegerError::invalid_index(span.clone()))?;
|
||||
let value_usize = value
|
||||
.parse::<usize>()
|
||||
.map_err(|_| IntegerError::invalid_integer(value, span))?;
|
||||
@ -378,7 +378,7 @@ impl Integer {
|
||||
|
||||
let result = match_signed_integer!(a, s => a.neg(cs.ns(|| unique_namespace)));
|
||||
|
||||
result.ok_or(IntegerError::negate_operation(span))
|
||||
result.ok_or_else(|| IntegerError::negate_operation(span))
|
||||
}
|
||||
|
||||
pub fn add<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||
@ -395,7 +395,7 @@ impl Integer {
|
||||
|
||||
let result = match_integers_span!((a, b), s => a.add(cs.ns(|| unique_namespace), &b));
|
||||
|
||||
result.ok_or(IntegerError::binary_operation(format!("+"), span))
|
||||
result.ok_or_else(|| IntegerError::binary_operation("+".to_string(), span))
|
||||
}
|
||||
|
||||
pub fn sub<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||
@ -412,7 +412,7 @@ impl Integer {
|
||||
|
||||
let result = match_integers_span!((a, b), s => a.sub(cs.ns(|| unique_namespace), &b));
|
||||
|
||||
result.ok_or(IntegerError::binary_operation(format!("-"), span))
|
||||
result.ok_or_else(|| IntegerError::binary_operation("-".to_string(), span))
|
||||
}
|
||||
|
||||
pub fn mul<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||
@ -429,7 +429,7 @@ impl Integer {
|
||||
|
||||
let result = match_integers_span!((a, b), s => a.mul(cs.ns(|| unique_namespace), &b));
|
||||
|
||||
result.ok_or(IntegerError::binary_operation(format!("*"), span))
|
||||
result.ok_or_else(|| IntegerError::binary_operation("*".to_string(), span))
|
||||
}
|
||||
|
||||
pub fn div<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||
@ -446,7 +446,7 @@ impl Integer {
|
||||
|
||||
let result = match_integers_span!((a, b), s => a.div(cs.ns(|| unique_namespace), &b));
|
||||
|
||||
result.ok_or(IntegerError::binary_operation(format!("÷"), span))
|
||||
result.ok_or_else(|| IntegerError::binary_operation("÷".to_string(), span))
|
||||
}
|
||||
|
||||
pub fn pow<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||
@ -463,7 +463,7 @@ impl Integer {
|
||||
|
||||
let result = match_integers_span!((a, b), s => a.pow(cs.ns(|| unique_namespace), &b));
|
||||
|
||||
result.ok_or(IntegerError::binary_operation(format!("**"), span))
|
||||
result.ok_or_else(|| IntegerError::binary_operation("**".to_string(), span))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
|
||||
// Data type wrappers
|
||||
ConstrainedValue::Array(array) => {
|
||||
let array_type = array[0].to_type(span.clone())?;
|
||||
let array_type = array[0].to_type(span)?;
|
||||
let mut dimensions = vec![array.len()];
|
||||
|
||||
// Nested array type
|
||||
@ -122,7 +122,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
Type::Array(Box::new(array_type), dimensions)
|
||||
}
|
||||
ConstrainedValue::Tuple(tuple) => {
|
||||
let mut types = vec![];
|
||||
let mut types = Vec::with_capacity(tuple.len());
|
||||
|
||||
for value in tuple {
|
||||
let type_ = value.to_type(span.clone())?;
|
||||
@ -205,15 +205,15 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
// If this is a circuit function, evaluate inside the circuit scope
|
||||
if let Some(identifier) = circuit_identifier {
|
||||
// avoid creating recursive scope
|
||||
if !is_in_scope(&scope, &identifier.name.to_string()) {
|
||||
outer_scope = new_scope(scope, identifier.name.to_string());
|
||||
if !is_in_scope(&scope, &identifier.name) {
|
||||
outer_scope = new_scope(scope, identifier.name);
|
||||
}
|
||||
}
|
||||
|
||||
Ok((outer_scope, function.clone()))
|
||||
Ok((outer_scope, function))
|
||||
}
|
||||
ConstrainedValue::Import(import_scope, function) => function.extract_function(import_scope, span),
|
||||
value => return Err(ExpressionError::undefined_function(value.to_string(), span)),
|
||||
value => Err(ExpressionError::undefined_function(value.to_string(), span)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,7 +221,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
match self {
|
||||
ConstrainedValue::CircuitDefinition(circuit) => Ok(circuit),
|
||||
ConstrainedValue::Import(_import_scope, circuit) => circuit.extract_circuit(span),
|
||||
value => return Err(ExpressionError::undefined_circuit(value.to_string(), span)),
|
||||
value => Err(ExpressionError::undefined_circuit(value.to_string(), span)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +239,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
}
|
||||
ConstrainedValue::Boolean(boolean) => {
|
||||
let option = boolean.get_value();
|
||||
let name = option.map(|b| b.to_string()).unwrap_or(format!("[allocated]"));
|
||||
let name = option
|
||||
.map(|b| b.to_string())
|
||||
.unwrap_or_else(|| "[allocated]".to_string());
|
||||
|
||||
*boolean = allocate_bool(&mut cs, name, option, span)?;
|
||||
}
|
||||
@ -256,7 +258,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::Integer(integer) => {
|
||||
let integer_type = integer.get_type();
|
||||
let option = integer.get_value();
|
||||
let name = option.clone().unwrap_or(format!("[allocated]"));
|
||||
let name = option.clone().unwrap_or_else(|| "[allocated]".to_string());
|
||||
|
||||
*integer = Integer::allocate_type(&mut cs, integer_type, name, option, span)?;
|
||||
}
|
||||
@ -328,7 +330,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<F
|
||||
value
|
||||
.get_value()
|
||||
.map(|v| v.to_string())
|
||||
.unwrap_or(format!("[allocated]"))
|
||||
.unwrap_or_else(|| "[allocated]".to_string())
|
||||
),
|
||||
ConstrainedValue::Field(ref value) => write!(f, "{:?}", value),
|
||||
ConstrainedValue::Group(ref value) => write!(f, "{:?}", value),
|
||||
@ -402,18 +404,18 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConditionalEqGadget<F> for Constrai
|
||||
num_1.conditional_enforce_equal(cs, num_2, condition)
|
||||
}
|
||||
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
|
||||
for (i, (left, right)) in arr_1.into_iter().zip(arr_2.into_iter()).enumerate() {
|
||||
for (i, (left, right)) in arr_1.iter().zip(arr_2.iter()).enumerate() {
|
||||
left.conditional_enforce_equal(cs.ns(|| format!("array[{}]", i)), right, condition)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Tuple(tuple_2)) => {
|
||||
for (i, (left, right)) in tuple_1.into_iter().zip(tuple_2.into_iter()).enumerate() {
|
||||
for (i, (left, right)) in tuple_1.iter().zip(tuple_2.iter()).enumerate() {
|
||||
left.conditional_enforce_equal(cs.ns(|| format!("tuple index {}", i)), right, condition)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
(_, _) => return Err(SynthesisError::Unsatisfiable),
|
||||
(_, _) => Err(SynthesisError::Unsatisfiable),
|
||||
}
|
||||
}
|
||||
|
||||
@ -446,9 +448,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
|
||||
ConstrainedValue::Integer(Integer::conditionally_select(cs, cond, num_1, num_2)?)
|
||||
}
|
||||
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
|
||||
let mut array = vec![];
|
||||
let mut array = Vec::with_capacity(arr_1.len());
|
||||
|
||||
for (i, (first, second)) in arr_1.into_iter().zip(arr_2.into_iter()).enumerate() {
|
||||
for (i, (first, second)) in arr_1.iter().zip(arr_2.iter()).enumerate() {
|
||||
array.push(Self::conditionally_select(
|
||||
cs.ns(|| format!("array[{}]", i)),
|
||||
cond,
|
||||
@ -460,9 +462,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
|
||||
ConstrainedValue::Array(array)
|
||||
}
|
||||
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Array(tuple_2)) => {
|
||||
let mut array = vec![];
|
||||
let mut array = Vec::with_capacity(tuple_1.len());
|
||||
|
||||
for (i, (first, second)) in tuple_1.into_iter().zip(tuple_2.into_iter()).enumerate() {
|
||||
for (i, (first, second)) in tuple_1.iter().zip(tuple_2.iter()).enumerate() {
|
||||
array.push(Self::conditionally_select(
|
||||
cs.ns(|| format!("tuple index {}", i)),
|
||||
cond,
|
||||
@ -482,9 +484,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
|
||||
ConstrainedValue::CircuitExpression(identifier, members_1),
|
||||
ConstrainedValue::CircuitExpression(_identifier, members_2),
|
||||
) => {
|
||||
let mut members = vec![];
|
||||
let mut members = Vec::with_capacity(members_1.len());
|
||||
|
||||
for (i, (first, second)) in members_1.into_iter().zip(members_2.into_iter()).enumerate() {
|
||||
for (i, (first, second)) in members_1.iter().zip(members_2.iter()).enumerate() {
|
||||
members.push(ConstrainedCircuitMember::conditionally_select(
|
||||
cs.ns(|| format!("circuit member[{}]", i)),
|
||||
cond,
|
||||
@ -545,18 +547,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> From<Value> for ConstrainedValue<F,
|
||||
Value::I64(i64) => ConstrainedValue::Integer(Integer::I64(i64)),
|
||||
Value::I128(i128) => ConstrainedValue::Integer(Integer::I128(i128)),
|
||||
|
||||
Value::Array(array) => ConstrainedValue::Array(
|
||||
array
|
||||
.into_iter()
|
||||
.map(|element| ConstrainedValue::from(element))
|
||||
.collect(),
|
||||
),
|
||||
Value::Tuple(tuple) => ConstrainedValue::Tuple(
|
||||
tuple
|
||||
.into_iter()
|
||||
.map(|element| ConstrainedValue::from(element))
|
||||
.collect(),
|
||||
),
|
||||
Value::Array(array) => ConstrainedValue::Array(array.into_iter().map(ConstrainedValue::from).collect()),
|
||||
Value::Tuple(tuple) => ConstrainedValue::Tuple(tuple.into_iter().map(ConstrainedValue::from).collect()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,8 @@
|
||||
use crate::{assert_satisfied, expect_compiler_error, generate_main_input, parse_program};
|
||||
use leo_typed::InputValue;
|
||||
|
||||
static TEST_ADDRESS_1: &'static str = "aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8";
|
||||
static TEST_ADDRESS_2: &'static str = "aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams6lfpgcpq3dq05r";
|
||||
static TEST_ADDRESS_1: &str = "aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8";
|
||||
static TEST_ADDRESS_2: &str = "aleo18qgam03qe483tdrcc3fkqwpp38ehff4a2xma6lu7hams6lfpgcpq3dq05r";
|
||||
|
||||
#[test]
|
||||
fn test_valid() {
|
||||
|
@ -43,7 +43,7 @@ fn fail_boolean_statement(program: EdwardsTestCompiler) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::BooleanError(BooleanError::Error(_)),
|
||||
))) => {}
|
||||
_ => panic!("Expected boolean error, got {}"),
|
||||
e => panic!("Expected boolean error, got {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// allow the use of EdwardsTestCompiler::parse_program_from_string for tests
|
||||
#![allow(deprecated)]
|
||||
|
||||
pub mod address;
|
||||
pub mod array;
|
||||
pub mod boolean;
|
||||
|
@ -35,7 +35,7 @@ impl CorePackageError {
|
||||
}
|
||||
|
||||
pub fn core_package_star(span: Span) -> Self {
|
||||
let message = format!("Cannot import star from leo-core");
|
||||
let message = "Cannot import star from leo-core".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ impl CorePackageListError {
|
||||
}
|
||||
|
||||
pub fn core_package_star(span: Span) -> Self {
|
||||
let message = format!("Cannot import star from leo-core");
|
||||
let message = "Cannot import star from leo-core".to_string();
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ impl CoreCircuit for Blake2sCircuit {
|
||||
),
|
||||
span.clone(),
|
||||
)],
|
||||
span: span.clone(),
|
||||
span,
|
||||
},
|
||||
)],
|
||||
}
|
||||
@ -141,7 +141,7 @@ impl CoreCircuit for Blake2sCircuit {
|
||||
.to_bytes(cs)
|
||||
.map_err(|e| CoreCircuitError::cannot_enforce("Vec<UInt8> ToBytes".to_owned(), e, span.clone()))?;
|
||||
|
||||
let return_value = bytes.into_iter().map(|byte| Value::U8(byte)).collect();
|
||||
let return_value = bytes.into_iter().map(Value::U8).collect();
|
||||
|
||||
// Return one array digest value
|
||||
Ok(vec![Value::Array(return_value)])
|
||||
@ -158,7 +158,7 @@ fn check_array_bytes(value: Value, size: usize, span: Span) -> Result<Vec<UInt8>
|
||||
return Err(CoreCircuitError::array_length(size, array_value.len(), span));
|
||||
}
|
||||
|
||||
let mut array_bytes = vec![];
|
||||
let mut array_bytes = Vec::with_capacity(array_value.len());
|
||||
|
||||
for value in array_value {
|
||||
let byte = match value {
|
||||
|
@ -71,7 +71,7 @@ impl CorePackage {
|
||||
let span = circuit.span.clone();
|
||||
|
||||
// take the alias if it is present
|
||||
let id = circuit.alias.clone().unwrap_or(circuit.symbol.clone());
|
||||
let id = circuit.alias.clone().unwrap_or_else(|| circuit.symbol.clone());
|
||||
let name = id.name.clone();
|
||||
|
||||
let circuit = if self.unstable {
|
||||
@ -87,9 +87,7 @@ impl CorePackage {
|
||||
}
|
||||
} else {
|
||||
// match core circuit
|
||||
match circuit_name {
|
||||
name => return Err(CorePackageError::undefined_core_circuit(name.to_string(), span)),
|
||||
}
|
||||
return Err(CorePackageError::undefined_core_circuit(circuit_name.to_string(), span));
|
||||
};
|
||||
|
||||
circuit_structs.push(name, circuit)
|
||||
|
@ -71,7 +71,7 @@ impl fmt::Display for Value {
|
||||
}
|
||||
};
|
||||
|
||||
let string = string_option.unwrap_or("[input]".to_owned());
|
||||
let string = string_option.unwrap_or_else(|| "[input]".to_owned());
|
||||
|
||||
write!(f, "{}", string)
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ where
|
||||
{
|
||||
type ErrorType;
|
||||
|
||||
#[must_use]
|
||||
fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,5 @@ where
|
||||
{
|
||||
type ErrorType;
|
||||
|
||||
#[must_use]
|
||||
fn div<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
||||
}
|
||||
|
@ -23,6 +23,5 @@ where
|
||||
{
|
||||
type ErrorType;
|
||||
|
||||
#[must_use]
|
||||
fn mul<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ where
|
||||
{
|
||||
type ErrorType;
|
||||
|
||||
#[must_use]
|
||||
fn neg<CS: ConstraintSystem<F>>(&self, cs: CS) -> Result<Self, Self::ErrorType>;
|
||||
}
|
||||
|
||||
@ -44,7 +43,7 @@ impl<F: Field> Neg<F> for Vec<Boolean> {
|
||||
let mut one = vec![Boolean::constant(true)];
|
||||
one.append(&mut vec![Boolean::Constant(false); self.len() - 1]);
|
||||
|
||||
let mut bits = flipped.add_bits(cs.ns(|| format!("add one")), &one)?;
|
||||
let mut bits = flipped.add_bits(cs.ns(|| "add one"), &one)?;
|
||||
let _carry = bits.pop(); // we already accounted for overflow above
|
||||
|
||||
Ok(bits)
|
||||
|
@ -23,6 +23,5 @@ where
|
||||
{
|
||||
type ErrorType;
|
||||
|
||||
#[must_use]
|
||||
fn pow<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
||||
}
|
||||
|
@ -23,6 +23,5 @@ where
|
||||
{
|
||||
type ErrorType;
|
||||
|
||||
#[must_use]
|
||||
fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
|
||||
}
|
||||
|
@ -44,12 +44,12 @@ impl<'a, F: Field> FullAdder<'a, F> for Boolean {
|
||||
b: &'a Self,
|
||||
carry: &'a Self,
|
||||
) -> Result<(Self, Self), SynthesisError> {
|
||||
let a_x_b = Boolean::xor(cs.ns(|| format!("a XOR b")), a, b)?;
|
||||
let sum = Boolean::xor(cs.ns(|| format!("adder sum")), &a_x_b, carry)?;
|
||||
let a_x_b = Boolean::xor(cs.ns(|| "a XOR b"), a, b)?;
|
||||
let sum = Boolean::xor(cs.ns(|| "adder sum"), &a_x_b, carry)?;
|
||||
|
||||
let c1 = Boolean::and(cs.ns(|| format!("a AND b")), a, b)?;
|
||||
let c2 = Boolean::and(cs.ns(|| format!("carry AND (a XOR b)")), carry, &a_x_b)?;
|
||||
let carry = Boolean::or(cs.ns(|| format!("c1 OR c2")), &c1, &c2)?;
|
||||
let c1 = Boolean::and(cs.ns(|| "a AND b"), a, b)?;
|
||||
let c2 = Boolean::and(cs.ns(|| "carry AND (a XOR b)"), carry, &a_x_b)?;
|
||||
let carry = Boolean::or(cs.ns(|| "c1 OR c2"), &c1, &c2)?;
|
||||
|
||||
Ok((sum, carry))
|
||||
}
|
||||
|
@ -27,14 +27,13 @@ pub trait RippleCarryAdder<F: Field, Rhs = Self>
|
||||
where
|
||||
Self: std::marker::Sized,
|
||||
{
|
||||
#[must_use]
|
||||
fn add_bits<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Vec<Boolean>, SynthesisError>;
|
||||
}
|
||||
|
||||
// Generic impl
|
||||
impl<F: Field> RippleCarryAdder<F> for Vec<Boolean> {
|
||||
fn add_bits<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Vec<Boolean>, SynthesisError> {
|
||||
let mut result = vec![];
|
||||
let mut result = Vec::with_capacity(self.len() + 1);
|
||||
let mut carry = Boolean::constant(false);
|
||||
for (i, (a, b)) in self.iter().zip(other.iter()).enumerate() {
|
||||
let (sum, next) = Boolean::add(cs.ns(|| format!("rpc {}", i)), a, b, &carry)?;
|
||||
|
@ -30,7 +30,7 @@ impl SignExtend for Boolean {
|
||||
fn sign_extend(bits: &[Boolean], length: usize) -> Vec<Boolean> {
|
||||
let msb = bits.last().expect("empty bit list");
|
||||
let bits_needed = length - bits.len();
|
||||
let mut extension = vec![msb.clone(); bits_needed];
|
||||
let mut extension = vec![*msb; bits_needed];
|
||||
|
||||
let mut result = Vec::from(bits);
|
||||
result.append(&mut extension);
|
||||
|
@ -87,7 +87,7 @@ macro_rules! add_int_impl {
|
||||
all_constants = false;
|
||||
|
||||
// Add the coeff * bit_gadget
|
||||
lc = lc + (coeff, bit.get_variable());
|
||||
lc += (coeff, bit.get_variable());
|
||||
}
|
||||
Boolean::Not(ref bit) => {
|
||||
all_constants = false;
|
||||
@ -97,7 +97,7 @@ macro_rules! add_int_impl {
|
||||
}
|
||||
Boolean::Constant(bit) => {
|
||||
if bit {
|
||||
lc = lc + (coeff, CS::one());
|
||||
lc += (coeff, CS::one());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,7 +117,7 @@ macro_rules! add_int_impl {
|
||||
}
|
||||
|
||||
// Storage area for the resulting bits
|
||||
let mut result_bits = vec![];
|
||||
let mut result_bits = Vec::with_capacity(max_bits);
|
||||
|
||||
// Allocate each bit_gadget of the result
|
||||
let mut coeff = F::one();
|
||||
|
@ -206,13 +206,13 @@ macro_rules! div_int_impl {
|
||||
&r
|
||||
)?;
|
||||
|
||||
index = index - 1;
|
||||
index -= 1;
|
||||
|
||||
let mut q_new = q.clone();
|
||||
q_new.bits[index] = true_bit.clone();
|
||||
q_new.value = Some(q_new.value.unwrap() + bit_value);
|
||||
|
||||
bit_value = (bit_value >> 1);
|
||||
bit_value >>= 1;
|
||||
|
||||
q = Self::conditionally_select(
|
||||
&mut cs.ns(|| format!("set_bit_or_same_{}", i)),
|
||||
|
@ -84,7 +84,7 @@ macro_rules! mul_int_impl {
|
||||
a_shifted.truncate(size);
|
||||
|
||||
// conditionally add
|
||||
let mut to_add = vec![];
|
||||
let mut to_add = Vec::with_capacity(a_shifted.len());
|
||||
for (j, a_bit) in a_shifted.iter().enumerate() {
|
||||
let selected_bit = Boolean::conditionally_select(
|
||||
&mut cs.ns(|| format!("select product bit {} {}", i, j)),
|
||||
@ -146,7 +146,7 @@ macro_rules! mul_int_impl {
|
||||
all_constants = false;
|
||||
|
||||
// Add the coeff * bit_gadget
|
||||
lc = lc + (coeff, bit.get_variable());
|
||||
lc += (coeff, bit.get_variable());
|
||||
}
|
||||
Boolean::Not(ref bit) => {
|
||||
all_constants = false;
|
||||
@ -156,7 +156,7 @@ macro_rules! mul_int_impl {
|
||||
}
|
||||
Boolean::Constant(bit) => {
|
||||
if bit {
|
||||
lc = lc + (coeff, CS::one());
|
||||
lc += (coeff, CS::one());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,7 +175,7 @@ macro_rules! mul_int_impl {
|
||||
}
|
||||
|
||||
// Storage area for the resulting bits
|
||||
let mut result_bits = vec![];
|
||||
let mut result_bits = Vec::with_capacity(max_bits);
|
||||
|
||||
// Allocate each bit_gadget of the result
|
||||
let mut coeff = F::one();
|
||||
|
@ -34,10 +34,10 @@ fn check_all_constant_bits(expected: i128, actual: Int128) {
|
||||
let mask = 1 << i as i128;
|
||||
let result = expected & mask;
|
||||
|
||||
match b {
|
||||
&Boolean::Is(_) => panic!(),
|
||||
&Boolean::Not(_) => panic!(),
|
||||
&Boolean::Constant(b) => {
|
||||
match *b {
|
||||
Boolean::Is(_) => panic!(),
|
||||
Boolean::Not(_) => panic!(),
|
||||
Boolean::Constant(b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(b, bit);
|
||||
}
|
||||
@ -51,16 +51,16 @@ fn check_all_allocated_bits(expected: i128, actual: Int128) {
|
||||
let mask = 1 << i as i128;
|
||||
let result = expected & mask;
|
||||
|
||||
match b {
|
||||
&Boolean::Is(ref b) => {
|
||||
match *b {
|
||||
Boolean::Is(ref b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(b.get_value().unwrap(), bit);
|
||||
}
|
||||
&Boolean::Not(ref b) => {
|
||||
Boolean::Not(ref b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(!b.get_value().unwrap(), bit);
|
||||
}
|
||||
&Boolean::Constant(_) => unreachable!(),
|
||||
Boolean::Constant(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,10 +34,10 @@ fn check_all_constant_bits(expected: i16, actual: Int16) {
|
||||
let mask = 1 << i as i16;
|
||||
let result = expected & mask;
|
||||
|
||||
match b {
|
||||
&Boolean::Is(_) => panic!(),
|
||||
&Boolean::Not(_) => panic!(),
|
||||
&Boolean::Constant(b) => {
|
||||
match *b {
|
||||
Boolean::Is(_) => panic!(),
|
||||
Boolean::Not(_) => panic!(),
|
||||
Boolean::Constant(b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(b, bit);
|
||||
}
|
||||
@ -51,16 +51,16 @@ fn check_all_allocated_bits(expected: i16, actual: Int16) {
|
||||
let mask = 1 << i as i16;
|
||||
let result = expected & mask;
|
||||
|
||||
match b {
|
||||
&Boolean::Is(ref b) => {
|
||||
match *b {
|
||||
Boolean::Is(ref b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(b.get_value().unwrap(), bit);
|
||||
}
|
||||
&Boolean::Not(ref b) => {
|
||||
Boolean::Not(ref b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(!b.get_value().unwrap(), bit);
|
||||
}
|
||||
&Boolean::Constant(_) => unreachable!(),
|
||||
Boolean::Constant(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,10 +34,10 @@ fn check_all_constant_bits(expected: i32, actual: Int32) {
|
||||
let mask = 1 << i as i32;
|
||||
let result = expected & mask;
|
||||
|
||||
match b {
|
||||
&Boolean::Is(_) => panic!(),
|
||||
&Boolean::Not(_) => panic!(),
|
||||
&Boolean::Constant(b) => {
|
||||
match *b {
|
||||
Boolean::Is(_) => panic!(),
|
||||
Boolean::Not(_) => panic!(),
|
||||
Boolean::Constant(b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(b, bit);
|
||||
}
|
||||
@ -51,16 +51,16 @@ fn check_all_allocated_bits(expected: i32, actual: Int32) {
|
||||
let mask = 1 << i as i32;
|
||||
let result = expected & mask;
|
||||
|
||||
match b {
|
||||
&Boolean::Is(ref b) => {
|
||||
match *b {
|
||||
Boolean::Is(ref b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(b.get_value().unwrap(), bit);
|
||||
}
|
||||
&Boolean::Not(ref b) => {
|
||||
Boolean::Not(ref b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(!b.get_value().unwrap(), bit);
|
||||
}
|
||||
&Boolean::Constant(_) => unreachable!(),
|
||||
Boolean::Constant(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,10 +34,10 @@ fn check_all_constant_bits(expected: i64, actual: Int64) {
|
||||
let mask = 1 << i as i64;
|
||||
let result = expected & mask;
|
||||
|
||||
match b {
|
||||
&Boolean::Is(_) => panic!(),
|
||||
&Boolean::Not(_) => panic!(),
|
||||
&Boolean::Constant(b) => {
|
||||
match *b {
|
||||
Boolean::Is(_) => panic!(),
|
||||
Boolean::Not(_) => panic!(),
|
||||
Boolean::Constant(b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(b, bit);
|
||||
}
|
||||
@ -51,16 +51,16 @@ fn check_all_allocated_bits(expected: i64, actual: Int64) {
|
||||
let mask = 1 << i as i64;
|
||||
let result = expected & mask;
|
||||
|
||||
match b {
|
||||
&Boolean::Is(ref b) => {
|
||||
match *b {
|
||||
Boolean::Is(ref b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(b.get_value().unwrap(), bit);
|
||||
}
|
||||
&Boolean::Not(ref b) => {
|
||||
Boolean::Not(ref b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(!b.get_value().unwrap(), bit);
|
||||
}
|
||||
&Boolean::Constant(_) => unreachable!(),
|
||||
Boolean::Constant(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,10 +34,10 @@ fn check_all_constant_bits(expected: i8, actual: Int8) {
|
||||
let mask = 1 << i as i8;
|
||||
let result = expected & mask;
|
||||
|
||||
match b {
|
||||
&Boolean::Is(_) => panic!(),
|
||||
&Boolean::Not(_) => panic!(),
|
||||
&Boolean::Constant(b) => {
|
||||
match *b {
|
||||
Boolean::Is(_) => panic!(),
|
||||
Boolean::Not(_) => panic!(),
|
||||
Boolean::Constant(b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(b, bit);
|
||||
}
|
||||
@ -51,16 +51,16 @@ fn check_all_allocated_bits(expected: i8, actual: Int8) {
|
||||
let mask = 1 << i as i8;
|
||||
let result = expected & mask;
|
||||
|
||||
match b {
|
||||
&Boolean::Is(ref b) => {
|
||||
match *b {
|
||||
Boolean::Is(ref b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(b.get_value().unwrap(), bit);
|
||||
}
|
||||
&Boolean::Not(ref b) => {
|
||||
Boolean::Not(ref b) => {
|
||||
let bit = result == mask;
|
||||
assert_eq!(!b.get_value().unwrap(), bit);
|
||||
}
|
||||
&Boolean::Constant(_) => unreachable!(),
|
||||
Boolean::Constant(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,20 +53,17 @@ pub enum InputParserError {
|
||||
|
||||
impl InputParserError {
|
||||
pub fn set_path(&mut self, path: PathBuf) {
|
||||
match self {
|
||||
InputParserError::SyntaxError(error) => {
|
||||
let new_error: Error<Rule> = match error {
|
||||
InputSyntaxError::Error(error) => {
|
||||
let new_error = error.clone();
|
||||
new_error.with_path(path.to_str().unwrap())
|
||||
}
|
||||
};
|
||||
if let InputParserError::SyntaxError(error) = self {
|
||||
let new_error: Error<Rule> = match error {
|
||||
InputSyntaxError::Error(error) => {
|
||||
let new_error = error.clone();
|
||||
new_error.with_path(path.to_str().unwrap())
|
||||
}
|
||||
};
|
||||
|
||||
tracing::error!("{}", new_error);
|
||||
tracing::error!("{}", new_error);
|
||||
|
||||
*error = InputSyntaxError::Error(new_error);
|
||||
}
|
||||
_ => {}
|
||||
*error = InputSyntaxError::Error(new_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ pub trait CLI {
|
||||
.iter()
|
||||
.map(|a| {
|
||||
let mut args = Arg::with_name(a.0).help(a.1).required(a.3).index(a.4);
|
||||
if a.2.len() > 0 {
|
||||
if !a.2.is_empty() {
|
||||
args = args.possible_values(a.2);
|
||||
}
|
||||
args
|
||||
@ -47,7 +47,7 @@ pub trait CLI {
|
||||
.collect::<Vec<Arg<'static, 'static>>>();
|
||||
let options = &Self::OPTIONS
|
||||
.iter()
|
||||
.map(|a| match a.2.len() > 0 {
|
||||
.map(|a| match !a.2.is_empty() {
|
||||
true => Arg::from_usage(a.0)
|
||||
.conflicts_with_all(a.1)
|
||||
.possible_values(a.2)
|
||||
@ -64,7 +64,7 @@ pub trait CLI {
|
||||
&s.2.iter()
|
||||
.map(|a| {
|
||||
let mut args = Arg::with_name(a.0).help(a.1).required(a.3).index(a.4);
|
||||
if a.2.len() > 0 {
|
||||
if !a.2.is_empty() {
|
||||
args = args.possible_values(a.2);
|
||||
}
|
||||
args
|
||||
@ -78,7 +78,7 @@ pub trait CLI {
|
||||
)
|
||||
.args(
|
||||
&s.4.iter()
|
||||
.map(|a| match a.2.len() > 0 {
|
||||
.map(|a| match !a.2.is_empty() {
|
||||
true => Arg::from_usage(a.0)
|
||||
.conflicts_with_all(a.1)
|
||||
.possible_values(a.2)
|
||||
|
@ -167,7 +167,7 @@ impl CLI for AddCommand {
|
||||
let mut file_path = path.clone();
|
||||
file_path.push(file_name);
|
||||
|
||||
if file_name.ends_with("/") {
|
||||
if file_name.ends_with('/') {
|
||||
create_dir_all(file_path)?;
|
||||
} else {
|
||||
if let Some(parent_directory) = path.parent() {
|
||||
|
@ -93,7 +93,7 @@ impl CLI for BuildCommand {
|
||||
// Compile the library file but do not output
|
||||
let _program = Compiler::<Fq, EdwardsGroupType>::parse_program_without_input(
|
||||
package_name.clone(),
|
||||
lib_file_path.clone(),
|
||||
lib_file_path,
|
||||
output_directory.clone(),
|
||||
)?;
|
||||
tracing::info!("Complete");
|
||||
@ -121,7 +121,7 @@ impl CLI for BuildCommand {
|
||||
// Load the program at `main_file_path`
|
||||
let program = Compiler::<Fq, EdwardsGroupType>::parse_program_with_input(
|
||||
package_name.clone(),
|
||||
main_file_path.clone(),
|
||||
main_file_path,
|
||||
output_directory,
|
||||
&input_string,
|
||||
input_path,
|
||||
|
@ -65,7 +65,7 @@ impl CLI for DeployCommand {
|
||||
Ok(())
|
||||
}
|
||||
None => {
|
||||
let mut main_file_path = path.clone();
|
||||
let mut main_file_path = path;
|
||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
main_file_path.push(MAIN_FILENAME);
|
||||
|
||||
|
@ -65,7 +65,7 @@ impl CLI for LintCommand {
|
||||
Ok(())
|
||||
}
|
||||
None => {
|
||||
let mut main_file_path = path.clone();
|
||||
let mut main_file_path = path;
|
||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
main_file_path.push(MAIN_FILENAME);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user