Merge pull request #384 from ljedrz/clippy_compliance

Clippy compliance, part 1/2
This commit is contained in:
Collin Chin 2020-10-20 21:23:06 -07:00 committed by GitHub
commit 6ede1f72eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
130 changed files with 491 additions and 592 deletions

View File

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // 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/>. // along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
#![allow(clippy::module_inception)]
pub mod access; pub mod access;
pub use access::*; pub use access::*;

View File

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // 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/>. // along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
#![allow(clippy::module_inception)]
pub mod annotations; pub mod annotations;
pub use annotations::*; pub use annotations::*;

View File

@ -39,20 +39,17 @@ pub enum ParserError {
impl ParserError { impl ParserError {
pub fn set_path(&mut self, path: PathBuf) { pub fn set_path(&mut self, path: PathBuf) {
match self { if let ParserError::SyntaxError(error) = self {
ParserError::SyntaxError(error) => { let new_error: Error<Rule> = match error {
let new_error: Error<Rule> = match error { SyntaxError::Error(error) => {
SyntaxError::Error(error) => { let new_error = error.clone();
let new_error = error.clone(); new_error.with_path(path.to_str().unwrap())
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);
}
_ => {}
} }
} }
} }

View File

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // 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/>. // along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
#![allow(clippy::module_inception)]
pub mod function_input; pub mod function_input;
pub use function_input::*; pub use function_input::*;

View File

@ -39,11 +39,11 @@ pub struct ConditionalStatement<'ast> {
impl<'ast> fmt::Display for ConditionalStatement<'ast> { impl<'ast> fmt::Display for ConditionalStatement<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "if ({}) {{\n", self.condition)?; writeln!(f, "if ({}) {{", self.condition)?;
write!(f, "\t{:#?}\n", self.statements)?; writeln!(f, "\t{:#?}", self.statements)?;
self.next self.next
.as_ref() .as_ref()
.map(|n_or_e| write!(f, "}} {}", n_or_e)) .map(|n_or_e| write!(f, "}} {}", n_or_e))
.unwrap_or(write!(f, "}}")) .unwrap_or_else(|| write!(f, "}}"))
} }
} }

View File

@ -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. /// Parses the Leo program file, constructs a syntax tree, and generates a program.
#[allow(deprecated)]
pub(crate) fn parse_program(&mut self) -> Result<(), CompilerError> { pub(crate) fn parse_program(&mut self) -> Result<(), CompilerError> {
// Use the parser to construct the abstract syntax tree. // Use the parser to construct the abstract syntax tree.
let program_string = LeoAst::load_file(&self.main_file_path)?; let program_string = LeoAst::load_file(&self.main_file_path)?;

View File

@ -53,9 +53,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// Unwrap assertion value and handle errors // Unwrap assertion value and handle errors
let result_option = match assert_expression { let result_option = match assert_expression {
ConstrainedValue::Boolean(boolean) => boolean.get_value(), 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 { if !result_bool {
return Err(ConsoleError::assertion_failed(expression_string, span)); return Err(ConsoleError::assertion_failed(expression_string, span));

View File

@ -37,16 +37,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
return Err(ConsoleError::length( return Err(ConsoleError::length(
formatted.containers.len(), formatted.containers.len(),
formatted.parameters.len(), formatted.parameters.len(),
formatted.span.clone(), formatted.span,
)); ));
} }
// Trim starting double quote `"` // Trim starting double quote `"`
let mut string = formatted.string.as_str(); let mut string = formatted.string.as_str();
string = string.trim_start_matches("\""); string = string.trim_start_matches('\"');
// Trim everything after the ending double quote `"` // Trim everything after the ending double quote `"`
let parts: Vec<&str> = string.split("\"").collect(); let parts: Vec<&str> = string.split('\"').collect();
string = parts[0]; string = parts[0];
// Insert the parameter for each container `{}` // Insert the parameter for each container `{}`

View File

@ -32,7 +32,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
mutable: bool, mutable: bool,
identifier: Identifier, identifier: Identifier,
mut value: ConstrainedValue<F, G>, mut value: ConstrainedValue<F, G>,
) -> () { ) {
// Store with given mutability // Store with given mutability
if mutable { if mutable {
value = ConstrainedValue::Mutable(Box::new(value)); value = ConstrainedValue::Mutable(Box::new(value));

View File

@ -50,7 +50,8 @@ impl ConsoleError {
} }
pub fn assertion_depends_on_input(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }

View File

@ -146,7 +146,7 @@ impl ExpressionError {
} }
pub fn self_keyword(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }

View File

@ -48,7 +48,7 @@ impl ImportError {
} }
pub fn convert_os_string(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }

View File

@ -36,7 +36,7 @@ impl OutputBytesError {
} }
pub fn not_enough_registers(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }

View File

@ -67,13 +67,13 @@ impl StatementError {
} }
pub fn array_assign_index(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }
pub fn array_assign_range(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }
@ -145,7 +145,7 @@ impl StatementError {
} }
pub fn tuple_assign_index(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }

View File

@ -64,7 +64,7 @@ impl AddressError {
} }
pub fn missing_address(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }

View File

@ -88,13 +88,13 @@ impl GroupError {
} }
pub fn x_recover(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }
pub fn y_recover(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }

View File

@ -68,7 +68,7 @@ impl IntegerError {
} }
pub fn negate_operation(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }
@ -83,9 +83,9 @@ impl IntegerError {
} }
pub fn invalid_index(span: Span) -> Self { 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" "index must be a constant value unsigned integer. allocated indices produce a circuit of unknown size"
); .to_string();
Self::new_from_span(message, span) Self::new_from_span(message, span)
} }

View File

@ -63,7 +63,7 @@ impl ValueError {
} }
pub fn implicit_group(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }

View File

@ -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())?; let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
enforce_div(cs, val_1, val_2, span) enforce_div(cs, val_1, val_2, span)
} }
(val_1, val_2) => { (val_1, val_2) => Err(ExpressionError::incompatible_types(
return Err(ExpressionError::incompatible_types( format!("{} / {}", val_1, val_2,),
format!("{} / {}", val_1, val_2,), span,
span, )),
));
}
} }
} }

View File

@ -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())?; let val_2 = ConstrainedValue::from_other(string, &val_1, span.clone())?;
enforce_mul(cs, val_1, val_2, span) enforce_mul(cs, val_1, val_2, span)
} }
(val_1, val_2) => { (val_1, val_2) => Err(ExpressionError::incompatible_types(
return Err(ExpressionError::incompatible_types( format!("{} * {}", val_1, val_2),
format!("{} * {}", val_1, val_2), span,
span, )),
));
}
} }
} }

View File

@ -25,6 +25,7 @@ use snarkos_models::{
}; };
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
#[allow(clippy::too_many_arguments)]
pub fn enforce_array_access<CS: ConstraintSystem<F>>( pub fn enforce_array_access<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, 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 None => 0usize, // Array slice starts at index 0
}; };
let to_resolved = match to { let to_resolved = match to {
Some(to_index) => { Some(to_index) => self.enforce_index(cs, file_scope, function_scope, to_index, span)?,
self.enforce_index(cs, file_scope.clone(), function_scope.clone(), to_index, span.clone())?
}
None => array.len(), // Array slice ends at array length None => array.len(), // Array slice ends at array length
}; };
Ok(ConstrainedValue::Array(array[from_resolved..to_resolved].to_owned())) Ok(ConstrainedValue::Array(array[from_resolved..to_resolved].to_owned()))

View File

