diff --git a/clarity/src/vm/analysis/contract_interface_builder/mod.rs b/clarity/src/vm/analysis/contract_interface_builder/mod.rs index c9bc3c71c1..63cf119933 100644 --- a/clarity/src/vm/analysis/contract_interface_builder/mod.rs +++ b/clarity/src/vm/analysis/contract_interface_builder/mod.rs @@ -237,14 +237,13 @@ pub struct ContractInterfaceFunctionArg { impl ContractInterfaceFunctionArg { pub fn from_function_args(fnArgs: &[FunctionArg]) -> Vec { - let mut args: Vec = Vec::new(); - for fnArg in fnArgs.iter() { - args.push(ContractInterfaceFunctionArg { + fnArgs + .iter() + .map(|fnArg| ContractInterfaceFunctionArg { name: fnArg.name.to_string(), type_f: ContractInterfaceAtomType::from_type_signature(&fnArg.signature), - }); - } - args + }) + .collect() } } diff --git a/clarity/src/vm/analysis/type_checker/v2_05/mod.rs b/clarity/src/vm/analysis/type_checker/v2_05/mod.rs index cc6d7e9064..7c6b587556 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/mod.rs @@ -526,7 +526,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { args: &[SymbolicExpression], context: &TypingContext, ) -> CheckResult> { - let mut result = Vec::new(); + let mut result = Vec::with_capacity(args.len()); for arg in args.iter() { // don't use map here, since type_check has side-effects. result.push(self.type_check(arg, context)?) diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs index 18663329f9..46830a8762 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs @@ -187,14 +187,11 @@ pub fn check_special_tuple_cons( context: &TypingContext, ) -> TypeResult { check_arguments_at_least(1, args)?; + let len = args.len(); - let mut tuple_type_data = Vec::new(); + runtime_cost(ClarityCostFunction::AnalysisCheckTupleCons, checker, len)?; - runtime_cost( - ClarityCostFunction::AnalysisCheckTupleCons, - checker, - args.len(), - )?; + let mut tuple_type_data = Vec::with_capacity(len); handle_binding_list(args, |var_name, var_sexp| { checker.type_check(var_sexp, context).and_then(|var_type| { diff --git a/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs b/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs index 49a29e8d38..81d52bb23d 100644 --- a/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs +++ b/clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs @@ -74,9 +74,10 @@ pub fn check_special_map( args.len(), )?; - let mut func_args = vec![]; + let iter = args[1..].iter(); + let mut func_args = Vec::with_capacity(iter.len()); let mut min_args = u32::MAX; - for arg in args[1..].iter() { + for arg in iter { let argument_type = checker.type_check(arg, context)?; let entry_type = match argument_type { TypeSignature::SequenceType(sequence) => { diff --git a/clarity/src/vm/analysis/type_checker/v2_1/mod.rs b/clarity/src/vm/analysis/type_checker/v2_1/mod.rs index 38cf3c7679..44aab0b4f2 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/mod.rs @@ -459,7 +459,7 @@ impl FunctionType { } } } else { - let mut arg_types = Vec::new(); + let mut arg_types = Vec::with_capacity(func_args.len()); for arg in func_args { arg_types.push(self.principal_to_callable_type(arg, 1, clarity_version)?); } @@ -1028,7 +1028,7 @@ impl<'a, 'b> TypeChecker<'a, 'b> { args: &[SymbolicExpression], context: &TypingContext, ) -> CheckResult> { - let mut result = Vec::new(); + let mut result = Vec::with_capacity(args.len()); for arg in args.iter() { // don't use map here, since type_check has side-effects. result.push(self.type_check(arg, context)?) diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs index fd1f456045..1c30eb7795 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/mod.rs @@ -195,7 +195,7 @@ pub fn check_special_tuple_cons( ) -> TypeResult { check_arguments_at_least(1, args)?; - let mut tuple_type_data = Vec::new(); + let mut tuple_type_data = Vec::with_capacity(args.len()); runtime_cost( ClarityCostFunction::AnalysisCheckTupleCons, diff --git a/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs b/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs index 9eb2ae17c9..52ceca66b6 100644 --- a/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs +++ b/clarity/src/vm/analysis/type_checker/v2_1/natives/sequences.rs @@ -74,9 +74,10 @@ pub fn check_special_map( args.len(), )?; - let mut func_args = vec![]; + let iter = args[1..].iter(); + let mut func_args = Vec::with_capacity(iter.len()); let mut min_args = u32::MAX; - for arg in args[1..].iter() { + for arg in iter { let argument_type = checker.type_check(arg, context)?; let entry_type = match argument_type { TypeSignature::SequenceType(sequence) => { diff --git a/clarity/src/vm/ast/definition_sorter/mod.rs b/clarity/src/vm/ast/definition_sorter/mod.rs index 36dfb21664..a48bfd0e34 100644 --- a/clarity/src/vm/ast/definition_sorter/mod.rs +++ b/clarity/src/vm/ast/definition_sorter/mod.rs @@ -91,14 +91,14 @@ impl DefinitionSorter { let sorted_indexes = walker.get_sorted_dependencies(&self.graph)?; if let Some(deps) = walker.get_cycling_dependencies(&self.graph, &sorted_indexes) { - let mut deps_props = vec![]; - for i in deps.iter() { - let exp = &contract_ast.pre_expressions[*i]; - if let Some(def) = self.find_expression_definition(exp) { - deps_props.push(def); - } - } - let functions_names = deps_props.iter().map(|i| i.0.to_string()).collect(); + let functions_names = deps + .into_iter() + .filter_map(|i| { + let exp = &contract_ast.pre_expressions[i]; + self.find_expression_definition(exp) + }) + .map(|i| i.0.to_string()) + .collect::>(); let error = ParseError::new(ParseErrors::CircularReference(functions_names)); return Err(error); diff --git a/clarity/src/vm/ast/parser/v2/mod.rs b/clarity/src/vm/ast/parser/v2/mod.rs index 75a622a7c0..6238af1383 100644 --- a/clarity/src/vm/ast/parser/v2/mod.rs +++ b/clarity/src/vm/ast/parser/v2/mod.rs @@ -894,12 +894,14 @@ impl<'a> Parser<'a> { Some(expr) } Token::Utf8String(s) => { - let mut data: Vec> = Vec::new(); - for ch in s.chars() { - let mut bytes = vec![0; ch.len_utf8()]; - ch.encode_utf8(&mut bytes); - data.push(bytes); - } + let data: Vec> = s + .chars() + .map(|ch| { + let mut bytes = vec![0; ch.len_utf8()]; + ch.encode_utf8(&mut bytes); + bytes + }) + .collect(); let val = Value::Sequence(SequenceData::String(CharType::UTF8(UTF8Data { data, diff --git a/clarity/src/vm/ast/sugar_expander/mod.rs b/clarity/src/vm/ast/sugar_expander/mod.rs index 481e1039dd..cf070548a8 100644 --- a/clarity/src/vm/ast/sugar_expander/mod.rs +++ b/clarity/src/vm/ast/sugar_expander/mod.rs @@ -65,7 +65,7 @@ impl SugarExpander { pre_exprs_iter: PreExpressionsDrain, contract_ast: &mut ContractAST, ) -> ParseResult> { - let mut expressions: Vec = Vec::new(); + let mut expressions: Vec = Vec::with_capacity(pre_exprs_iter.len()); #[cfg(feature = "developer-mode")] let mut comments = Vec::new(); diff --git a/clarity/src/vm/ast/types.rs b/clarity/src/vm/ast/types.rs index e8183220af..87ab844b85 100644 --- a/clarity/src/vm/ast/types.rs +++ b/clarity/src/vm/ast/types.rs @@ -95,6 +95,10 @@ impl PreExpressionsDrain { index: 0, } } + + pub fn len(&self) -> usize { + self.len + } } impl Iterator for PreExpressionsDrain { diff --git a/clarity/src/vm/coverage.rs b/clarity/src/vm/coverage.rs index 6f2de9f5c6..ea62981696 100644 --- a/clarity/src/vm/coverage.rs +++ b/clarity/src/vm/coverage.rs @@ -74,10 +74,11 @@ impl CoverageReporter { let f = File::create(filename)?; let mut coverage = HashMap::new(); for (contract, execution_map) in self.executed_lines.iter() { - let mut executed_lines = vec![]; - for (line, count) in execution_map.iter() { - executed_lines.push((*line, *count)); - } + let mut executed_lines = execution_map + .iter() + .map(|(line, count)| (*line, *count)) + .collect::>(); + executed_lines.sort_by_key(|f| f.0); coverage.insert(contract.to_string(), executed_lines); diff --git a/clarity/src/vm/docs/mod.rs b/clarity/src/vm/docs/mod.rs index 50ca695e46..205fdc6170 100644 --- a/clarity/src/vm/docs/mod.rs +++ b/clarity/src/vm/docs/mod.rs @@ -2609,20 +2609,18 @@ pub fn make_define_reference(define_type: &DefineFunctions) -> FunctionAPI { fn make_all_api_reference() -> ReferenceAPIs { let mut functions: Vec<_> = NativeFunctions::ALL .iter() - .map(|x| make_api_reference(x)) + .map(make_api_reference) .collect(); for data_type in DefineFunctions::ALL.iter() { functions.push(make_define_reference(data_type)) } functions.sort_by(|x, y| x.name.cmp(&y.name)); - let mut keywords = Vec::new(); - for variable in NativeVariables::ALL.iter() { - let output = make_keyword_reference(variable); - if let Some(api_ref) = output { - keywords.push(api_ref) - } - } + let mut keywords: Vec<_> = NativeVariables::ALL + .iter() + .filter_map(make_keyword_reference) + .collect(); + keywords.sort_by(|x, y| x.name.cmp(&y.name)); ReferenceAPIs { diff --git a/clarity/src/vm/functions/database.rs b/clarity/src/vm/functions/database.rs index d036dd27c2..e52ac57b54 100644 --- a/clarity/src/vm/functions/database.rs +++ b/clarity/src/vm/functions/database.rs @@ -75,9 +75,11 @@ pub fn special_contract_call( runtime_cost(ClarityCostFunction::ContractCall, env, 0)?; let function_name = args[1].match_atom().ok_or(CheckErrors::ExpectedName)?; - let mut rest_args = vec![]; - let mut rest_args_sizes = vec![]; - for arg in args[2..].iter() { + let rest_args_slice = &args[2..]; + let rest_args_len = rest_args_slice.len(); + let mut rest_args = Vec::with_capacity(rest_args_len); + let mut rest_args_sizes = Vec::with_capacity(rest_args_len); + for arg in rest_args_slice.iter() { let evaluated_arg = eval(arg, env, context)?; rest_args_sizes.push(evaluated_arg.size()? as u64); rest_args.push(SymbolicExpression::atom_value(evaluated_arg)); diff --git a/clarity/src/vm/functions/mod.rs b/clarity/src/vm/functions/mod.rs index a523db8643..7c3647c2f6 100644 --- a/clarity/src/vm/functions/mod.rs +++ b/clarity/src/vm/functions/mod.rs @@ -701,7 +701,7 @@ pub fn parse_eval_bindings( env: &mut Environment, context: &LocalContext, ) -> Result> { - let mut result = Vec::new(); + let mut result = Vec::with_capacity(bindings.len()); handle_binding_list(bindings, |var_name, var_sexp| { eval(var_sexp, env, context).map(|value| result.push((var_name.clone(), value))) })?; diff --git a/clarity/src/vm/mod.rs b/clarity/src/vm/mod.rs index 7231ad584d..45d71cf222 100644 --- a/clarity/src/vm/mod.rs +++ b/clarity/src/vm/mod.rs @@ -257,7 +257,7 @@ pub fn apply( resp } else { let mut used_memory = 0; - let mut evaluated_args = vec![]; + let mut evaluated_args = Vec::with_capacity(args.len()); env.call_stack.incr_apply_depth(); for arg_x in args.iter() { let arg_value = match eval(arg_x, env, context) { diff --git a/clarity/src/vm/types/mod.rs b/clarity/src/vm/types/mod.rs index 06eea08966..cc3cbeeba0 100644 --- a/clarity/src/vm/types/mod.rs +++ b/clarity/src/vm/types/mod.rs @@ -1034,12 +1034,14 @@ impl Value { Ok(string) => string, _ => return Err(CheckErrors::InvalidCharactersDetected.into()), }; - let mut data = vec![]; - for char in validated_utf8_str.chars() { - let mut encoded_char: Vec = vec![0; char.len_utf8()]; - char.encode_utf8(&mut encoded_char[..]); - data.push(encoded_char); - } + let data = validated_utf8_str + .chars() + .map(|char| { + let mut encoded_char = vec![0u8; char.len_utf8()]; + char.encode_utf8(&mut encoded_char); + encoded_char + }) + .collect::>(); // check the string size StringUTF8Length::try_from(data.len())?; diff --git a/clarity/src/vm/types/serialization.rs b/clarity/src/vm/types/serialization.rs index 32cf9cf9f1..69a662e6b7 100644 --- a/clarity/src/vm/types/serialization.rs +++ b/clarity/src/vm/types/serialization.rs @@ -1249,7 +1249,7 @@ impl Value { if l.len().ok()? > lt.get_max_len() { return None; } - let mut sanitized_items = vec![]; + let mut sanitized_items = Vec::with_capacity(l.data.len()); let mut did_sanitize_children = false; for item in l.data.into_iter() { let (sanitized_item, did_sanitize) = @@ -1266,11 +1266,12 @@ impl Value { TypeSignature::TupleType(tt) => tt, _ => return None, }; - let mut sanitized_tuple_entries = vec![]; + let type_map = tt.get_type_map(); + let mut sanitized_tuple_entries = Vec::with_capacity(type_map.len()); let original_tuple_len = tuple_data.len(); let mut tuple_data_map = tuple_data.data_map; let mut did_sanitize_children = false; - for (key, expect_key_type) in tt.get_type_map().iter() { + for (key, expect_key_type) in type_map.iter() { let field_data = tuple_data_map.remove(key)?; let (sanitized_field, did_sanitize) = Self::sanitize_value(epoch, expect_key_type, field_data)?; diff --git a/clarity/src/vm/types/signatures.rs b/clarity/src/vm/types/signatures.rs index f906ada188..c6838eb3fb 100644 --- a/clarity/src/vm/types/signatures.rs +++ b/clarity/src/vm/types/signatures.rs @@ -981,10 +981,12 @@ impl FunctionSignature { } pub fn canonicalize(&self, epoch: &StacksEpochId) -> FunctionSignature { - let mut canonicalized_args = vec![]; - for arg in &self.args { - canonicalized_args.push(arg.canonicalize(epoch)); - } + let canonicalized_args = self + .args + .iter() + .map(|arg| arg.canonicalize(epoch)) + .collect(); + FunctionSignature { args: canonicalized_args, returns: self.returns.canonicalize(epoch), @@ -1644,8 +1646,8 @@ impl TypeSignature { let fn_args_exprs = args[1] .match_list() .ok_or(CheckErrors::DefineTraitBadSignature)?; - let mut fn_args = vec![]; - for arg_type in fn_args_exprs.iter() { + let mut fn_args = Vec::with_capacity(fn_args_exprs.len()); + for arg_type in fn_args_exprs.into_iter() { let arg_t = TypeSignature::parse_type_repr(epoch, arg_type, accounting)?; fn_args.push(arg_t); } @@ -2064,8 +2066,9 @@ mod test { // set k = 4033 let first_tuple = TypeSignature::from_string("(tuple (a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 bool))", version, epoch); - let mut keys = vec![]; - for i in 0..4033 { + let len = 4033; + let mut keys = Vec::with_capacity(len); + for i in 0..len { let key_name = ClarityName::try_from(format!("a{:0127}", i)).unwrap(); let key_val = first_tuple.clone(); keys.push((key_name, key_val));