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
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
#![allow(clippy::module_inception)]
pub mod access;
pub use access::*;

View File

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

View File

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

View File

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

View File

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

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

View File

@ -53,9 +53,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// Unwrap assertion value and handle errors
let result_option = match assert_expression {
ConstrainedValue::Boolean(boolean) => boolean.get_value(),
_ => return Err(ConsoleError::assertion_must_be_boolean(expression_string, span.clone())),
_ => return Err(ConsoleError::assertion_must_be_boolean(expression_string, span)),
};
let result_bool = result_option.ok_or(ConsoleError::assertion_depends_on_input(span.clone()))?;
let result_bool = result_option.ok_or_else(|| ConsoleError::assertion_depends_on_input(span.clone()))?;
if !result_bool {
return Err(ConsoleError::assertion_failed(expression_string, span));

View File

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

View File

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

View File

@ -50,7 +50,8 @@ impl ConsoleError {
}
pub fn assertion_depends_on_input(span: Span) -> Self {
let message = format!("console.assert() failed to evaluate. This error is caused by empty input file values");
let message =
"console.assert() failed to evaluate. This error is caused by empty input file values".to_string();
Self::new_from_span(message, span)
}

View File

@ -146,7 +146,7 @@ impl ExpressionError {
}
pub fn self_keyword(span: Span) -> Self {
let message = format!("cannot call keyword `Self` outside of a circuit function");
let message = "cannot call keyword `Self` outside of a circuit function".to_string();
Self::new_from_span(message, span)
}

View File

@ -48,7 +48,7 @@ impl ImportError {
}
pub fn convert_os_string(span: Span) -> Self {
let message = format!("failed to convert file string name, maybe an illegal character?");
let message = "failed to convert file string name, maybe an illegal character?".to_string();
Self::new_from_span(message, span)
}

View File

@ -36,7 +36,7 @@ impl OutputBytesError {
}
pub fn not_enough_registers(span: Span) -> Self {
let message = format!("number of input registers must be greater than or equal to output registers");
let message = "number of input registers must be greater than or equal to output registers".to_string();
Self::new_from_span(message, span)
}

View File

@ -67,13 +67,13 @@ impl StatementError {
}
pub fn array_assign_index(span: Span) -> Self {
let message = format!("Cannot assign single index to array of values");
let message = "Cannot assign single index to array of values".to_string();
Self::new_from_span(message, span)
}
pub fn array_assign_range(span: Span) -> Self {
let message = format!("Cannot assign range of array values to single value");
let message = "Cannot assign range of array values to single value".to_string();
Self::new_from_span(message, span)
}
@ -145,7 +145,7 @@ impl StatementError {
}
pub fn tuple_assign_index(span: Span) -> Self {
let message = format!("Cannot assign single index to tuple of values");
let message = "Cannot assign single index to tuple of values".to_string();
Self::new_from_span(message, span)
}

View File

@ -64,7 +64,7 @@ impl AddressError {
}
pub fn missing_address(span: Span) -> Self {
let message = format!("expected address input not found");
let message = "expected address input not found".to_string();
Self::new_from_span(message, span)
}

View File

@ -88,13 +88,13 @@ impl GroupError {
}
pub fn x_recover(span: Span) -> Self {
let message = format!("could not recover group element from x coordinate");
let message = "could not recover group element from x coordinate".to_string();
Self::new_from_span(message, span)
}
pub fn y_recover(span: Span) -> Self {
let message = format!("could not recover group element from y coordinate");
let message = "could not recover group element from y coordinate".to_string();
Self::new_from_span(message, span)
}

View File

@ -68,7 +68,7 @@ impl IntegerError {
}
pub fn negate_operation(span: Span) -> Self {
let message = format!("integer negation can only be enforced on signed integers");
let message = "integer negation can only be enforced on signed integers".to_string();
Self::new_from_span(message, span)
}
@ -83,9 +83,9 @@ impl IntegerError {
}
pub fn invalid_index(span: Span) -> Self {
let message = format!(
let message =
"index must be a constant value unsigned integer. allocated indices produce a circuit of unknown size"
);
.to_string();
Self::new_from_span(message, span)
}

View File

@ -63,7 +63,7 @@ impl ValueError {
}
pub fn implicit_group(span: Span) -> Self {
let message = format!("group coordinates should be in (x, y)group format");
let message = "group coordinates should be in (x, y)group format".to_string();
Self::new_from_span(message, span)
}

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())?;
enforce_div(cs, val_1, val_2, span)
}
(val_1, val_2) => {
return Err(ExpressionError::incompatible_types(
format!("{} / {}", val_1, val_2,),
span,
));
}
(val_1, val_2) => Err(ExpressionError::incompatible_types(
format!("{} / {}", val_1, val_2,),
span,
)),
}
}

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())?;
enforce_mul(cs, val_1, val_2, span)
}
(val_1, val_2) => {
return Err(ExpressionError::incompatible_types(
format!("{} * {}", val_1, val_2),
span,
));
}
(val_1, val_2) => Err(ExpressionError::incompatible_types(
format!("{} * {}", val_1, val_2),
span,
)),
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -37,7 +37,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
unresolved_identifier: Identifier,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
// Evaluate the identifier name in the current function scope
let variable_name = new_scope(function_scope.clone(), unresolved_identifier.to_string());
let variable_name = new_scope(function_scope, unresolved_identifier.to_string());
let identifier_name = new_scope(file_scope, unresolved_identifier.to_string());
let mut result_value = if let Some(value) = self.get(&variable_name) {
@ -58,7 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
return Err(ExpressionError::undefined_identifier(unresolved_identifier));
};
result_value.resolve_type(expected_type, unresolved_identifier.span.clone())?;
result_value.resolve_type(expected_type, unresolved_identifier.span)?;
Ok(result_value)
}

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) {
let name_unique = format!("{} {}:{}", name, span.line, span.start);
let result = Boolean::and(cs.ns(|| name_unique), &left_bool, &right_bool)
.map_err(|e| BooleanError::cannot_enforce(format!("&&"), e, span))?;
.map_err(|e| BooleanError::cannot_enforce("&&".to_string(), e, span))?;
return Ok(ConstrainedValue::Boolean(result));
}

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) {
let name_unique = format!("{} {}:{}", name, span.line, span.start);
let result = Boolean::or(cs.ns(|| name_unique), &left_bool, &right_bool)
.map_err(|e| BooleanError::cannot_enforce(format!("||"), e, span))?;
.map_err(|e| BooleanError::cannot_enforce("||".to_string(), e, span))?;
return Ok(ConstrainedValue::Boolean(result));
}

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))
}

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))
}

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))
}

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))
}

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))
}