@ -37,7 +37,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
file_scope: String, file_scope: String,
function_scope: String, function_scope: String,
mut expected_type: Option<Type>, mut expected_type: Option<Type>,
array: Vec<Box<SpreadOrExpression>>, array: Vec<SpreadOrExpression>,
span: Span, span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> { ) -> Result<ConstrainedValue<F, G>, ExpressionError> {
// Check explicit array type dimension if given // Check explicit array type dimension if given
@ -47,12 +47,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
match type_ { match type_ {
Type::Array(ref type_, ref dimensions) => { Type::Array(ref type_, ref dimensions) => {
let number = match dimensions.first() { let number = match dimensions.first() {
Some(number) => number.clone(), Some(number) => *number,
None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)), None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)),
}; };
expected_dimensions.push(number); expected_dimensions.push(number);
expected_type = Some(type_.outer_dimension(dimensions).clone()); expected_type = Some(type_.outer_dimension(dimensions));
} }
ref type_ => { ref type_ => {
return Err(ExpressionError::unexpected_array(type_.to_string(), span)); 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![]; let mut result = vec![];
for element in array.into_iter() { for element in array.into_iter() {
match *element { match element {
SpreadOrExpression::Spread(spread) => match spread { SpreadOrExpression::Spread(spread) => match spread {
Expression::Identifier(identifier) => { Expression::Identifier(identifier) => {
let array_name = new_scope(function_scope.clone(), identifier.to_string()); 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 // Check expected_dimensions if given
if !expected_dimensions.is_empty() { if !expected_dimensions.is_empty() && expected_dimensions[expected_dimensions.len() - 1] != result.len() {
if expected_dimensions[expected_dimensions.len() - 1] != result.len() { return Err(ExpressionError::invalid_length(
return Err(ExpressionError::invalid_length( expected_dimensions[expected_dimensions.len() - 1],
expected_dimensions[expected_dimensions.len() - 1], result.len(),
result.len(), span,
span, ));
));
}
} }
Ok(ConstrainedValue::Array(result)) Ok(ConstrainedValue::Array(result))

View File

@ -34,15 +34,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
span: Span, span: Span,
) -> Result<usize, ExpressionError> { ) -> Result<usize, ExpressionError> {
let expected_type = Some(Type::IntegerType(IntegerType::U32)); let expected_type = Some(Type::IntegerType(IntegerType::U32));
match self.enforce_operand( match self.enforce_operand(cs, file_scope, function_scope, expected_type, index, span.clone())? {
cs, ConstrainedValue::Integer(number) => Ok(number.to_usize(span)?),
file_scope.clone(),
function_scope.clone(),
expected_type,
index,
span.clone(),
)? {
ConstrainedValue::Integer(number) => Ok(number.to_usize(span.clone())?),
value => Err(ExpressionError::invalid_index(value.to_string(), span)), value => Err(ExpressionError::invalid_index(value.to_string(), span)),
} }
} }

View File

@ -24,7 +24,10 @@ use snarkos_models::{
gadgets::r1cs::ConstraintSystem, gadgets::r1cs::ConstraintSystem,
}; };
type ConstrainedValuePair<T, U> = (ConstrainedValue<T, U>, ConstrainedValue<T, U>);
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
#[allow(clippy::too_many_arguments)]
pub fn enforce_binary_expression<CS: ConstraintSystem<F>>( pub fn enforce_binary_expression<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -34,7 +37,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
left: Expression, left: Expression,
right: Expression, right: Expression,
span: Span, span: Span,
) -> Result<(ConstrainedValue<F, G>, ConstrainedValue<F, G>), ExpressionError> { ) -> Result<ConstrainedValuePair<F, G>, ExpressionError> {
let mut resolved_left = self.enforce_operand( let mut resolved_left = self.enforce_operand(
cs, cs,
file_scope.clone(), file_scope.clone(),
@ -45,8 +48,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
)?; )?;
let mut resolved_right = self.enforce_operand( let mut resolved_right = self.enforce_operand(
cs, cs,
file_scope.clone(), file_scope,
function_scope.clone(), function_scope,
expected_type.clone(), expected_type.clone(),
right, right,
span.clone(), span.clone(),

View File

@ -29,9 +29,10 @@ use snarkos_models::{
gadgets::r1cs::ConstraintSystem, gadgets::r1cs::ConstraintSystem,
}; };
static SELF_KEYWORD: &'static str = "self"; static SELF_KEYWORD: &str = "self";
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
#[allow(clippy::too_many_arguments)]
pub fn enforce_circuit_access<CS: ConstraintSystem<F>>( pub fn enforce_circuit_access<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, 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 // access a circuit member using the `self` keyword
if let Expression::Identifier(ref identifier) = *circuit_identifier { if let Expression::Identifier(ref identifier) = *circuit_identifier {
if identifier.is_self() { 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 self_function_scope = new_scope(self_file_scope.clone(), identifier.name.to_string());
let member_value = 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); 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( let (circuit_name, members) = match self.enforce_operand(
cs, cs,
file_scope.clone(), file_scope.clone(),
function_scope.clone(), function_scope,
expected_type, expected_type,
*circuit_identifier.clone(), *circuit_identifier,
span.clone(), span.clone(),
)? { )? {
ConstrainedValue::CircuitExpression(name, members) => (name, members), ConstrainedValue::CircuitExpression(name, members) => (name, members),

View File

@ -40,7 +40,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
span: Span, span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> { ) -> Result<ConstrainedValue<F, G>, ExpressionError> {
// Circuit definitions are located at the minimum file scope // 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()); let mut program_identifier = new_scope(scopes[0].to_string(), identifier.to_string());
if identifier.is_self() { if identifier.is_self() {
@ -55,7 +55,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
let circuit_identifier = circuit.circuit_name.clone(); let circuit_identifier = circuit.circuit_name.clone();
let mut resolved_members = vec![]; let mut resolved_members = vec![];
for member in circuit.members.clone().into_iter() { for member in circuit.members.into_iter() {
match member { match member {
CircuitMember::CircuitVariable(is_mutable, identifier, type_) => { CircuitMember::CircuitVariable(is_mutable, identifier, type_) => {
let matched_variable = members let matched_variable = members
@ -98,7 +98,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
} }
Ok(ConstrainedValue::CircuitExpression( Ok(ConstrainedValue::CircuitExpression(
circuit_identifier.clone(), circuit_identifier,
resolved_members, resolved_members,
)) ))
} }

View File

@ -25,6 +25,7 @@ use snarkos_models::{
}; };
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
#[allow(clippy::too_many_arguments)]
pub fn enforce_circuit_static_access<CS: ConstraintSystem<F>>( pub fn enforce_circuit_static_access<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -36,26 +37,20 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
span: Span, span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> { ) -> Result<ConstrainedValue<F, G>, ExpressionError> {
// Get defined circuit // Get defined circuit
let circuit = match *circuit_identifier.clone() { let circuit = match *circuit_identifier {
Expression::Identifier(identifier) => { Expression::Identifier(identifier) => {
// Use the "Self" keyword to access a static circuit function // Use the "Self" keyword to access a static circuit function
if identifier.is_self() { if identifier.is_self() {
let circuit = self let circuit = self
.get(&file_scope) .get(&file_scope)
.ok_or(ExpressionError::self_keyword(identifier.span.clone()))?; .ok_or_else(|| ExpressionError::self_keyword(identifier.span))?;
circuit.to_owned() circuit.to_owned()
} else { } 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( expression => self.enforce_expression(cs, file_scope, function_scope, expected_type, expression)?,
cs,
file_scope.clone(),
function_scope.clone(),
expected_type,
expression,
)?,
} }
.extract_circuit(span.clone())?; .extract_circuit(span.clone())?;

View File

@ -26,6 +26,7 @@ use snarkos_models::{
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
/// Enforce ternary conditional expression /// Enforce ternary conditional expression
#[allow(clippy::too_many_arguments)]
pub fn enforce_conditional_expression<CS: ConstraintSystem<F>>( pub fn enforce_conditional_expression<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -57,14 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
span.clone(), span.clone(),
)?; )?;
let second_value = self.enforce_operand( let second_value = self.enforce_operand(cs, file_scope, function_scope, expected_type, second, span.clone())?;
cs,
file_scope.clone(),
function_scope.clone(),
expected_type,
second,
span.clone(),
)?;
let unique_namespace = cs.ns(|| { let unique_namespace = cs.ns(|| {
format!( 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) 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))
} }
} }

View File

@ -70,8 +70,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Expression::Add(left, right, span) => { Expression::Add(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs, cs,
file_scope.clone(), file_scope,
function_scope.clone(), function_scope,
expected_type, expected_type,
*left, *left,
*right, *right,
@ -83,8 +83,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Expression::Sub(left, right, span) => { Expression::Sub(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs, cs,
file_scope.clone(), file_scope,
function_scope.clone(), function_scope,
expected_type, expected_type,
*left, *left,
*right, *right,
@ -96,8 +96,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Expression::Mul(left, right, span) => { Expression::Mul(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs, cs,
file_scope.clone(), file_scope,
function_scope.clone(), function_scope,
expected_type, expected_type,
*left, *left,
*right, *right,
@ -109,8 +109,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Expression::Div(left, right, span) => { Expression::Div(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs, cs,
file_scope.clone(), file_scope,
function_scope.clone(), function_scope,
expected_type, expected_type,
*left, *left,
*right, *right,
@ -122,8 +122,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Expression::Pow(left, right, span) => { Expression::Pow(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs, cs,
file_scope.clone(), file_scope,
function_scope.clone(), function_scope,
expected_type, expected_type,
*left, *left,
*right, *right,
@ -141,8 +141,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Expression::Or(left, right, span) => { Expression::Or(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs, cs,
file_scope.clone(), file_scope,
function_scope.clone(), function_scope,
expected_type, expected_type,
*left, *left,
*right, *right,
@ -154,8 +154,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Expression::And(left, right, span) => { Expression::And(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs, cs,
file_scope.clone(), file_scope,
function_scope.clone(), function_scope,
expected_type, expected_type,
*left, *left,
*right, *right,
@ -165,67 +165,32 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Ok(enforce_and(cs, resolved_left, resolved_right, span)?) Ok(enforce_and(cs, resolved_left, resolved_right, span)?)
} }
Expression::Eq(left, right, span) => { Expression::Eq(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) =
cs, self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
file_scope.clone(),
function_scope.clone(),
None,
*left,
*right,
span.clone(),
)?;
Ok(evaluate_eq(cs, resolved_left, resolved_right, span)?) Ok(evaluate_eq(cs, resolved_left, resolved_right, span)?)
} }
Expression::Ge(left, right, span) => { Expression::Ge(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) =
cs, self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
file_scope.clone(),
function_scope.clone(),
None,
*left,
*right,
span.clone(),
)?;
Ok(evaluate_ge(cs, resolved_left, resolved_right, span)?) Ok(evaluate_ge(cs, resolved_left, resolved_right, span)?)
} }
Expression::Gt(left, right, span) => { Expression::Gt(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) =
cs, self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
file_scope.clone(),
function_scope.clone(),
None,
*left,
*right,
span.clone(),
)?;
Ok(evaluate_gt(cs, resolved_left, resolved_right, span)?) Ok(evaluate_gt(cs, resolved_left, resolved_right, span)?)
} }
Expression::Le(left, right, span) => { Expression::Le(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) =
cs, self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
file_scope.clone(),
function_scope.clone(),
None,
*left,
*right,
span.clone(),
)?;
Ok(evaluate_le(cs, resolved_left, resolved_right, span)?) Ok(evaluate_le(cs, resolved_left, resolved_right, span)?)
} }
Expression::Lt(left, right, span) => { Expression::Lt(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression( let (resolved_left, resolved_right) =
cs, self.enforce_binary_expression(cs, file_scope, function_scope, None, *left, *right, span.clone())?;
file_scope.clone(),
function_scope.clone(),
None,
*left,
*right,
span.clone(),
)?;
Ok(evaluate_lt(cs, resolved_left, resolved_right, span)?) Ok(evaluate_lt(cs, resolved_left, resolved_right, span)?)
} }

View File

@ -25,6 +25,7 @@ use snarkos_models::{
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
/// Call a default core circuit function with arguments /// Call a default core circuit function with arguments
#[allow(clippy::too_many_arguments)]
pub fn enforce_core_circuit_call_expression<CS: ConstraintSystem<F>>( pub fn enforce_core_circuit_call_expression<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -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())?; let res = call_core_circuit(cs, core_circuit, argument_values, span.clone())?;
// Convert the core function returns into constrained values // Convert the core function returns into constrained values
let returns = res let returns = res.into_iter().map(ConstrainedValue::from).collect::<Vec<_>>();
.into_iter()
.map(|value| ConstrainedValue::from(value))
.collect::<Vec<_>>();
let return_value = if returns.len() == 1 { let return_value = if returns.len() == 1 {
// The function has a single return // 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)
} }
} }

View File

@ -25,6 +25,7 @@ use snarkos_models::{
}; };
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
#[allow(clippy::too_many_arguments)]
pub fn enforce_function_call_expression<CS: ConstraintSystem<F>>( pub fn enforce_function_call_expression<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -35,7 +36,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
arguments: Vec<Expression>, arguments: Vec<Expression>,
span: Span, span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> { ) -> 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) => { Expression::CircuitMemberAccess(circuit_identifier, circuit_member, span) => {
// Call a circuit function that can mutate self. // 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!( let name_unique = format!(
"function call {} {}:{}", "function call {} {}:{}",

View File

@ -37,7 +37,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
unresolved_identifier: Identifier, unresolved_identifier: Identifier,
) -> Result<ConstrainedValue<F, G>, ExpressionError> { ) -> Result<ConstrainedValue<F, G>, ExpressionError> {
// Evaluate the identifier name in the current function scope // 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 identifier_name = new_scope(file_scope, unresolved_identifier.to_string());
let mut result_value = if let Some(value) = self.get(&variable_name) { 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)); 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) Ok(result_value)
} }

View File

@ -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) { if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) {
let name_unique = format!("{} {}:{}", name, span.line, span.start); let name_unique = format!("{} {}:{}", name, span.line, span.start);
let result = Boolean::and(cs.ns(|| name_unique), &left_bool, &right_bool) 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)); return Ok(ConstrainedValue::Boolean(result));
} }

View File

@ -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) { if let (ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) = (left, right) {
let name_unique = format!("{} {}:{}", name, span.line, span.start); let name_unique = format!("{} {}:{}", name, span.line, span.start);
let result = Boolean::or(cs.ns(|| name_unique), &left_bool, &right_bool) 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)); return Ok(ConstrainedValue::Boolean(result));
} }

View File

@ -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)) Ok(ConstrainedValue::Boolean(boolean))
} }

View File

@ -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)) Ok(ConstrainedValue::Boolean(boolean))
} }

View File

@ -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)) Ok(ConstrainedValue::Boolean(boolean))
} }

View File

@ -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)) Ok(ConstrainedValue::Boolean(boolean))
} }

