diff --git a/ast/src/common/array_dimensions.rs b/ast/src/common/array_dimensions.rs index 1a3236f01b..4e2b06f9f5 100644 --- a/ast/src/common/array_dimensions.rs +++ b/ast/src/common/array_dimensions.rs @@ -81,9 +81,7 @@ impl ArrayDimensions { /// pub fn remove_first(&mut self) -> Option { // If there are no dimensions in the array, then return None. - if self.0.first().is_none() { - return None; - } + self.0.first()?; // Remove the first dimension. let removed = self.0.remove(0); diff --git a/ast/src/types/type_.rs b/ast/src/types/type_.rs index 32d462d11e..554e524898 100644 --- a/ast/src/types/type_.rs +++ b/ast/src/types/type_.rs @@ -91,7 +91,7 @@ impl Type { let right_new_type = inner_array_type(*right_type.to_owned(), right_dim_owned); // Call eq_flat() on the new left and right types. - return left_new_type.eq_flat(&right_new_type); + left_new_type.eq_flat(&right_new_type) } (Type::Tuple(left), Type::Tuple(right)) => left .iter() diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 61a36acfa2..b0dd22fc77 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -70,7 +70,7 @@ impl> Compiler { output_directory, program: Program::new(package_name), program_input: Input::new(), - imported_programs: ImportParser::new(), + imported_programs: ImportParser::default(), _engine: PhantomData, _group: PhantomData, } @@ -214,7 +214,7 @@ impl> Compiler { })?; // Run type inference check on program. - TypeInference::new(&self.program, symbol_table).map_err(|mut e| { + TypeInference::run(&self.program, symbol_table).map_err(|mut e| { e.set_path(&self.main_file_path); e @@ -256,7 +256,7 @@ impl> Compiler { let symbol_table = SymbolTable::new(&self.program, &self.imported_programs, &self.program_input)?; // Run type inference check on program. - TypeInference::new(&self.program, symbol_table)?; + TypeInference::run(&self.program, symbol_table)?; tracing::debug!("Program parsing complete\n{:#?}", self.program); diff --git a/compiler/src/constraints/constraints.rs b/compiler/src/constraints/constraints.rs index d8b067c9bd..0027f0762e 100644 --- a/compiler/src/constraints/constraints.rs +++ b/compiler/src/constraints/constraints.rs @@ -48,9 +48,7 @@ pub fn generate_constraints, CS: Constrai resolved_program.store_definitions(program, imported_programs)?; - let main = resolved_program - .get(&main_function_name) - .ok_or_else(|| CompilerError::NoMain)?; + let main = resolved_program.get(&main_function_name).ok_or(CompilerError::NoMain)?; match main.clone() { ConstrainedValue::Function(_circuit_identifier, function) => { diff --git a/compiler/src/expression/array/array.rs b/compiler/src/expression/array/array.rs index ed36684c88..fe740cc069 100644 --- a/compiler/src/expression/array/array.rs +++ b/compiler/src/expression/array/array.rs @@ -107,7 +107,10 @@ impl> ConstrainedProgram { Ok(ConstrainedValue::Array(result)) } - /// Enforce array expressions + /// + /// Returns an array value from an array initializer expression. + /// + #[allow(clippy::too_many_arguments)] pub fn enforce_array_initializer>( &mut self, cs: &mut CS, @@ -142,65 +145,63 @@ impl> ConstrainedProgram { } Ok(value) + } else if expected_dimensions.first().eq(&actual_dimensions.first()) { + // Case 2 - enforce expression with updated array type. + let dimension = match expected_dimensions.remove_first() { + Some(number) => { + // Parse the array dimension into a `usize`. + parse_index(&number, &span)? + } + None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)), + }; + + // Update the actual array dimensions. + let _first_dimension = actual_dimensions.remove_first(); + + // Update the expected type to a new array type with the first dimension removed. + let expected_expression_type = Some(inner_array_type(*type_, expected_dimensions)); + + // If the expression has more dimensions. + let element_value = match actual_dimensions.first() { + Some(_dimension) => { + // Get the value of the array element as an initializer. + self.enforce_array_initializer( + cs, + file_scope, + function_scope, + expected_expression_type, + element_expression, + actual_dimensions.clone(), + span, + )? + } + None => { + // Get the value of the array element as an expression. + self.enforce_expression( + cs, + file_scope, + function_scope, + expected_expression_type, + element_expression, + )? + } + }; + + // Allocate the array of values. + let array_values = vec![element_value; dimension]; + + // Create a new value with the expected dimension. + Ok(ConstrainedValue::Array(array_values)) } else { - if expected_dimensions.first().eq(&actual_dimensions.first()) { - // Case 2 - enforce expression with updated array type. - let dimension = match expected_dimensions.remove_first() { - Some(number) => { - // Parse the array dimension into a `usize`. - parse_index(&number, &span)? - } - None => return Err(ExpressionError::unexpected_array(type_.to_string(), span)), - }; - - // Update the actual array dimensions. - let _first_dimension = actual_dimensions.remove_first(); - - // Update the expected type to a new array type with the first dimension removed. - let expected_expression_type = Some(inner_array_type(*type_, expected_dimensions)); - - // If the expression has more dimensions. - let element_value = match actual_dimensions.first() { - Some(_dimension) => { - // Get the value of the array element as an initializer. - self.enforce_array_initializer( - cs, - file_scope, - function_scope, - expected_expression_type, - element_expression, - actual_dimensions.clone(), - span.clone(), - )? - } - None => { - // Get the value of the array element as an expression. - self.enforce_expression( - cs, - file_scope, - function_scope, - expected_expression_type, - element_expression, - )? - } - }; - - // Allocate the array of values. - let array_values = vec![element_value; dimension]; - - // Create a new value with the expected dimension. - Ok(ConstrainedValue::Array(array_values)) - } else { - // Case 3 - return mismatched dimensions error. - Err(ExpressionError::invalid_first_dimension( - expected_dimensions - .first() - .ok_or(ExpressionError::undefined_first_dimension(span.clone()))?, - actual_dimensions - .first() - .ok_or(ExpressionError::undefined_first_dimension(span.clone()))?, - )) - } + // Case 3 - return mismatched dimensions error. + Err(ExpressionError::invalid_first_dimension( + expected_dimensions + .first() + .ok_or_else(|| ExpressionError::undefined_first_dimension(span.clone()))?, + actual_dimensions + .first() + .ok_or_else(|| ExpressionError::undefined_first_dimension(span))?, + )) } } else { // No explicit type given - evaluate array element expression. diff --git a/compiler/src/statement/assign/assign.rs b/compiler/src/statement/assign/assign.rs index c33bd43f79..8899c9b286 100644 --- a/compiler/src/statement/assign/assign.rs +++ b/compiler/src/statement/assign/assign.rs @@ -70,7 +70,7 @@ impl> ConstrainedProgram { *old_value = selected_value; - return Ok(()); + Ok(()) } else { match assignee.accesses[0].clone() { AssigneeAccess::Array(range_or_expression) => self.assign_array( diff --git a/compiler/src/statement/statement.rs b/compiler/src/statement/statement.rs index 6b3472c9b6..763ea328a7 100644 --- a/compiler/src/statement/statement.rs +++ b/compiler/src/statement/statement.rs @@ -28,11 +28,13 @@ pub type StatementResult = Result; pub type IndicatorAndConstrainedValue = (Option, ConstrainedValue); impl> ConstrainedProgram { + /// /// 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>( &mut self, diff --git a/imports/src/errors/import_parser.rs b/imports/src/errors/import_parser.rs index 5638e867cd..647a37a259 100644 --- a/imports/src/errors/import_parser.rs +++ b/imports/src/errors/import_parser.rs @@ -58,7 +58,7 @@ impl ImportParserError { /// Failed to convert a file path into an os string. /// 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) } diff --git a/imports/src/parser/import_parser.rs b/imports/src/parser/import_parser.rs index 58a2ca8f19..49b41f7533 100644 --- a/imports/src/parser/import_parser.rs +++ b/imports/src/parser/import_parser.rs @@ -26,23 +26,13 @@ use std::{ /// /// A program can import one or more packages. A package can be found locally in the source /// directory, foreign in the imports directory, or part of the core package list. -#[derive(Clone)] +#[derive(Clone, Default)] pub struct ImportParser { imports: HashMap, core_packages: HashSet, } impl ImportParser { - /// - /// Creates a new empty `ImportParser`. - /// - pub fn new() -> Self { - Self { - imports: HashMap::new(), - core_packages: HashSet::new(), - } - } - /// /// Inserts a (file name -> program) pair into the `ImportParser`. /// @@ -96,10 +86,10 @@ impl ImportParser { /// 3. Insert the typed syntax tree into the `ImportParser` /// pub fn parse(program: &Program) -> Result { - let mut imports = Self::new(); + let mut imports = Self::default(); // Find all imports relative to current directory. - let path = current_dir().map_err(|error| ImportParserError::current_directory_error(error))?; + let path = current_dir().map_err(ImportParserError::current_directory_error)?; // Parse each import statement. for import in &program.imports { diff --git a/symbol-table/src/errors/type_.rs b/symbol-table/src/errors/type_.rs index 030fce9c0f..c040fcc10a 100644 --- a/symbol-table/src/errors/type_.rs +++ b/symbol-table/src/errors/type_.rs @@ -46,7 +46,7 @@ impl TypeError { /// The `Self` keyword was used outside of a circuit. /// pub fn self_not_available(span: Span) -> Self { - let message = format!("Type `Self` is only available in circuit definitions and circuit functions."); + let message = "Type `Self` is only available in circuit definitions and circuit functions.".to_string(); Self::new_from_span(message, span) } diff --git a/symbol-table/src/symbol_table.rs b/symbol-table/src/symbol_table.rs index 2214e66b36..0e5a56b121 100644 --- a/symbol-table/src/symbol_table.rs +++ b/symbol-table/src/symbol_table.rs @@ -367,7 +367,7 @@ impl SymbolTable { self.check_function_names(&program.functions) } else { // Check for a symbol alias. - let identifier = symbol.alias.to_owned().unwrap_or(symbol.symbol.to_owned()); + let identifier = symbol.alias.to_owned().unwrap_or_else(|| symbol.symbol.to_owned()); // Check if the imported symbol is a circuit match program.circuits.get(&symbol.symbol) { diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs index ca96be17e7..0abdc87aa9 100644 --- a/symbol-table/src/types/functions/function.rs +++ b/symbol-table/src/types/functions/function.rs @@ -92,7 +92,7 @@ impl FunctionType { // Type check function output. let output = FunctionOutputType::new_from_circuit( table, - circuit_name.clone(), + circuit_name, unresolved_function.output, unresolved_function.span, )?; diff --git a/symbol-table/src/types/type_.rs b/symbol-table/src/types/type_.rs index 4f1721e9ea..304ffa083d 100644 --- a/symbol-table/src/types/type_.rs +++ b/symbol-table/src/types/type_.rs @@ -76,7 +76,7 @@ impl Type { // Lookup the circuit type in the symbol table let circuit_type = table .get_circuit_type(&identifier.name) - .ok_or(TypeError::undefined_circuit(identifier))?; + .ok_or_else(|| TypeError::undefined_circuit(identifier))?; Type::Circuit(circuit_type.identifier.clone()) } diff --git a/symbol-table/tests/mod.rs b/symbol-table/tests/mod.rs index 5e7646b25e..a0db2ba170 100644 --- a/symbol-table/tests/mod.rs +++ b/symbol-table/tests/mod.rs @@ -60,7 +60,7 @@ impl TestSymbolTable { let program = self.typed.into_repr(); // Create empty import parser. - let import_parser = ImportParser::new(); + let import_parser = ImportParser::default(); // Create empty input. let input = Input::new(); @@ -82,7 +82,7 @@ impl TestSymbolTable { let static_check = &mut SymbolTable::default(); // Create empty import parser. - let import_parser = ImportParser::new(); + let import_parser = ImportParser::default(); // Run pass one and expect an error. let error = static_check.check_names(&program, &import_parser).unwrap_err(); @@ -106,7 +106,7 @@ impl TestSymbolTable { let static_check = &mut SymbolTable::default(); // Create empty import parser. - let import_parser = ImportParser::new(); + let import_parser = ImportParser::default(); // Run the pass one and expect no errors. static_check.check_names(&program, &import_parser).unwrap(); diff --git a/type-inference/src/assertions/type_variable_pair.rs b/type-inference/src/assertions/type_variable_pair.rs index 6bfc25397e..e7cca2b2e6 100644 --- a/type-inference/src/assertions/type_variable_pair.rs +++ b/type-inference/src/assertions/type_variable_pair.rs @@ -85,8 +85,14 @@ impl TypeVariablePairs { /// pub fn push_pairs(&mut self, left: Type, right: Type, span: &Span) -> Result<(), TypeAssertionError> { match (left, right) { - (Type::TypeVariable(variable), type_) => Ok(self.push(variable, type_)), - (type_, Type::TypeVariable(variable)) => Ok(self.push(variable, type_)), + (Type::TypeVariable(variable), type_) => { + self.push(variable, type_); + Ok(()) + } + (type_, Type::TypeVariable(variable)) => { + self.push(variable, type_); + Ok(()) + } (Type::Array(left_type), Type::Array(right_type)) => self.push_pairs_array(*left_type, *right_type, span), (Type::Tuple(left_types), Type::Tuple(right_types)) => { self.push_pairs_tuple(left_types.into_iter(), right_types.into_iter(), span) diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index 7df352a404..7244cc3a19 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -302,7 +302,7 @@ impl Frame { }; // Assert that the expected type is equal to the actual type. - self.assert_equal(expected_type.clone(), actual_type.clone(), span) + self.assert_equal(expected_type, actual_type.clone(), span) } // Check for multiple defined variables. @@ -1128,7 +1128,7 @@ impl Frame { } // Return the function output type. - Ok(function_type.output.type_.clone()) + Ok(function_type.output.type_) } /// diff --git a/type-inference/src/type_inference.rs b/type-inference/src/type_inference.rs index ee485d1d47..087b82c82b 100644 --- a/type-inference/src/type_inference.rs +++ b/type-inference/src/type_inference.rs @@ -34,7 +34,7 @@ impl TypeInference { /// /// Evaluates all `TypeAssertion` predicates. /// - pub fn new(program: &Program, symbol_table: SymbolTable) -> Result<(), TypeInferenceError> { + pub fn run(program: &Program, symbol_table: SymbolTable) -> Result<(), TypeInferenceError> { let mut type_inference = Self { table: symbol_table, frames: Vec::new(), diff --git a/type-inference/tests/mod.rs b/type-inference/tests/mod.rs index 0753812059..f03a083711 100644 --- a/type-inference/tests/mod.rs +++ b/type-inference/tests/mod.rs @@ -53,7 +53,7 @@ impl TestTypeInference { let program = typed.into_repr(); // Create empty import parser. - let import_parser = ImportParser::new(); + let import_parser = ImportParser::default(); // Create empty input. let input = Input::new(); @@ -66,11 +66,11 @@ impl TestTypeInference { } pub fn check(self) { - TypeInference::new(&self.program, self.symbol_table).unwrap(); + TypeInference::run(&self.program, self.symbol_table).unwrap(); } pub fn expect_error(self) { - assert!(TypeInference::new(&self.program, self.symbol_table).is_err()); + assert!(TypeInference::run(&self.program, self.symbol_table).is_err()); } }