View File

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

View File

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

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

View File

@ -54,7 +54,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
let name = input_model.identifier.name.clone();
let input_option = input
.get(&name)
.ok_or(FunctionError::input_not_found(name.clone(), function.span.clone()))?;
.ok_or_else(|| FunctionError::input_not_found(name.clone(), function.span.clone()))?;
let input_value = self.allocate_main_function_input(
cs,
input_model.type_,

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

@ -16,6 +16,8 @@
//! Module containing structs and types that make up a Leo program.
#![allow(clippy::module_inception)]
#[macro_use]
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>>,
}
impl<F: Field + PrimeField, G: GroupType<F>> Default for ConstrainedProgram<F, G> {
fn default() -> Self {
Self {
identifiers: HashMap::new(),
}
}
}
pub fn new_scope(outer: String, inner: String) -> String {
format!("{}_{}", outer, inner)
}
pub fn is_in_scope(current_scope: &String, desired_scope: &String) -> bool {
pub fn is_in_scope(current_scope: &str, desired_scope: &str) -> bool {
current_scope.ends_with(desired_scope)
}
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
pub fn new() -> Self {
Self {
identifiers: HashMap::new(),
}
Self::default()
}
pub(crate) fn store(&mut self, name: String, value: ConstrainedValue<F, G>) {
self.identifiers.insert(name, value);
}
pub(crate) fn get(&self, name: &String) -> Option<&ConstrainedValue<F, G>> {
pub(crate) fn get(&self, name: &str) -> Option<&ConstrainedValue<F, G>> {
self.identifiers.get(name)
}
pub(crate) fn get_mut(&mut self, name: &String) -> Option<&mut ConstrainedValue<F, G>> {
pub(crate) fn get_mut(&mut self, name: &str) -> Option<&mut ConstrainedValue<F, G>> {
self.identifiers.get_mut(name)
}
}

View File

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

View File

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

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())? {
ConstrainedValue::CircuitExpression(_variable, members) => {
// Modify the circuit variable in place
let matched_variable = members.into_iter().find(|member| member.0 == variable_name);
let matched_variable = members.iter_mut().find(|member| member.0 == variable_name);
match matched_variable {
Some(member) => match &member.1 {
@ -81,7 +81,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
member.1 = selected_value.to_owned();
Ok(selected_value.to_owned())
Ok(selected_value)
}
_ => {
// Throw an error if we try to mutate an immutable circuit variable

View File

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

View File

@ -16,7 +16,14 @@
//! Methods to enforce constraints on statements in a compiled Leo program.
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
use crate::{
errors::StatementError,
program::ConstrainedProgram,
value::ConstrainedValue,
GroupType,
IndicatorAndConstrainedValue,
StatementResult,
};
use leo_typed::{ConditionalNestedOrEndStatement, ConditionalStatement, Span, Type};
use snarkos_models::{
@ -28,7 +35,7 @@ fn indicator_to_string(indicator: &Boolean) -> String {
indicator
.get_value()
.map(|b| b.to_string())
.unwrap_or(format!("[input]"))
.unwrap_or_else(|| "[input]".to_string())
}
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
@ -36,6 +43,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
/// Due to R1CS constraints, we must evaluate every branch to properly construct the circuit.
/// At program execution, we will pass an `indicator` bit down to all child statements within each branch.
/// The `indicator` bit will select that branch while keeping the constraint system satisfied.
#[allow(clippy::too_many_arguments)]
pub fn enforce_conditional_statement<CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,
@ -45,7 +53,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
statement: ConditionalStatement,
return_type: Option<Type>,
span: Span,
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
) -> StatementResult<Vec<IndicatorAndConstrainedValue<F, G>>> {
let statement_string = statement.to_string();
// Inherit the indicator from a previous conditional statement or assume that we are the outer parent

View File

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

View File

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

View File

@ -28,9 +28,7 @@ fn check_return_type(expected: Option<Type>, actual: Type, span: Span) -> Result
match expected {
Some(expected) => {
if expected.ne(&actual) {
if expected.is_self() && actual.is_circuit() {
return Ok(());
} else if expected.match_array_types(&actual) {
if (expected.is_self() && actual.is_circuit()) || expected.match_array_types(&actual) {
return Ok(());
} else {
return Err(StatementError::arguments_type(&expected, &actual, span));
@ -56,8 +54,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
let result = self.enforce_operand(
cs,
file_scope.clone(),
function_scope.clone(),
file_scope,
function_scope,
return_type.clone(),
expression,
span.clone(),

View File

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

View File

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

View File

@ -79,7 +79,7 @@ impl<F: Field + PrimeField> FieldType<F> {
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
let result = self_value
.add(cs, other_value)
.map_err(|e| FieldError::binary_operation(format!("+"), e, span))?;
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?;
Ok(FieldType::Allocated(result))
}
@ -88,7 +88,7 @@ impl<F: Field + PrimeField> FieldType<F> {
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
allocated_value
.add_constant(cs, constant_value)
.map_err(|e| FieldError::binary_operation(format!("+"), e, span))?,
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?,
)),
}
}
@ -102,7 +102,7 @@ impl<F: Field + PrimeField> FieldType<F> {
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
let result = self_value
.sub(cs, other_value)
.map_err(|e| FieldError::binary_operation(format!("-"), e, span))?;
.map_err(|e| FieldError::binary_operation("-".to_string(), e, span))?;
Ok(FieldType::Allocated(result))
}
@ -111,7 +111,7 @@ impl<F: Field + PrimeField> FieldType<F> {
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
allocated_value
.sub_constant(cs, constant_value)
.map_err(|e| FieldError::binary_operation(format!("+"), e, span))?,
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span))?,
)),
}
}
@ -125,7 +125,7 @@ impl<F: Field + PrimeField> FieldType<F> {
(FieldType::Allocated(self_value), FieldType::Allocated(other_value)) => {
let result = self_value
.mul(cs, other_value)
.map_err(|e| FieldError::binary_operation(format!("*"), e, span))?;
.map_err(|e| FieldError::binary_operation("*".to_string(), e, span))?;
Ok(FieldType::Allocated(result))
}
@ -134,7 +134,7 @@ impl<F: Field + PrimeField> FieldType<F> {
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
allocated_value
.mul_by_constant(cs, constant_value)
.map_err(|e| FieldError::binary_operation(format!("*"), e, span))?,
.map_err(|e| FieldError::binary_operation("*".to_string(), e, span))?,
)),
}
}
@ -144,14 +144,14 @@ impl<F: Field + PrimeField> FieldType<F> {
FieldType::Constant(constant) => {
let constant_inverse = constant
.inverse()
.ok_or(FieldError::no_inverse(constant.to_string(), span.clone()))?;
.ok_or_else(|| FieldError::no_inverse(constant.to_string(), span.clone()))?;
FieldType::Constant(constant_inverse)
}
FieldType::Allocated(allocated) => {
let allocated_inverse = allocated
.inverse(&mut cs)
.map_err(|e| FieldError::binary_operation(format!("+"), e, span.clone()))?;
.map_err(|e| FieldError::binary_operation("+".to_string(), e, span.clone()))?;
FieldType::Allocated(allocated_inverse)
}

View File

@ -48,7 +48,7 @@ use std::{
#[derive(Clone, Debug)]
pub enum EdwardsGroupType {
Constant(EdwardsAffine),
Allocated(EdwardsBlsGadget),
Allocated(Box<EdwardsBlsGadget>),
}
impl GroupType<Fq> for EdwardsGroupType {
@ -60,7 +60,7 @@ impl GroupType<Fq> for EdwardsGroupType {
fn to_allocated<CS: ConstraintSystem<Fq>>(&self, mut cs: CS, span: Span) -> Result<Self, GroupError> {
self.allocated(cs.ns(|| format!("allocate affine point {}:{}", span.line, span.start)))
.map(|result| EdwardsGroupType::Allocated(result))
.map(|ebg| EdwardsGroupType::Allocated(Box::new(ebg)))
.map_err(|error| GroupError::synthesis_error(error, span))
}
@ -71,7 +71,7 @@ impl GroupType<Fq> for EdwardsGroupType {
let result = <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::negate(group, cs)
.map_err(|e| GroupError::negate_operation(e, span))?;
Ok(EdwardsGroupType::Allocated(result))
Ok(EdwardsGroupType::Allocated(Box::new(result)))
}
}
}
@ -88,18 +88,18 @@ impl GroupType<Fq> for EdwardsGroupType {
cs,
other_value,
)
.map_err(|e| GroupError::binary_operation(format!("+"), e, span))?;
.map_err(|e| GroupError::binary_operation("+".to_string(), e, span))?;
Ok(EdwardsGroupType::Allocated(result))
Ok(EdwardsGroupType::Allocated(Box::new(result)))
}
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
Ok(EdwardsGroupType::Allocated(
Ok(EdwardsGroupType::Allocated(Box::new(
allocated_value
.add_constant(cs, constant_value)
.map_err(|e| GroupError::binary_operation(format!("+"), e, span))?,
))
.map_err(|e| GroupError::binary_operation("+".to_string(), e, span))?,
)))
}
}
}
@ -116,18 +116,18 @@ impl GroupType<Fq> for EdwardsGroupType {
cs,
other_value,
)
.map_err(|e| GroupError::binary_operation(format!("-"), e, span))?;
.map_err(|e| GroupError::binary_operation("-".to_string(), e, span))?;
Ok(EdwardsGroupType::Allocated(result))
Ok(EdwardsGroupType::Allocated(Box::new(result)))
}
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
Ok(EdwardsGroupType::Allocated(
Ok(EdwardsGroupType::Allocated(Box::new(
allocated_value
.sub_constant(cs, constant_value)
.map_err(|e| GroupError::binary_operation(format!("-"), e, span))?,
))
.map_err(|e| GroupError::binary_operation("-".to_string(), e, span))?,
)))
}
}
}
@ -143,13 +143,13 @@ impl EdwardsGroupType {
pub fn edwards_affine_from_single(number: String, span: Span) -> Result<EdwardsAffine, GroupError> {
if number.eq("0") {
return Ok(EdwardsAffine::zero());
Ok(EdwardsAffine::zero())
} else {
let one = edwards_affine_one();
let number_value = Fp256::from_str(&number).map_err(|_| GroupError::n_group(number, span))?;
let result: EdwardsAffine = one.mul(&number_value);
return Ok(result);
Ok(result)
}
}
@ -201,11 +201,13 @@ impl EdwardsGroupType {
let x = Fq::from_str(&x_string).map_err(|_| GroupError::x_invalid(x_string, x_span))?;
match greatest {
// Sign provided
Some(greatest) => EdwardsAffine::from_x_coordinate(x, greatest).ok_or(GroupError::x_recover(element_span)),
Some(greatest) => {
EdwardsAffine::from_x_coordinate(x, greatest).ok_or_else(|| GroupError::x_recover(element_span))
}
// Sign inferred
None => {
// Attempt to recover with a sign_low bit.
if let Some(element) = EdwardsAffine::from_x_coordinate(x.clone(), false) {
if let Some(element) = EdwardsAffine::from_x_coordinate(x, false) {
return Ok(element);
}
@ -230,11 +232,13 @@ impl EdwardsGroupType {
match greatest {
// Sign provided
Some(greatest) => EdwardsAffine::from_y_coordinate(y, greatest).ok_or(GroupError::y_recover(element_span)),
Some(greatest) => {
EdwardsAffine::from_y_coordinate(y, greatest).ok_or_else(|| GroupError::y_recover(element_span))
}
// Sign inferred
None => {
// Attempt to recover with a sign_low bit.
if let Some(element) = EdwardsAffine::from_y_coordinate(y.clone(), false) {
if let Some(element) = EdwardsAffine::from_y_coordinate(y, false) {
return Ok(element);
}
@ -294,12 +298,8 @@ impl EdwardsGroupType {
let x_value = allocated.x.get_value();
let y_value = allocated.y.get_value();
let x_allocated = FpGadget::alloc(cs.ns(|| format!("x")), || {
x_value.ok_or(SynthesisError::AssignmentMissing)
})?;
let y_allocated = FpGadget::alloc(cs.ns(|| format!("y")), || {
y_value.ok_or(SynthesisError::AssignmentMissing)
})?;
let x_allocated = FpGadget::alloc(cs.ns(|| "x"), || x_value.ok_or(SynthesisError::AssignmentMissing))?;
let y_allocated = FpGadget::alloc(cs.ns(|| "y"), || y_value.ok_or(SynthesisError::AssignmentMissing))?;
Ok(EdwardsBlsGadget::new(x_allocated, y_allocated))
}
@ -316,7 +316,7 @@ impl AllocGadget<GroupValue, Fq> for EdwardsGroupType {
Self::alloc_helper(value_gen)
})?;
Ok(EdwardsGroupType::Allocated(value))
Ok(EdwardsGroupType::Allocated(Box::new(value)))
}
fn alloc_input<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<GroupValue>, CS: ConstraintSystem<Fq>>(
@ -327,7 +327,7 @@ impl AllocGadget<GroupValue, Fq> for EdwardsGroupType {
Self::alloc_helper(value_gen)
})?;
Ok(EdwardsGroupType::Allocated(value))
Ok(EdwardsGroupType::Allocated(Box::new(value)))
}
}
@ -454,7 +454,7 @@ impl CondSelectGadget<Fq> for EdwardsGroupType {
let second_gadget = second.allocated(cs.ns(|| "second"))?;
let result = EdwardsBlsGadget::conditionally_select(cs, cond, &first_gadget, &second_gadget)?;
Ok(EdwardsGroupType::Allocated(result))
Ok(EdwardsGroupType::Allocated(Box::new(result)))
}
}

View File

@ -157,7 +157,7 @@ impl Integer {
let unsigned_integer = self;
let value_option: Option<String> = match_unsigned_integer!(unsigned_integer => unsigned_integer.get_value());
let value = value_option.ok_or(IntegerError::invalid_index(span.clone()))?;
let value = value_option.ok_or_else(|| IntegerError::invalid_index(span.clone()))?;
let value_usize = value
.parse::<usize>()
.map_err(|_| IntegerError::invalid_integer(value, span))?;
@ -378,7 +378,7 @@ impl Integer {
let result = match_signed_integer!(a, s => a.neg(cs.ns(|| unique_namespace)));
result.ok_or(IntegerError::negate_operation(span))
result.ok_or_else(|| IntegerError::negate_operation(span))
}
pub fn add<F: Field + PrimeField, CS: ConstraintSystem<F>>(
@ -395,7 +395,7 @@ impl Integer {
let result = match_integers_span!((a, b), s => a.add(cs.ns(|| unique_namespace), &b));
result.ok_or(IntegerError::binary_operation(format!("+"), span))
result.ok_or_else(|| IntegerError::binary_operation("+".to_string(), span))
}
pub fn sub<F: Field + PrimeField, CS: ConstraintSystem<F>>(
@ -412,7 +412,7 @@ impl Integer {
let result = match_integers_span!((a, b), s => a.sub(cs.ns(|| unique_namespace), &b));
result.ok_or(IntegerError::binary_operation(format!("-"), span))
result.ok_or_else(|| IntegerError::binary_operation("-".to_string(), span))
}
pub fn mul<F: Field + PrimeField, CS: ConstraintSystem<F>>(
@ -429,7 +429,7 @@ impl Integer {
let result = match_integers_span!((a, b), s => a.mul(cs.ns(|| unique_namespace), &b));
result.ok_or(IntegerError::binary_operation(format!("*"), span))
result.ok_or_else(|| IntegerError::binary_operation("*".to_string(), span))
}
pub fn div<F: Field + PrimeField, CS: ConstraintSystem<F>>(
@ -446,7 +446,7 @@ impl Integer {
let result = match_integers_span!((a, b), s => a.div(cs.ns(|| unique_namespace), &b));
result.ok_or(IntegerError::binary_operation(format!("÷"), span))
result.ok_or_else(|| IntegerError::binary_operation("÷".to_string(), span))
}
pub fn pow<F: Field + PrimeField, CS: ConstraintSystem<F>>(
@ -463,7 +463,7 @@ impl Integer {
let result = match_integers_span!((a, b), s => a.pow(cs.ns(|| unique_namespace), &b));
result.ok_or(IntegerError::binary_operation(format!("**"), span))
result.ok_or_else(|| IntegerError::binary_operation("**".to_string(), span))
}
}

View File

@ -110,7 +110,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
// Data type wrappers
ConstrainedValue::Array(array) => {
let array_type = array[0].to_type(span.clone())?;
let array_type = array[0].to_type(span)?;
let mut dimensions = vec![array.len()];
// Nested array type
@ -205,15 +205,15 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
// If this is a circuit function, evaluate inside the circuit scope
if let Some(identifier) = circuit_identifier {
// avoid creating recursive scope
if !is_in_scope(&scope, &identifier.name.to_string()) {
outer_scope = new_scope(scope, identifier.name.to_string());
if !is_in_scope(&scope, &identifier.name) {
outer_scope = new_scope(scope, identifier.name);
}
}
Ok((outer_scope, function.clone()))
Ok((outer_scope, function))
}
ConstrainedValue::Import(import_scope, function) => function.extract_function(import_scope, span),
value => return Err(ExpressionError::undefined_function(value.to_string(), span)),
value => Err(ExpressionError::undefined_function(value.to_string(), span)),
}
}
@ -221,7 +221,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
match self {
ConstrainedValue::CircuitDefinition(circuit) => Ok(circuit),
ConstrainedValue::Import(_import_scope, circuit) => circuit.extract_circuit(span),
value => return Err(ExpressionError::undefined_circuit(value.to_string(), span)),
value => Err(ExpressionError::undefined_circuit(value.to_string(), span)),
}
}
@ -239,7 +239,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
}
ConstrainedValue::Boolean(boolean) => {
let option = boolean.get_value();
let name = option.map(|b| b.to_string()).unwrap_or(format!("[allocated]"));
let name = option
.map(|b| b.to_string())
.unwrap_or_else(|| "[allocated]".to_string());
*boolean = allocate_bool(&mut cs, name, option, span)?;
}
@ -256,7 +258,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
ConstrainedValue::Integer(integer) => {
let integer_type = integer.get_type();
let option = integer.get_value();
let name = option.clone().unwrap_or(format!("[allocated]"));
let name = option.clone().unwrap_or_else(|| "[allocated]".to_string());
*integer = Integer::allocate_type(&mut cs, integer_type, name, option, span)?;
}
@ -328,7 +330,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<F
value
.get_value()
.map(|v| v.to_string())
.unwrap_or(format!("[allocated]"))
.unwrap_or_else(|| "[allocated]".to_string())
),
ConstrainedValue::Field(ref value) => write!(f, "{:?}", value),
ConstrainedValue::Group(ref value) => write!(f, "{:?}", value),
@ -402,18 +404,18 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConditionalEqGadget<F> for Constrai
num_1.conditional_enforce_equal(cs, num_2, condition)
}
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
for (i, (left, right)) in arr_1.into_iter().zip(arr_2.into_iter()).enumerate() {
for (i, (left, right)) in arr_1.iter().zip(arr_2.iter()).enumerate() {
left.conditional_enforce_equal(cs.ns(|| format!("array[{}]", i)), right, condition)?;
}
Ok(())
}
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Tuple(tuple_2)) => {
for (i, (left, right)) in tuple_1.into_iter().zip(tuple_2.into_iter()).enumerate() {
for (i, (left, right)) in tuple_1.iter().zip(tuple_2.iter()).enumerate() {
left.conditional_enforce_equal(cs.ns(|| format!("tuple index {}", i)), right, condition)?;
}
Ok(())
}
(_, _) => return Err(SynthesisError::Unsatisfiable),
(_, _) => Err(SynthesisError::Unsatisfiable),
}
}
@ -448,7 +450,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
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(
cs.ns(|| format!("array[{}]", i)),
cond,
@ -462,7 +464,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
(ConstrainedValue::Tuple(tuple_1), ConstrainedValue::Array(tuple_2)) => {
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(
cs.ns(|| format!("tuple index {}", i)),
cond,
@ -484,7 +486,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> CondSelectGadget<F> for Constrained
) => {
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(
cs.ns(|| format!("circuit member[{}]", i)),
cond,
@ -545,18 +547,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> From<Value> for ConstrainedValue<F,
Value::I64(i64) => ConstrainedValue::Integer(Integer::I64(i64)),
Value::I128(i128) => ConstrainedValue::Integer(Integer::I128(i128)),
Value::Array(array) => ConstrainedValue::Array(
array
.into_iter()
.map(|element| ConstrainedValue::from(element))
.collect(),
),
Value::Tuple(tuple) => ConstrainedValue::Tuple(
tuple
.into_iter()
.map(|element| ConstrainedValue::from(element))
.collect(),
),
Value::Array(array) => ConstrainedValue::Array(array.into_iter().map(ConstrainedValue::from).collect()),
Value::Tuple(tuple) => ConstrainedValue::Tuple(tuple.into_iter().map(ConstrainedValue::from).collect()),
}
}
}

View File

@ -35,7 +35,7 @@ impl CorePackageError {
}
pub fn core_package_star(span: Span) -> Self {
let message = format!("Cannot import star from leo-core");
let message = "Cannot import star from leo-core".to_string();
Self::new_from_span(message, span)
}

View File

@ -48,7 +48,7 @@ impl CorePackageListError {
}
pub fn core_package_star(span: Span) -> Self {
let message = format!("Cannot import star from leo-core");
let message = "Cannot import star from leo-core".to_string();
Self::new_from_span(message, span)
}

View File

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

View File

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

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)
}

View File

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

View File

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

View File

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

View File

@ -29,7 +29,6 @@ where
{
type ErrorType;
#[must_use]
fn neg<CS: ConstraintSystem<F>>(&self, cs: CS) -> Result<Self, Self::ErrorType>;
}
@ -44,7 +43,7 @@ impl<F: Field> Neg<F> for Vec<Boolean> {
let mut one = vec![Boolean::constant(true)];
one.append(&mut vec![Boolean::Constant(false); self.len() - 1]);
let mut bits = flipped.add_bits(cs.ns(|| format!("add one")), &one)?;
let mut bits = flipped.add_bits(cs.ns(|| "add one"), &one)?;
let _carry = bits.pop(); // we already accounted for overflow above
Ok(bits)

View File

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

View File

@ -23,6 +23,5 @@ where
{
type ErrorType;
#[must_use]
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,
carry: &'a Self,
) -> Result<(Self, Self), SynthesisError> {
let a_x_b = Boolean::xor(cs.ns(|| format!("a XOR b")), a, b)?;
let sum = Boolean::xor(cs.ns(|| format!("adder sum")), &a_x_b, carry)?;
let a_x_b = Boolean::xor(cs.ns(|| "a XOR b"), a, b)?;
let sum = Boolean::xor(cs.ns(|| "adder sum"), &a_x_b, carry)?;
let c1 = Boolean::and(cs.ns(|| format!("a AND b")), a, b)?;
let c2 = Boolean::and(cs.ns(|| format!("carry AND (a XOR b)")), carry, &a_x_b)?;
let carry = Boolean::or(cs.ns(|| format!("c1 OR c2")), &c1, &c2)?;
let c1 = Boolean::and(cs.ns(|| "a AND b"), a, b)?;
let c2 = Boolean::and(cs.ns(|| "carry AND (a XOR b)"), carry, &a_x_b)?;
let carry = Boolean::or(cs.ns(|| "c1 OR c2"), &c1, &c2)?;
Ok((sum, carry))
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -65,7 +65,7 @@ impl CLI for DeployCommand {
Ok(())
}
None => {
let mut main_file_path = path.clone();
let mut main_file_path = path;
main_file_path.push(SOURCE_DIRECTORY_NAME);
main_file_path.push(MAIN_FILENAME);

View File

@ -65,7 +65,7 @@ impl CLI for LintCommand {
Ok(())
}
None => {
let mut main_file_path = path.clone();
let mut main_file_path = path;
main_file_path.push(SOURCE_DIRECTORY_NAME);
main_file_path.push(MAIN_FILENAME);

View File

@ -146,7 +146,7 @@ impl CLI for SetupCommand {
Ok((program, proving_key, prepared_verifying_key))
}
None => {
let mut main_file_path = path.clone();
let mut main_file_path = path;
main_file_path.push(SOURCE_DIRECTORY_NAME);
main_file_path.push(MAIN_FILENAME);

View File

@ -60,7 +60,7 @@ impl CLI for TestCommand {
let package_name = manifest.get_package_name();
// Sanitize the package path to the root directory
let mut package_path = path.clone();
let mut package_path = path;
if package_path.is_file() {
package_path.pop();
}
@ -92,17 +92,14 @@ impl CLI for TestCommand {
let start = Instant::now();
// Parse the current main program file
let program = Compiler::<Fq, EdwardsGroupType>::parse_program_without_input(
package_name.clone(),
file_path.clone(),
output_directory,
)?;
let program =
Compiler::<Fq, EdwardsGroupType>::parse_program_without_input(package_name, file_path, output_directory)?;
// Parse all inputs as input pairs
let pairs = InputPairs::try_from(&package_path)?;
// Run tests
let temporary_program = program.clone();
let temporary_program = program;
let (passed, failed) = temporary_program.compile_test_constraints(pairs)?;
// 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> {
match arguments.subcommand() {
("automatic", Some(arguments)) => {
// Run the `automatic` subcommand
let options = UpdateAutomatic::parse(arguments)?;
let _output = UpdateAutomatic::output(options)?;
return Ok(None);
}
_ => {}
if let ("automatic", Some(arguments)) = arguments.subcommand() {
// Run the `automatic` subcommand
let options = UpdateAutomatic::parse(arguments)?;
let _output = UpdateAutomatic::output(options)?;
return Ok(None);
};
let show_all_versions = arguments.is_present("list");

View File

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

View File

@ -91,7 +91,7 @@ impl Config {
let toml_string = match fs::read_to_string(&config_path) {
Ok(mut toml) => {
// 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())?;
fs::write(&config_path, default_config_string.clone())?;
toml = default_config_string;
@ -131,7 +131,7 @@ pub fn write_token(token: &str) -> Result<(), io::Error> {
let config_dir = LEO_CONFIG_DIRECTORY.clone();
// 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)?;
}

View File

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

View File

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

View File

@ -21,6 +21,7 @@ use crate::{
use std::{collections::HashMap, convert::TryFrom, path::PathBuf};
#[derive(Default)]
pub struct InputPairs {
/// Maps file names to input file pairs
pub pairs: HashMap<String, InputPair>,
@ -33,7 +34,7 @@ pub struct InputPair {
impl InputPairs {
pub fn new() -> Self {
Self { pairs: HashMap::new() }
Self::default()
}
}
@ -52,11 +53,11 @@ impl TryFrom<&PathBuf> for InputPairs {
let file_name = file
.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()
.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;
if pairs.contains_key(file_name) {
@ -69,7 +70,7 @@ impl TryFrom<&PathBuf> for InputPairs {
};
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;
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);
}
return result;
result
}
/// 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
@ -128,9 +128,10 @@ impl Package {
// First, verify that this directory is not already initialized as a Leo package.
{
if !Self::can_initialize(package_name, is_lib, path) {
return Err(
PackageError::FailedToInitialize(package_name.to_owned(), path.as_os_str().to_owned()).into(),
);
return Err(PackageError::FailedToInitialize(
package_name.to_owned(),
path.as_os_str().to_owned(),
));
}
}
// 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
{
if !Self::is_initialized(package_name, is_lib, path) {
return Err(
PackageError::FailedToInitialize(package_name.to_owned(), path.as_os_str().to_owned()).into(),
);
return Err(PackageError::FailedToInitialize(
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";
#[derive(Deserialize)]
#[derive(Deserialize, Default)]
pub struct Gitignore;
impl Gitignore {
pub fn new() -> Self {
Self
Self::default()
}
pub fn exists_at(path: &PathBuf) -> bool {
@ -50,9 +50,6 @@ impl Gitignore {
}
fn template(&self) -> String {
format!(
r#"outputs/
"#,
)
"outputs/\n".to_string()
}
}

View File

@ -139,7 +139,7 @@ impl TryFrom<&PathBuf> for Manifest {
// Determine if the old remote format is being used
if line.starts_with("remote") {
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}"'
old_remote_format = Some(remote);
@ -182,7 +182,7 @@ impl TryFrom<&PathBuf> for Manifest {
if !new_remote_format_exists {
// Fetch the author from the 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}'
.replace(&['\"', ' '][..], ""); // Remove the quotes from the author string

View File

@ -102,17 +102,17 @@ impl ZipFile {
// Write file or directory
if path.is_file() {
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)?;
f.read_to_end(&mut buffer)?;
zip.write_all(&*buffer)?;
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
// and mapname conversion failed error on unzip
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.
fn is_included(path: &Path) -> bool {
// excluded directories: `input`, `output`, `imports`
if path.ends_with(INPUTS_DIRECTORY_NAME.trim_end_matches("/"))
| path.ends_with(OUTPUTS_DIRECTORY_NAME.trim_end_matches("/"))
| path.ends_with(IMPORTS_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(IMPORTS_DIRECTORY_NAME.trim_end_matches('/'))
{
return false;
}
// excluded extensions: `.in`, `.bytes`, `lpk`, `lvk`, `.proof`, `.sum`, `.zip`, `.bytes`
if let Some(true) = path.extension().map(|ext| {
ext.eq(INPUT_FILE_EXTENSION.trim_start_matches("."))
| ext.eq(ZIP_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(PROOF_FILE_EXTENSION.trim_start_matches("."))
| ext.eq(CHECKSUM_FILE_EXTENSION.trim_start_matches("."))
| ext.eq(ZIP_FILE_EXTENSION.trim_start_matches("."))
| ext.eq(CIRCUIT_FILE_EXTENSION.trim_start_matches("."))
ext.eq(INPUT_FILE_EXTENSION.trim_start_matches('.'))
| ext.eq(ZIP_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(PROOF_FILE_EXTENSION.trim_start_matches('.'))
| ext.eq(CHECKSUM_FILE_EXTENSION.trim_start_matches('.'))
| ext.eq(ZIP_FILE_EXTENSION.trim_start_matches('.'))
| ext.eq(CIRCUIT_FILE_EXTENSION.trim_start_matches('.'))
}) {
return false;
}
@ -177,12 +177,12 @@ fn is_included(path: &Path) -> bool {
}
// 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;
}
// Allow the `.leo` files in the `src/` directory
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)
}

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