View File

@ -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)) Ok(ConstrainedValue::Boolean(boolean))
} }

View File

@ -25,6 +25,7 @@ use snarkos_models::{
}; };
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
#[allow(clippy::too_many_arguments)]
pub fn enforce_tuple_access<CS: ConstraintSystem<F>>( pub fn enforce_tuple_access<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -35,16 +36,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
index: usize, index: usize,
span: Span, span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> { ) -> Result<ConstrainedValue<F, G>, ExpressionError> {
let tuple = match self.enforce_operand( let tuple = match self.enforce_operand(cs, file_scope, function_scope, expected_type, *tuple, span.clone())? {
cs,
file_scope.clone(),
function_scope.clone(),
expected_type,
*tuple,
span.clone(),
)? {
ConstrainedValue::Tuple(tuple) => tuple, 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 { if index > tuple.len() - 1 {

View File

@ -38,19 +38,18 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// Check explicit tuple type dimension if given // Check explicit tuple type dimension if given
let mut expected_types = vec![]; let mut expected_types = vec![];
if expected_type.is_some() { match expected_type {
match expected_type.unwrap() { Some(Type::Tuple(ref types)) => {
Type::Tuple(ref types) => { expected_types = types.clone();
expected_types = types.clone();
}
ref type_ => {
return Err(ExpressionError::unexpected_tuple(
type_.to_string(),
format!("{:?}", tuple),
span,
));
}
} }
Some(ref type_) => {
return Err(ExpressionError::unexpected_tuple(
type_.to_string(),
format!("{:?}", tuple),
span,
));
}
None => {}
} }
let mut result = vec![]; let mut result = vec![];

View File

@ -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())?; check_arguments_length(function.input.len(), input.len(), function.span.clone())?;
// Store input values as new variables in resolved program // 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 { let (name, value) = match input_model {
InputVariable::InputKeyword(identifier) => { InputVariable::InputKeyword(identifier) => {
let input_value = self.enforce_function_input( let input_value = self.enforce_function_input(

View File

@ -54,7 +54,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
let name = input_model.identifier.name.clone(); let name = input_model.identifier.name.clone();
let input_option = input let input_option = input
.get(&name) .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( let input_value = self.allocate_main_function_input(
cs, cs,
input_model.type_, input_model.type_,

View File

@ -37,14 +37,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
span: Span, span: Span,
) -> Result<(), StatementError> { ) -> Result<(), StatementError> {
// if there are no results, continue // if there are no results, continue
if results.len() == 0 { if results.is_empty() {
return Ok(()); return Ok(());
} }
// If all indicators are none, then there are no branch conditions in the function. // If all indicators are none, then there are no branch conditions in the function.
// We simply return the last result. // 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; let result = &results[results.len() - 1].1;
*return_value = result.clone(); *return_value = result.clone();

View File

@ -21,7 +21,7 @@ use std::{collections::HashMap, env::current_dir};
/// Parses all relevant import files for a program. /// Parses all relevant import files for a program.
/// Stores compiled program structs. /// Stores compiled program structs.
#[derive(Clone)] #[derive(Clone, Default)]
pub struct ImportParser { pub struct ImportParser {
imports: HashMap<String, Program>, imports: HashMap<String, Program>,
core_packages: Vec<Package>, core_packages: Vec<Package>,
@ -29,10 +29,7 @@ pub struct ImportParser {
impl ImportParser { impl ImportParser {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
imports: HashMap::new(),
core_packages: vec![],
}
} }
pub(crate) fn insert_import(&mut self, file_name: String, program: Program) { 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()); 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) self.imports.get(file_name)
} }
@ -56,7 +53,7 @@ impl ImportParser {
let mut imports = Self::new(); let mut imports = Self::new();
// Find all imports relative to current directory // 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 // Parse each imported file
program program

View File

@ -70,14 +70,12 @@ impl ImportParser {
let entries = fs::read_dir(path) let entries = fs::read_dir(path)
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))? .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?
.into_iter()
.collect::<Result<Vec<_>, std::io::Error>>() .collect::<Result<Vec<_>, std::io::Error>>()
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?; .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?;
let matched_source_entry = entries.into_iter().find(|entry| { let matched_source_entry = entries.into_iter().find(|entry| {
entry entry
.file_name() .file_name()
.to_os_string()
.into_string() .into_string()
.unwrap() .unwrap()
.trim_end_matches(SOURCE_FILE_EXTENSION) .trim_end_matches(SOURCE_FILE_EXTENSION)
@ -90,7 +88,6 @@ impl ImportParser {
} else if imports_directory.exists() { } else if imports_directory.exists() {
let entries = fs::read_dir(imports_directory) let entries = fs::read_dir(imports_directory)
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))? .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?
.into_iter()
.collect::<Result<Vec<_>, std::io::Error>>() .collect::<Result<Vec<_>, std::io::Error>>()
.map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?; .map_err(|error| ImportError::directory_error(error, package_name.span.clone(), error_path.clone()))?;

View File

@ -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()))?; .map_err(|error| ImportError::directory_error(error, span.clone(), entry.path()))?;
let file_name = entry let file_name = entry
.file_name() .file_name()
.to_os_string()
.into_string() .into_string()
.map_err(|_| ImportError::convert_os_string(span.clone()))?; .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() { if file_type.is_dir() {
file_path.push(LIBRARY_FILE); file_path.push(LIBRARY_FILE);
@ -62,7 +61,7 @@ impl ImportParser {
.extension() .extension()
.map_or(false, |ext| ext.eq(&OsString::from(FILE_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); package_path.push(LIBRARY_FILE);
let is_package = is_dir && package_path.exists(); let is_package = is_dir && package_path.exists();
@ -93,7 +92,7 @@ impl ImportParser {
Ok(()) Ok(())
} else { } else {
// importing * from a directory or non-leo file in `package/src/` is illegal // 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()))
} }
} }

View File

@ -33,7 +33,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
.find(|package| import.package.eq(package)); .find(|package| import.package.eq(package));
if let Some(package) = core_dependency { if let Some(package) = core_dependency {
self.store_core_package(scope.clone(), package.clone())?; self.store_core_package(scope, package.clone())?;
return Ok(()); return Ok(());
} }
@ -45,7 +45,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// Find imported program // Find imported program
let program = imported_programs let program = imported_programs
.get_import(&package) .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 // Parse imported program
self.store_definitions(program.clone(), imported_programs)?; self.store_definitions(program.clone(), imported_programs)?;

View File

@ -59,7 +59,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
let value = match matched_circuit { let value = match matched_circuit {
Some((_circuit_name, circuit)) => ConstrainedValue::Import( Some((_circuit_name, circuit)) => ConstrainedValue::Import(
program_name.clone(), program_name,
Box::new(ConstrainedValue::CircuitDefinition(circuit.clone())), Box::new(ConstrainedValue::CircuitDefinition(circuit.clone())),
), ),
None => { None => {
@ -71,7 +71,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
match matched_function { match matched_function {
Some((_function_name, function)) => ConstrainedValue::Import( Some((_function_name, function)) => ConstrainedValue::Import(
program_name.clone(), program_name,
Box::new(ConstrainedValue::Function(None, function.clone())), Box::new(ConstrainedValue::Function(None, function.clone())),
), ),
None => return Err(ImportError::unknown_symbol(symbol.to_owned(), program_name)), 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 // 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()); let name = new_scope(scope, id.to_string());
// store imported circuit under imported name // store imported circuit under imported name

View File

@ -16,6 +16,8 @@
//! Module containing structs and types that make up a Leo program. //! Module containing structs and types that make up a Leo program.
#![allow(clippy::module_inception)]
#[macro_use] #[macro_use]
extern crate thiserror; extern crate thiserror;

View File

@ -27,30 +27,36 @@ pub struct ConstrainedProgram<F: Field + PrimeField, G: GroupType<F>> {
pub identifiers: HashMap<String, ConstrainedValue<F, G>>, 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 { pub fn new_scope(outer: String, inner: String) -> String {
format!("{}_{}", outer, inner) 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) current_scope.ends_with(desired_scope)
} }
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self::default()
identifiers: HashMap::new(),
}
} }
pub(crate) fn store(&mut self, name: String, value: ConstrainedValue<F, G>) { pub(crate) fn store(&mut self, name: String, value: ConstrainedValue<F, G>) {
self.identifiers.insert(name, value); 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) 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) self.identifiers.get_mut(name)
} }
} }

View File

@ -28,6 +28,7 @@ use snarkos_models::{
}; };
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
#[allow(clippy::too_many_arguments)]
pub fn assign_array<CS: ConstraintSystem<F>>( pub fn assign_array<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, 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 // Resolve index so we know if we are assigning to a single value or a range of values
match range_or_expression { match range_or_expression {
RangeOrExpression::Expression(index) => { 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 // Modify the single value of the array in place
match self.get_mutable_assignee(name, span.clone())? { match self.get_mutable_assignee(name, span.clone())? {
@ -75,13 +76,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
None => 0usize, None => 0usize,
}; };
let to_index_option = match to { let to_index_option = match to {
Some(integer) => Some(self.enforce_index( Some(integer) => Some(self.enforce_index(cs, file_scope, function_scope, integer, span.clone())?),
cs,
file_scope.clone(),
function_scope.clone(),
integer,
span.clone(),
)?),
None => None, None => None,
}; };

View File

@ -35,6 +35,7 @@ use snarkos_models::{
}; };
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
#[allow(clippy::too_many_arguments)]
pub fn enforce_assign_statement<CS: ConstraintSystem<F>>( pub fn enforce_assign_statement<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -57,7 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
match assignee { match assignee {
Assignee::Identifier(_identifier) => { Assignee::Identifier(_identifier) => {
let condition = indicator.unwrap_or(Boolean::Constant(true)); 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())?; 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, function_scope,
indicator, indicator,
variable_name, variable_name,
range_or_expression, *range_or_expression,
new_value, new_value,
span, span,
), ),

View File

@ -43,7 +43,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
match self.get_mutable_assignee(circuit_name, span.clone())? { match self.get_mutable_assignee(circuit_name, span.clone())? {
ConstrainedValue::CircuitExpression(_variable, members) => { ConstrainedValue::CircuitExpression(_variable, members) => {
// Modify the circuit variable in place // 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 { match matched_variable {
Some(member) => match &member.1 { 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(); 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 // Throw an error if we try to mutate an immutable circuit variable

View File

@ -16,7 +16,7 @@
//! Enforces a branch of a conditional or iteration statement in a compiled Leo program. //! 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 leo_typed::{Statement, Type};
use snarkos_models::{ use snarkos_models::{
@ -33,7 +33,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
indicator: Option<Boolean>, indicator: Option<Boolean>,
statements: Vec<Statement>, statements: Vec<Statement>,
return_type: Option<Type>, return_type: Option<Type>,
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> { ) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
let mut results = vec![]; let mut results = vec![];
// Evaluate statements. Only allow a single return argument to be returned. // Evaluate statements. Only allow a single return argument to be returned.
for statement in statements.iter() { for statement in statements.iter() {
@ -41,7 +41,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
cs, cs,
file_scope.clone(), file_scope.clone(),
function_scope.clone(), function_scope.clone(),
indicator.clone(), indicator,
statement.clone(), statement.clone(),
return_type.clone(), return_type.clone(),
"".to_owned(), "".to_owned(),

View File

@ -16,7 +16,14 @@
//! Methods to enforce constraints on statements in a compiled Leo program. //! 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 leo_typed::{ConditionalNestedOrEndStatement, ConditionalStatement, Span, Type};
use snarkos_models::{ use snarkos_models::{
@ -28,7 +35,7 @@ fn indicator_to_string(indicator: &Boolean) -> String {
indicator indicator
.get_value() .get_value()
.map(|b| b.to_string()) .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> { 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. /// 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. /// 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. /// 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>>( pub fn enforce_conditional_statement<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -45,7 +53,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
statement: ConditionalStatement, statement: ConditionalStatement,
return_type: Option<Type>, return_type: Option<Type>,
span: Span, span: Span,
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> { ) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
let statement_string = statement.to_string(); let statement_string = statement.to_string();
// Inherit the indicator from a previous conditional statement or assume that we are the outer parent // Inherit the indicator from a previous conditional statement or assume that we are the outer parent

View File

@ -56,15 +56,15 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
) -> Result<Vec<ConstrainedValue<F, G>>, StatementError> { ) -> Result<Vec<ConstrainedValue<F, G>>, StatementError> {
let types = match type_ { let types = match type_ {
Some(Type::Tuple(types)) => types, 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![], None => vec![],
}; };
let implicit_types = types.is_empty(); let implicit_types = types.is_empty();
let mut expected_types = vec![]; let mut expected_types = vec![];
for i in 0..expressions.len() { for ty in types.iter().take(expressions.len()) {
let expected_type = if implicit_types { None } else { Some(types[i].clone()) }; let expected_type = if implicit_types { None } else { Some(ty.clone()) };
expected_types.push(expected_type); expected_types.push(expected_type);
} }
@ -86,6 +86,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Ok(values) Ok(values)
} }
#[allow(clippy::too_many_arguments)]
fn enforce_tuple_definition<CS: ConstraintSystem<F>>( fn enforce_tuple_definition<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -135,6 +136,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
Ok(()) Ok(())
} }
#[allow(clippy::too_many_arguments)]
pub fn enforce_definition_statement<CS: ConstraintSystem<F>>( pub fn enforce_definition_statement<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -157,7 +159,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
let variable = variables.names[0].clone(); let variable = variables.names[0].clone();
let expression = self.enforce_expression( let expression = self.enforce_expression(
cs, cs,
file_scope.clone(), file_scope,
function_scope.clone(), function_scope.clone(),
variables.type_, variables.type_,
expressions[0].clone(), expressions[0].clone(),
@ -181,14 +183,14 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
let values = match self.enforce_expression( let values = match self.enforce_expression(
cs, cs,
file_scope.clone(), file_scope,
function_scope.clone(), function_scope.clone(),
variables.type_.clone(), variables.type_.clone(),
expressions[0].clone(), expressions[0].clone(),
)? { )? {
// ConstrainedValue::Return(values) => values, // ConstrainedValue::Return(values) => values,
ConstrainedValue::Tuple(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) self.enforce_multiple_definition(cs, function_scope, is_constant, variables, values, span)

View File

@ -17,12 +17,13 @@
//! Enforces an iteration statement in a compiled Leo program. //! Enforces an iteration statement in a compiled Leo program.
use crate::{ use crate::{
errors::StatementError,
new_scope, new_scope,
program::ConstrainedProgram, program::ConstrainedProgram,
value::ConstrainedValue, value::ConstrainedValue,
GroupType, GroupType,
IndicatorAndConstrainedValue,
Integer, Integer,
StatementResult,
}; };
use leo_typed::{Expression, Identifier, Span, Statement, Type}; 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> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
#[allow(clippy::too_many_arguments)]
pub fn enforce_iteration_statement<CS: ConstraintSystem<F>>( pub fn enforce_iteration_statement<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -47,7 +49,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
statements: Vec<Statement>, statements: Vec<Statement>,
return_type: Option<Type>, return_type: Option<Type>,
span: Span, span: Span,
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> { ) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
let mut results = vec![]; let mut results = vec![];
let from = self.enforce_index(cs, file_scope.clone(), function_scope.clone(), start, span.clone())?; let from = self.enforce_index(cs, file_scope.clone(), function_scope.clone(), start, span.clone())?;

View File

@ -28,9 +28,7 @@ fn check_return_type(expected: Option<Type>, actual: Type, span: Span) -> Result
match expected { match expected {
Some(expected) => { Some(expected) => {
if expected.ne(&actual) { if expected.ne(&actual) {
if expected.is_self() && actual.is_circuit() { if (expected.is_self() && actual.is_circuit()) || expected.match_array_types(&actual) {
return Ok(());
} else if expected.match_array_types(&actual) {
return Ok(()); return Ok(());
} else { } else {
return Err(StatementError::arguments_type(&expected, &actual, span)); 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( let result = self.enforce_operand(
cs, cs,
file_scope.clone(), file_scope,
function_scope.clone(), function_scope,
return_type.clone(), return_type.clone(),
expression, expression,
span.clone(), span.clone(),

View File

@ -24,12 +24,16 @@ use snarkos_models::{
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean}, 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> { impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
/// Enforce a program statement. /// Enforce a program statement.
/// Returns a Vector of (indicator, value) tuples. /// Returns a Vector of (indicator, value) tuples.
/// Each evaluated statement may execute of one or more statements that may return early. /// 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 indicate which of these return values to take we conditionally select the value according
/// to the `indicator` bit that evaluates to true. /// to the `indicator` bit that evaluates to true.
#[allow(clippy::too_many_arguments)]
pub fn enforce_statement<CS: ConstraintSystem<F>>( pub fn enforce_statement<CS: ConstraintSystem<F>>(
&mut self, &mut self,
cs: &mut CS, cs: &mut CS,
@ -39,7 +43,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
statement: Statement, statement: Statement,
return_type: Option<Type>, return_type: Option<Type>,
declared_circuit_reference: String, declared_circuit_reference: String,
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> { ) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
let mut results = vec![]; let mut results = vec![];
match statement { match statement {
@ -70,7 +74,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
declared_circuit_reference, declared_circuit_reference,
indicator, indicator,
variable, variable,
expression, *expression,
span, span,
)?; )?;
} }
@ -94,8 +98,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
function_scope, function_scope,
indicator, indicator,
index, index,
start, *start,
stop, *stop,
statements, statements,
return_type, return_type,
span, span,

View File

@ -153,7 +153,7 @@ impl<F: Field + PrimeField> AllocGadget<String, F> for Address {
impl<F: Field + PrimeField> EvaluateEqGadget<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> { fn evaluate_equal<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
if self.is_constant() && other.is_constant() { if self.is_constant() && other.is_constant() {
return Ok(Boolean::Constant(self.eq(other))); Ok(Boolean::Constant(self.eq(other)))
} else { } else {
let mut result = Boolean::constant(true); let mut result = Boolean::constant(true);

View File

@ -79,7 +79,7 @@ impl<F: Field + PrimeField> FieldType<F> {
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => { (FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
let result = self_value let result = self_value
.add(cs, other_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)) 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( | (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
allocated_value allocated_value
.add_constant(cs, constant_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)) => { (FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
let result = self_value let result = self_value
.sub(cs, other_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)) 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( | (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
allocated_value allocated_value
.sub_constant(cs, constant_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)) => { (FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
let result = self_value let result = self_value
.mul(cs, other_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)) 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( | (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
allocated_value allocated_value
.mul_by_constant(cs, constant_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) => { FieldType::Constant(constant) => {
let constant_inverse = constant let constant_inverse = constant
.inverse() .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::Constant(constant_inverse)
} }
FieldType::Allocated(allocated) => { FieldType::Allocated(allocated) => {
let allocated_inverse = allocated let allocated_inverse = allocated
.inverse(&mut cs) .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) FieldType::Allocated(allocated_inverse)
} }

View File

@ -48,7 +48,7 @@ use std::{
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum EdwardsGroupType { pub enum EdwardsGroupType {
Constant(EdwardsAffine), Constant(EdwardsAffine),
Allocated(EdwardsBlsGadget), Allocated(Box<EdwardsBlsGadget>),
} }
impl GroupType<Fq> for EdwardsGroupType { 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> { 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))) 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)) .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) let result = <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::negate(group, cs)
.map_err(|e| GroupError::negate_operation(e, span))?; .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, cs,
other_value, 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::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => { | (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
Ok(EdwardsGroupType::Allocated( Ok(EdwardsGroupType::Allocated(Box::new(
allocated_value allocated_value
.add_constant(cs, constant_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, cs,
other_value, 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::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => { | (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
Ok(EdwardsGroupType::Allocated( Ok(EdwardsGroupType::Allocated(Box::new(
allocated_value allocated_value
.sub_constant(cs, constant_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> { pub fn edwards_affine_from_single(number: String, span: Span) -> Result<EdwardsAffine, GroupError> {
if number.eq("0") { if number.eq("0") {
return Ok(EdwardsAffine::zero()); Ok(EdwardsAffine::zero())
} else { } else {
let one = edwards_affine_one(); let one = edwards_affine_one();
let number_value = Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span))?; let number_value = Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span))?;
let result: EdwardsAffine = one.mul(&number_value); 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))?; let x = Fq::from_str(&x_string).map_err(|_| GroupError::x_invalid(x_string, x_span))?;
match greatest { match greatest {
// Sign provided // 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 // Sign inferred
None => { None => {
// Attempt to recover with a sign_low bit. // 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); return Ok(element);
} }
@ -230,11 +232,13 @@ impl EdwardsGroupType {
match greatest { match greatest {
// Sign provided // 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 // Sign inferred
None => { None => {
// Attempt to recover with a sign_low bit. // 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); return Ok(element);
} }
@ -294,12 +298,8 @@ impl EdwardsGroupType {
let x_value = allocated.x.get_value(); let x_value = allocated.x.get_value();
let y_value = allocated.y.get_value(); let y_value = allocated.y.get_value();
let x_allocated = FpGadget::alloc(cs.ns(|| format!("x")), || { let x_allocated = FpGadget::alloc(cs.ns(|| "x"), || x_value.ok_or(SynthesisError::AssignmentMissing))?;
x_value.ok_or(SynthesisError::AssignmentMissing) let y_allocated = FpGadget::alloc(cs.ns(|| "y"), || y_value.ok_or(SynthesisError::AssignmentMissing))?;
})?;
let y_allocated = FpGadget::alloc(cs.ns(|| format!("y")), || {
y_value.ok_or(SynthesisError::AssignmentMissing)
})?;
Ok(EdwardsBlsGadget::new(x_allocated, y_allocated)) Ok(EdwardsBlsGadget::new(x_allocated, y_allocated))
} }
@ -316,7 +316,7 @@ impl AllocGadget<GroupValue, Fq> for EdwardsGroupType {
Self::alloc_helper(value_gen) 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>>( 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) 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 second_gadget = second.allocated(cs.ns(|| "second"))?;
let result = EdwardsBlsGadget::conditionally_select(cs, cond, &first_gadget, &second_gadget)?; let result = EdwardsBlsGadget::conditionally_select(cs, cond, &first_gadget, &second_gadget)?;
Ok(EdwardsGroupType::Allocated(result)) Ok(EdwardsGroupType::Allocated(Box::new(result)))
} }
} }

View File

@ -157,7 +157,7 @@ impl Integer {
let unsigned_integer = self; let unsigned_integer = self;
let value_option: Option<String> = match_unsigned_integer!(unsigned_integer => unsigned_integer.get_value()); 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 let value_usize = value
.parse::<usize>() .parse::<usize>()
.map_err(|_| IntegerError::invalid_integer(value, span))?; .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))); 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>>( 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)); 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>>( 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)); 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>>( 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)); 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>>( 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)); 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>>( 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)); 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))
} }
} }

View File

@ -110,7 +110,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
// Data type wrappers // Data type wrappers
ConstrainedValue::Array(array) => { 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()]; let mut dimensions = vec![array.len()];
// Nested array type // Nested array type
@ -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 this is a circuit function, evaluate inside the circuit scope
if let Some(identifier) = circuit_identifier { if let Some(identifier) = circuit_identifier {
// avoid creating recursive scope // avoid creating recursive scope
if !is_in_scope(&scope, &identifier.name.to_string()) { if !is_in_scope(&scope, &identifier.name) {
outer_scope = new_scope(scope, identifier.name.to_string()); 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), 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 { match self {
ConstrainedValue::CircuitDefinition(circuit) => Ok(circuit), ConstrainedValue::CircuitDefinition(circuit) => Ok(circuit),
ConstrainedValue::Import(_import_scope, circuit) => circuit.extract_circuit(span), 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) => { ConstrainedValue::Boolean(boolean) => {
let option = boolean.get_value(); 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)?; *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) => { ConstrainedValue::Integer(integer) => {
let integer_type = integer.get_type(); let integer_type = integer.get_type();
let option = integer.get_value(); 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)?; *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 value
.get_value() .get_value()
.map(|v| v.to_string()) .map(|v| v.to_string())
.unwrap_or(format!("[allocated]")) .unwrap_or_else(|| "[allocated]".to_string())
), ),
ConstrainedValue::Field(ref value) => write!(f, "{:?}", value), ConstrainedValue::Field(ref value) => write!(f, "{:?}", value),
ConstrainedValue::Group(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) num_1.conditional_enforce_equal(cs, num_2, condition)
} }
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => { (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)?; left.conditional_enforce_equal(cs.ns(|| format!("array[{}]", i)), right, condition)?;
} }
Ok(()) Ok(())
} }
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Tuple(tuple_2)) => { (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)?; left.conditional_enforce_equal(cs.ns(|| format!("tuple index {}", i)), right, condition)?;
} }
Ok(()) Ok(())
} }
(_, _) => return Err(SynthesisError::Unsatisfiable), (_, _) => Err(SynthesisError::Unsatisfiable),
} }
} }
@ -448,7 +450,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => { (ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
let mut array = vec![]; let mut array = vec![];
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( array.push(Self::conditionally_select(
cs.ns(|| format!("array[{}]", i)), cs.ns(|| format!("array[{}]", i)),
cond, cond,
@ -462,7 +464,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Array(tuple_2)) => { (ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Array(tuple_2)) => {
let mut array = vec![]; let mut array = vec![];
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( array.push(Self::conditionally_select(
cs.ns(|| format!("tuple index {}", i)), cs.ns(|| format!("tuple index {}", i)),
cond, cond,
@ -484,7 +486,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
) => { ) => {
let mut members = vec![]; let mut members = vec![];
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( members.push(ConstrainedCircuitMember::conditionally_select(
cs.ns(|| format!("circuit member[{}]", i)), cs.ns(|| format!("circuit member[{}]", i)),
cond, 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::I64(i64) => ConstrainedValue::Integer(Integer::I64(i64)),
Value::I128(i128) => ConstrainedValue::Integer(Integer::I128(i128)), Value::I128(i128) => ConstrainedValue::Integer(Integer::I128(i128)),
Value::Array(array) => ConstrainedValue::Array( Value::Array(array) => ConstrainedValue::Array(array.into_iter().map(ConstrainedValue::from).collect()),
array Value::Tuple(tuple) => ConstrainedValue::Tuple(tuple.into_iter().map(ConstrainedValue::from).collect()),
.into_iter()
.map(|element| ConstrainedValue::from(element))
.collect(),
),
Value::Tuple(tuple) => ConstrainedValue::Tuple(
tuple
.into_iter()
.map(|element| ConstrainedValue::from(element))
.collect(),
),
} }
} }
} }

View File

@ -35,7 +35,7 @@ impl CorePackageError {
} }
pub fn core_package_star(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }

View File

@ -48,7 +48,7 @@ impl CorePackageListError {
} }
pub fn core_package_star(span: Span) -> Self { 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) Self::new_from_span(message, span)
} }

View File

@ -104,7 +104,7 @@ impl CoreCircuit for Blake2sCircuit {
), ),
span.clone(), span.clone(),
)], )],
span: span.clone(), span,
}, },
)], )],
} }
@ -141,7 +141,7 @@ impl CoreCircuit for Blake2sCircuit {
.to_bytes(cs) .to_bytes(cs)
.map_err(|e| CoreCircuitError::cannot_enforce("Vec<UInt8> ToBytes".to_owned(), e, span.clone()))?; .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 // Return one array digest value
Ok(vec![Value::Array(return_value)]) Ok(vec![Value::Array(return_value)])

View File

@ -71,7 +71,7 @@ impl CorePackage {
let span = circuit.span.clone(); let span = circuit.span.clone();
// take the alias if it is present // 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 name = id.name.clone();
let circuit = if self.unstable { let circuit = if self.unstable {
@ -87,9 +87,7 @@ impl CorePackage {
} }
} else { } else {
// match core circuit // match core circuit
match circuit_name { return Err(CorePackageError::undefined_core_circuit(circuit_name.to_string(), span));
name => return Err(CorePackageError::undefined_core_circuit(name.to_string(), span)),
}
}; };
circuit_structs.push(name, circuit) circuit_structs.push(name, circuit)

View File

@ -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) write!(f, "{}", string)
} }

View File

@ -30,7 +30,6 @@ where
{ {
type ErrorType; type ErrorType;
#[must_use]
fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>; fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
} }

View File

@ -23,6 +23,5 @@ where
{ {
type ErrorType; type ErrorType;
#[must_use]
fn div<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>; fn div<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
} }

View File

@ -23,6 +23,5 @@ where
{ {
type ErrorType; type ErrorType;
#[must_use]
fn mul<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>; fn mul<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
} }

View File

@ -29,7 +29,6 @@ where
{ {
type ErrorType; type ErrorType;
#[must_use]
fn neg<CS: ConstraintSystem<F>>(&self, cs: CS) -> Result<Self, Self::ErrorType>; 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)]; let mut one = vec![Boolean::constant(true)];
one.append(&mut vec![Boolean::Constant(false); self.len() - 1]); 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 let _carry = bits.pop(); // we already accounted for overflow above
Ok(bits) Ok(bits)

View File

@ -23,6 +23,5 @@ where
{ {
type ErrorType; type ErrorType;
#[must_use]
fn pow<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>; fn pow<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
} }

View File

@ -23,6 +23,5 @@ where
{ {
type ErrorType; type ErrorType;
#[must_use]
fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>; fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, Self::ErrorType>;
} }

View File

@ -44,12 +44,12 @@ impl<'a, F: Field> FullAdder<'a, F> for Boolean {
b: &'a Self, b: &'a Self,
carry: &'a Self, carry: &'a Self,
) -> Result<(Self, Self), SynthesisError> { ) -> Result<(Self, Self), SynthesisError> {
let a_x_b = Boolean::xor(cs.ns(|| format!("a XOR b")), a, b)?; let a_x_b = Boolean::xor(cs.ns(|| "a XOR b"), a, b)?;
let sum = Boolean::xor(cs.ns(|| format!("adder sum")), &a_x_b, carry)?; 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 c1 = Boolean::and(cs.ns(|| "a AND b"), a, b)?;
let c2 = Boolean::and(cs.ns(|| format!("carry AND (a XOR b)")), carry, &a_x_b)?; let c2 = Boolean::and(cs.ns(|| "carry AND (a XOR b)"), carry, &a_x_b)?;
let carry = Boolean::or(cs.ns(|| format!("c1 OR c2")), &c1, &c2)?; let carry = Boolean::or(cs.ns(|| "c1 OR c2"), &c1, &c2)?;
Ok((sum, carry)) Ok((sum, carry))
} }

View File

@ -27,7 +27,6 @@ pub trait RippleCarryAdder<F: Field, Rhs = Self>
where where
Self: std::marker::Sized, Self: std::marker::Sized,
{ {
#[must_use]
fn add_bits<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Vec<Boolean>, SynthesisError>; fn add_bits<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Vec<Boolean>, SynthesisError>;
} }

View File

@ -30,7 +30,7 @@ impl SignExtend for Boolean {
fn sign_extend(bits: &[Boolean], length: usize) -> Vec<Boolean> { fn sign_extend(bits: &[Boolean], length: usize) -> Vec<Boolean> {
let msb = bits.last().expect("empty bit list"); let msb = bits.last().expect("empty bit list");
let bits_needed = length - bits.len(); 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); let mut result = Vec::from(bits);
result.append(&mut extension); result.append(&mut extension);

View File

@ -87,7 +87,7 @@ macro_rules! add_int_impl {
all_constants = false; all_constants = false;
// Add the coeff * bit_gadget // Add the coeff * bit_gadget
lc = lc + (coeff, bit.get_variable()); lc += (coeff, bit.get_variable());
} }
Boolean::Not(ref bit) => { Boolean::Not(ref bit) => {
all_constants = false; all_constants = false;
@ -97,7 +97,7 @@ macro_rules! add_int_impl {
} }
Boolean::Constant(bit) => { Boolean::Constant(bit) => {
if bit { if bit {
lc = lc + (coeff, CS::one()); lc += (coeff, CS::one());
} }
} }
} }

View File

@ -206,13 +206,13 @@ macro_rules! div_int_impl {
&r &r
)?; )?;
index = index - 1; index -= 1;
let mut q_new = q.clone(); let mut q_new = q.clone();
q_new.bits[index] = true_bit.clone(); q_new.bits[index] = true_bit.clone();
q_new.value = Some(q_new.value.unwrap() + bit_value); q_new.value = Some(q_new.value.unwrap() + bit_value);
bit_value = (bit_value >> 1); bit_value >>= 1;
q = Self::conditionally_select( q = Self::conditionally_select(
&mut cs.ns(|| format!("set_bit_or_same_{}", i)), &mut cs.ns(|| format!("set_bit_or_same_{}", i)),

View File

@ -146,7 +146,7 @@ macro_rules! mul_int_impl {
all_constants = false; all_constants = false;
// Add the coeff * bit_gadget // Add the coeff * bit_gadget
lc = lc + (coeff, bit.get_variable()); lc += (coeff, bit.get_variable());
} }
Boolean::Not(ref bit) => { Boolean::Not(ref bit) => {
all_constants = false; all_constants = false;
@ -156,7 +156,7 @@ macro_rules! mul_int_impl {
} }
Boolean::Constant(bit) => { Boolean::Constant(bit) => {
if bit { if bit {
lc = lc + (coeff, CS::one()); lc += (coeff, CS::one());
} }
} }
} }

View File

@ -53,20 +53,17 @@ pub enum InputParserError {
impl InputParserError { impl InputParserError {
pub fn set_path(&mut self, path: PathBuf) { pub fn set_path(&mut self, path: PathBuf) {
match self { if let InputParserError::SyntaxError(error) = self {
InputParserError::SyntaxError(error) => { let new_error: Error<Rule> = match error {
let new_error: Error<Rule> = match error { InputSyntaxError::Error(error) => {
InputSyntaxError::Error(error) => { let new_error = error.clone();
let new_error = error.clone(); new_error.with_path(path.to_str().unwrap())
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);
}
_ => {}
} }
} }

View File

@ -35,7 +35,7 @@ pub trait CLI {
.iter() .iter()
.map(|a| { .map(|a| {
let mut args = Arg::with_name(a.0).help(a.1).required(a.3).index(a.4); 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 = args.possible_values(a.2);
} }
args args
@ -47,7 +47,7 @@ pub trait CLI {
.collect::<Vec<Arg<'static, 'static>>>(); .collect::<Vec<Arg<'static, 'static>>>();
let options = &Self::OPTIONS let options = &Self::OPTIONS
.iter() .iter()
.map(|a| match a.2.len() > 0 { .map(|a| match !a.2.is_empty() {
true => Arg::from_usage(a.0) true => Arg::from_usage(a.0)
.conflicts_with_all(a.1) .conflicts_with_all(a.1)
.possible_values(a.2) .possible_values(a.2)
@ -64,7 +64,7 @@ pub trait CLI {
&s.2.iter() &s.2.iter()
.map(|a| { .map(|a| {
let mut args = Arg::with_name(a.0).help(a.1).required(a.3).index(a.4); 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 = args.possible_values(a.2);
} }
args args
@ -78,7 +78,7 @@ pub trait CLI {
) )
.args( .args(
&s.4.iter() &s.4.iter()
.map(|a| match a.2.len() > 0 { .map(|a| match !a.2.is_empty() {
true => Arg::from_usage(a.0) true => Arg::from_usage(a.0)
.conflicts_with_all(a.1) .conflicts_with_all(a.1)
.possible_values(a.2) .possible_values(a.2)

View File

@ -167,7 +167,7 @@ impl CLI for AddCommand {
let mut file_path = path.clone(); let mut file_path = path.clone();
file_path.push(file_name); file_path.push(file_name);
if file_name.ends_with("/") { if file_name.ends_with('/') {
create_dir_all(file_path)?; create_dir_all(file_path)?;
} else { } else {
if let Some(parent_directory) = path.parent() { if let Some(parent_directory) = path.parent() {

View File

@ -93,7 +93,7 @@ impl CLI for BuildCommand {
// Compile the library file but do not output // Compile the library file but do not output
let _program = Compiler::<Fq, EdwardsGroupType>::parse_program_without_input( let _program = Compiler::<Fq, EdwardsGroupType>::parse_program_without_input(
package_name.clone(), package_name.clone(),
lib_file_path.clone(), lib_file_path,
output_directory.clone(), output_directory.clone(),
)?; )?;
tracing::info!("Complete"); tracing::info!("Complete");
@ -121,7 +121,7 @@ impl CLI for BuildCommand {
// Load the program at `main_file_path` // Load the program at `main_file_path`
let program = Compiler::<Fq, EdwardsGroupType>::parse_program_with_input( let program = Compiler::<Fq, EdwardsGroupType>::parse_program_with_input(
package_name.clone(), package_name.clone(),
main_file_path.clone(), main_file_path,
output_directory, output_directory,
&input_string, &input_string,
input_path, input_path,

View File

@ -65,7 +65,7 @@ impl CLI for DeployCommand {
Ok(()) Ok(())
} }
None => { 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(SOURCE_DIRECTORY_NAME);
main_file_path.push(MAIN_FILENAME); main_file_path.push(MAIN_FILENAME);

View File

@ -65,7 +65,7 @@ impl CLI for LintCommand {
Ok(()) Ok(())
} }
None => { 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(SOURCE_DIRECTORY_NAME);
main_file_path.push(MAIN_FILENAME); main_file_path.push(MAIN_FILENAME);

View File

@ -146,7 +146,7 @@ impl CLI for SetupCommand {
Ok((program, proving_key, prepared_verifying_key)) Ok((program, proving_key, prepared_verifying_key))
} }
None => { 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(SOURCE_DIRECTORY_NAME);
main_file_path.push(MAIN_FILENAME); main_file_path.push(MAIN_FILENAME);

View File

@ -60,7 +60,7 @@ impl CLI for TestCommand {
let package_name = manifest.get_package_name(); let package_name = manifest.get_package_name();
// Sanitize the package path to the root directory // Sanitize the package path to the root directory
let mut package_path = path.clone(); let mut package_path = path;
if package_path.is_file() { if package_path.is_file() {
package_path.pop(); package_path.pop();
} }
@ -92,17 +92,14 @@ impl CLI for TestCommand {
let start = Instant::now(); let start = Instant::now();
// Parse the current main program file // Parse the current main program file
let program = Compiler::<Fq, EdwardsGroupType>::parse_program_without_input( let program =
package_name.clone(), Compiler::<Fq, EdwardsGroupType>::parse_program_without_input(package_name, file_path, output_directory)?;
file_path.clone(),
output_directory,
)?;
// Parse all inputs as input pairs // Parse all inputs as input pairs
let pairs = InputPairs::try_from(&package_path)?; let pairs = InputPairs::try_from(&package_path)?;
// Run tests // Run tests
let temporary_program = program.clone(); let temporary_program = program;
let (passed, failed) = temporary_program.compile_test_constraints(pairs)?; let (passed, failed) = temporary_program.compile_test_constraints(pairs)?;
// Drop "Test" context for console logging // Drop "Test" context for console logging

View File

@ -52,14 +52,11 @@ impl CLI for UpdateCommand {
]; ];
fn parse(arguments: &clap::ArgMatches) -> Result<Self::Options, crate::errors::CLIError> { fn parse(arguments: &clap::ArgMatches) -> Result<Self::Options, crate::errors::CLIError> {
match arguments.subcommand() { if let ("automatic", Some(arguments)) = arguments.subcommand() {
("automatic", Some(arguments)) => { // Run the `automatic` subcommand
// Run the `automatic` subcommand let options = UpdateAutomatic::parse(arguments)?;
let options = UpdateAutomatic::parse(arguments)?; let _output = UpdateAutomatic::output(options)?;
let _output = UpdateAutomatic::output(options)?; return Ok(None);
return Ok(None);
}
_ => {}
}; };
let show_all_versions = arguments.is_present("list"); let show_all_versions = arguments.is_present("list");

View File

@ -57,8 +57,7 @@ impl CLI for WatchCommand {
match rx.recv() { match rx.recv() {
// See changes on the write event // See changes on the write event
Ok(DebouncedEvent::Write(_write)) => { Ok(DebouncedEvent::Write(_write)) => {
let options = (); match BuildCommand::output(()) {
match BuildCommand::output(options) {
Ok(_output) => { Ok(_output) => {
tracing::info!("Built successfully"); tracing::info!("Built successfully");
} }

View File

@ -91,7 +91,7 @@ impl Config {
let toml_string = match fs::read_to_string(&config_path) { let toml_string = match fs::read_to_string(&config_path) {
Ok(mut toml) => { Ok(mut toml) => {
// If the config is using an incorrect format, rewrite it. // If the config is using an incorrect format, rewrite it.
if let Err(_) = toml::from_str::<Config>(&toml) { if toml::from_str::<Config>(&toml).is_err() {
let default_config_string = toml::to_string(&Config::default())?; let default_config_string = toml::to_string(&Config::default())?;
fs::write(&config_path, default_config_string.clone())?; fs::write(&config_path, default_config_string.clone())?;
toml = default_config_string; toml = default_config_string;
@ -131,7 +131,7 @@ pub fn write_token(token: &str) -> Result<(), io::Error> {
let config_dir = LEO_CONFIG_DIRECTORY.clone(); let config_dir = LEO_CONFIG_DIRECTORY.clone();
// Create Leo config directory if it not exists // Create Leo config directory if it not exists
if !Path::new(&config_dir.to_path_buf()).exists() { if !Path::new(&config_dir).exists() {
create_dir_all(&config_dir)?; create_dir_all(&config_dir)?;
} }

View File

@ -57,7 +57,7 @@ impl<E: PairingEngine> From<CircuitSynthesizer<E>> for SerializedCircuit {
let num_constraints = synthesizer.num_constraints(); let num_constraints = synthesizer.num_constraints();
// Serialize assignments // Serialize assignments
fn get_serialized_assignments<E: PairingEngine>(assignments: &Vec<E::Fr>) -> Vec<SerializedField> { fn get_serialized_assignments<E: PairingEngine>(assignments: &[E::Fr]) -> Vec<SerializedField> {
let mut serialized = vec![]; let mut serialized = vec![];
for assignment in assignments { for assignment in assignments {
@ -74,7 +74,7 @@ impl<E: PairingEngine> From<CircuitSynthesizer<E>> for SerializedCircuit {
// Serialize constraints // Serialize constraints
fn get_serialized_constraints<E: PairingEngine>( fn get_serialized_constraints<E: PairingEngine>(
constraints: &Vec<(E::Fr, Index)>, constraints: &[(E::Fr, Index)],
) -> Vec<(SerializedField, SerializedIndex)> { ) -> Vec<(SerializedField, SerializedIndex)> {
let mut serialized = vec![]; let mut serialized = vec![];
@ -128,7 +128,7 @@ impl TryFrom<SerializedCircuit> for CircuitSynthesizer<Bls12_377> {
fn try_from(serialized: SerializedCircuit) -> Result<CircuitSynthesizer<Bls12_377>, Self::Error> { fn try_from(serialized: SerializedCircuit) -> Result<CircuitSynthesizer<Bls12_377>, Self::Error> {
// Deserialize assignments // Deserialize assignments
fn get_deserialized_assignments( fn get_deserialized_assignments(
assignments: &Vec<SerializedField>, assignments: &[SerializedField],
) -> Result<Vec<<Bls12_377 as PairingEngine>::Fr>, FieldError> { ) -> Result<Vec<<Bls12_377 as PairingEngine>::Fr>, FieldError> {
let mut deserialized = vec![]; let mut deserialized = vec![];
@ -146,7 +146,7 @@ impl TryFrom<SerializedCircuit> for CircuitSynthesizer<Bls12_377> {
// Deserialize constraints // Deserialize constraints
fn get_deserialized_constraints( fn get_deserialized_constraints(
constraints: &Vec<(SerializedField, SerializedIndex)>, constraints: &[(SerializedField, SerializedIndex)],
) -> Result<Vec<(<Bls12_377 as PairingEngine>::Fr, Index)>, FieldError> { ) -> Result<Vec<(<Bls12_377 as PairingEngine>::Fr, Index)>, FieldError> {
let mut deserialized = vec![]; let mut deserialized = vec![];

View File

@ -36,8 +36,8 @@ impl From<Index> for SerializedIndex {
impl From<&SerializedIndex> for Index { impl From<&SerializedIndex> for Index {
fn from(serialized_index: &SerializedIndex) -> Self { fn from(serialized_index: &SerializedIndex) -> Self {
match serialized_index { match serialized_index {
SerializedIndex::Input(idx) => Index::Input(idx.clone()), SerializedIndex::Input(idx) => Index::Input(*idx),
SerializedIndex::Aux(idx) => Index::Aux(idx.clone()), SerializedIndex::Aux(idx) => Index::Aux(*idx),
} }
} }
} }

View File

@ -21,6 +21,7 @@ use crate::{
use std::{collections::HashMap, convert::TryFrom, path::PathBuf}; use std::{collections::HashMap, convert::TryFrom, path::PathBuf};
#[derive(Default)]
pub struct InputPairs { pub struct InputPairs {
/// Maps file names to input file pairs /// Maps file names to input file pairs
pub pairs: HashMap<String, InputPair>, pub pairs: HashMap<String, InputPair>,
@ -33,7 +34,7 @@ pub struct InputPair {
impl InputPairs { impl InputPairs {
pub fn new() -> Self { pub fn new() -> Self {
Self { pairs: HashMap::new() } Self::default()
} }
} }
@ -52,11 +53,11 @@ impl TryFrom<&PathBuf> for InputPairs {
let file_name = file let file_name = file
.file_stem() .file_stem()
.ok_or(InputsDirectoryError::GettingFileName(file.as_os_str().to_owned()))? .ok_or_else(|| InputsDirectoryError::GettingFileName(file.as_os_str().to_owned()))?
.to_str() .to_str()
.ok_or(InputsDirectoryError::GettingFileName(file.as_os_str().to_owned()))?; .ok_or_else(|| InputsDirectoryError::GettingFileName(file.as_os_str().to_owned()))?;
if file_extension == INPUT_FILE_EXTENSION.trim_start_matches(".") { if file_extension == INPUT_FILE_EXTENSION.trim_start_matches('.') {
let input_file = InputFile::new(file_name).read_from(&file)?.0; let input_file = InputFile::new(file_name).read_from(&file)?.0;
if pairs.contains_key(file_name) { if pairs.contains_key(file_name) {
@ -69,7 +70,7 @@ impl TryFrom<&PathBuf> for InputPairs {
}; };
pairs.insert(file_name.to_owned(), pair); pairs.insert(file_name.to_owned(), pair);
} }
} else if file_extension == STATE_FILE_EXTENSION.trim_start_matches(".") { } else if file_extension == STATE_FILE_EXTENSION.trim_start_matches('.') {
let state_file = StateFile::new(file_name).read_from(&file)?.0; let state_file = StateFile::new(file_name).read_from(&file)?.0;
if pairs.contains_key(file_name) { if pairs.contains_key(file_name) {

View File

@ -82,11 +82,11 @@ impl Package {
} }
} }
if existing_files.len() > 0 { if !existing_files.is_empty() {
tracing::error!("File(s) {:?} already exist", existing_files); tracing::error!("File(s) {:?} already exist", existing_files);
} }
return result; result
} }
/// Returns `true` if a package is initialized at the given path /// Returns `true` if a package is initialized at the given path
@ -120,7 +120,7 @@ impl Package {
} }
} }
return true; true
} }
/// Creates a package at the given path /// Creates a package at the given path
@ -128,9 +128,10 @@ impl Package {
// First, verify that this directory is not already initialized as a Leo package. // First, verify that this directory is not already initialized as a Leo package.
{ {
if !Self::can_initialize(package_name, is_lib, path) { if !Self::can_initialize(package_name, is_lib, path) {
return Err( return Err(PackageError::FailedToInitialize(
PackageError::FailedToInitialize(package_name.to_owned(), path.as_os_str().to_owned()).into(), package_name.to_owned(),
); path.as_os_str().to_owned(),
));
} }
} }
// Next, initialize this directory as a Leo package. // Next, initialize this directory as a Leo package.
@ -174,9 +175,10 @@ impl Package {
// Next, verify that a valid Leo package has been initialized in this directory // Next, verify that a valid Leo package has been initialized in this directory
{ {
if !Self::is_initialized(package_name, is_lib, path) { if !Self::is_initialized(package_name, is_lib, path) {
return Err( return Err(PackageError::FailedToInitialize(
PackageError::FailedToInitialize(package_name.to_owned(), path.as_os_str().to_owned()).into(), package_name.to_owned(),
); path.as_os_str().to_owned(),
));
} }
} }

View File

@ -23,12 +23,12 @@ use std::{fs::File, io::Write, path::PathBuf};
pub static GITIGNORE_FILENAME: &str = ".gitignore"; pub static GITIGNORE_FILENAME: &str = ".gitignore";
#[derive(Deserialize)] #[derive(Deserialize, Default)]
pub struct Gitignore; pub struct Gitignore;
impl Gitignore { impl Gitignore {
pub fn new() -> Self { pub fn new() -> Self {
Self Self::default()
} }
pub fn exists_at(path: &PathBuf) -> bool { pub fn exists_at(path: &PathBuf) -> bool {
@ -50,9 +50,6 @@ impl Gitignore {
} }
fn template(&self) -> String { fn template(&self) -> String {
format!( "outputs/\n".to_string()
r#"outputs/
"#,
)
} }
} }

View File

@ -139,7 +139,7 @@ impl TryFrom<&PathBuf> for Manifest {
// Determine if the old remote format is being used // Determine if the old remote format is being used
if line.starts_with("remote") { if line.starts_with("remote") {
let remote = line let remote = line
.split("=") // Split the line as 'remote' = '"{author}/{package_name}"' .split('=') // Split the line as 'remote' = '"{author}/{package_name}"'
.collect::<Vec<&str>>()[1]; // Fetch just '"{author}/{package_name}"' .collect::<Vec<&str>>()[1]; // Fetch just '"{author}/{package_name}"'
old_remote_format = Some(remote); old_remote_format = Some(remote);
@ -182,7 +182,7 @@ impl TryFrom<&PathBuf> for Manifest {
if !new_remote_format_exists { if !new_remote_format_exists {
// Fetch the author from the old remote. // Fetch the author from the old remote.
let remote_author = old_remote let remote_author = old_remote
.split("/") // Split the old remote as '"{author}' and '{package_name}"' .split('/') // Split the old remote as '"{author}' and '{package_name}"'
.collect::<Vec<&str>>()[0] // Fetch just the '"{author}' .collect::<Vec<&str>>()[0] // Fetch just the '"{author}'
.replace(&['\"', ' '][..], ""); // Remove the quotes from the author string .replace(&['\"', ' '][..], ""); // Remove the quotes from the author string

View File

@ -102,17 +102,17 @@ impl ZipFile {
// Write file or directory // Write file or directory
if path.is_file() { if path.is_file() {
tracing::info!("Adding file {:?} as {:?}", path, name); tracing::info!("Adding file {:?} as {:?}", path, name);
zip.start_file_from_path(name, options)?; zip.start_file(name.to_string_lossy(), options)?;
let mut f = File::open(path)?; let mut f = File::open(path)?;
f.read_to_end(&mut buffer)?; f.read_to_end(&mut buffer)?;
zip.write_all(&*buffer)?; zip.write_all(&*buffer)?;
buffer.clear(); buffer.clear();
} else if name.as_os_str().len() != 0 { } else if !name.as_os_str().is_empty() {
// Only if not root Avoids path spec / warning // Only if not root Avoids path spec / warning
// and mapname conversion failed error on unzip // and mapname conversion failed error on unzip
tracing::info!("Adding directory {:?} as {:?}", path, name); tracing::info!("Adding directory {:?} as {:?}", path, name);
zip.add_directory_from_path(name, options)?; zip.add_directory(name.to_string_lossy(), options)?;
} }
} }
@ -150,23 +150,23 @@ impl ZipFile {
/// Check if the file path should be included in the package zip file. /// Check if the file path should be included in the package zip file.
fn is_included(path: &Path) -> bool { fn is_included(path: &Path) -> bool {
// excluded directories: `input`, `output`, `imports` // excluded directories: `input`, `output`, `imports`
if path.ends_with(INPUTS_DIRECTORY_NAME.trim_end_matches("/")) if path.ends_with(INPUTS_DIRECTORY_NAME.trim_end_matches('/'))
| path.ends_with(OUTPUTS_DIRECTORY_NAME.trim_end_matches("/")) | path.ends_with(OUTPUTS_DIRECTORY_NAME.trim_end_matches('/'))
| path.ends_with(IMPORTS_DIRECTORY_NAME.trim_end_matches("/")) | path.ends_with(IMPORTS_DIRECTORY_NAME.trim_end_matches('/'))
{ {
return false; return false;
} }
// excluded extensions: `.in`, `.bytes`, `lpk`, `lvk`, `.proof`, `.sum`, `.zip`, `.bytes` // excluded extensions: `.in`, `.bytes`, `lpk`, `lvk`, `.proof`, `.sum`, `.zip`, `.bytes`
if let Some(true) = path.extension().map(|ext| { if let Some(true) = path.extension().map(|ext| {
ext.eq(INPUT_FILE_EXTENSION.trim_start_matches(".")) ext.eq(INPUT_FILE_EXTENSION.trim_start_matches('.'))
| ext.eq(ZIP_FILE_EXTENSION.trim_start_matches(".")) | ext.eq(ZIP_FILE_EXTENSION.trim_start_matches('.'))
| ext.eq(PROVING_KEY_FILE_EXTENSION.trim_start_matches(".")) | ext.eq(PROVING_KEY_FILE_EXTENSION.trim_start_matches('.'))
| ext.eq(VERIFICATION_KEY_FILE_EXTENSION.trim_start_matches(".")) | ext.eq(VERIFICATION_KEY_FILE_EXTENSION.trim_start_matches('.'))
| ext.eq(PROOF_FILE_EXTENSION.trim_start_matches(".")) | ext.eq(PROOF_FILE_EXTENSION.trim_start_matches('.'))
| ext.eq(CHECKSUM_FILE_EXTENSION.trim_start_matches(".")) | ext.eq(CHECKSUM_FILE_EXTENSION.trim_start_matches('.'))
| ext.eq(ZIP_FILE_EXTENSION.trim_start_matches(".")) | ext.eq(ZIP_FILE_EXTENSION.trim_start_matches('.'))
| ext.eq(CIRCUIT_FILE_EXTENSION.trim_start_matches(".")) | ext.eq(CIRCUIT_FILE_EXTENSION.trim_start_matches('.'))
}) { }) {
return false; return false;
} }
@ -177,12 +177,12 @@ fn is_included(path: &Path) -> bool {
} }
// Only allow additional files in the `src/` directory // Only allow additional files in the `src/` directory
if !path.starts_with(SOURCE_DIRECTORY_NAME.trim_end_matches("/")) { if !path.starts_with(SOURCE_DIRECTORY_NAME.trim_end_matches('/')) {
return false; return false;
} }
// Allow the `.leo` files in the `src/` directory // Allow the `.leo` files in the `src/` directory
path.extension() path.extension()
.map(|ext| ext.eq(SOURCE_FILE_EXTENSION.trim_start_matches("."))) .map(|ext| ext.eq(SOURCE_FILE_EXTENSION.trim_start_matches('.')))
.unwrap_or(false) .unwrap_or(false)
} }

Some files were not shown because too many files have changed in this diff Show More