diff --git a/src/api/deprecated.rs b/src/api/deprecated.rs index 4dd7d703..dca53e94 100644 --- a/src/api/deprecated.rs +++ b/src/api/deprecated.rs @@ -1,7 +1,6 @@ //! Module containing all deprecated API that will be removed in the next major version. use crate::func::RegisterNativeFunction; -use crate::plugin::*; use crate::types::dynamic::Variant; use crate::{ Dynamic, Engine, EvalAltResult, FnPtr, Identifier, ImmutableString, Module, NativeCallContext, @@ -633,6 +632,9 @@ impl Module { } } +#[cfg(not(feature = "no_index"))] +use crate::plugin::*; + #[cfg(not(feature = "no_index"))] #[export_module] pub mod deprecated_array_functions { diff --git a/src/ast/expr.rs b/src/ast/expr.rs index bfb4a9ef..c8cdedb1 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -489,11 +489,13 @@ impl Expr { #[cfg(not(feature = "no_object"))] Self::Map(x, ..) if self.is_constant() => { - Dynamic::from_map(x.0.iter().fold(x.1.clone(), |mut map, (k, v)| { - let value_ref = map.get_mut(k.name.as_str()).unwrap(); - *value_ref = v.get_literal_value().unwrap(); - map - })) + let mut map = x.1.clone(); + + for (k, v) in &x.0 { + *map.get_mut(k.name.as_str()).unwrap() = v.get_literal_value().unwrap(); + } + + Dynamic::from_map(map) } // Interpolated string diff --git a/src/eval/data_check.rs b/src/eval/data_check.rs index 2b031bcd..57d3297a 100644 --- a/src/eval/data_check.rs +++ b/src/eval/data_check.rs @@ -18,23 +18,37 @@ impl Dynamic { /// Panics if any interior data is shared (should never happen). #[cfg(not(feature = "no_index"))] #[inline] - pub(crate) fn calc_array_sizes(array: &crate::Array, _top: bool) -> (usize, usize, usize) { - array - .iter() - .fold((0, 0, 0), |(ax, mx, sx), value| match value.0 { - Union::Array(..) => { - let (a, m, s) = value.calc_data_sizes(false); - (ax + a + 1, mx + m, sx + s) + pub(crate) fn calc_array_sizes(array: &crate::Array) -> (usize, usize, usize) { + let (mut ax, mut mx, mut sx) = (0, 0, 0); + + for value in array { + ax += 1; + + match value.0 { + Union::Array(ref a, ..) => { + let (a, m, s) = Self::calc_array_sizes(a); + ax += a; + mx += m; + sx += s; } - Union::Blob(ref a, ..) => (ax + 1 + a.len(), mx, sx), + Union::Blob(ref a, ..) => ax += 1 + a.len(), #[cfg(not(feature = "no_object"))] - Union::Map(..) => { - let (a, m, s) = value.calc_data_sizes(false); - (ax + a + 1, mx + m, sx + s) + Union::Map(ref m, ..) => { + let (a, m, s) = Self::calc_map_sizes(m); + ax += a; + mx += m; + sx += s; } - Union::Str(ref s, ..) => (ax + 1, mx, sx + s.len()), - _ => (ax + 1, mx, sx), - }) + Union::Str(ref s, ..) => sx += s.len(), + #[cfg(not(feature = "no_closure"))] + Union::Shared(..) => { + unreachable!("shared values discovered within data") + } + _ => (), + } + } + + (ax, mx, sx) } /// Recursively calculate the sizes of a map. /// @@ -45,23 +59,38 @@ impl Dynamic { /// Panics if any interior data is shared (should never happen). #[cfg(not(feature = "no_object"))] #[inline] - pub(crate) fn calc_map_sizes(map: &crate::Map, _top: bool) -> (usize, usize, usize) { - map.values() - .fold((0, 0, 0), |(ax, mx, sx), value| match value.0 { + pub(crate) fn calc_map_sizes(map: &crate::Map) -> (usize, usize, usize) { + let (mut ax, mut mx, mut sx) = (0, 0, 0); + + for value in map.values() { + mx += 1; + + match value.0 { #[cfg(not(feature = "no_index"))] - Union::Array(..) => { - let (a, m, s) = value.calc_data_sizes(false); - (ax + a, mx + m + 1, sx + s) + Union::Array(ref a, ..) => { + let (a, m, s) = Self::calc_array_sizes(a); + ax += a; + mx += m; + sx += s; } #[cfg(not(feature = "no_index"))] - Union::Blob(ref a, ..) => (ax + a.len(), mx, sx), - Union::Map(..) => { - let (a, m, s) = value.calc_data_sizes(false); - (ax + a, mx + m + 1, sx + s) + Union::Blob(ref a, ..) => ax += 1 + a.len(), + Union::Map(ref m, ..) => { + let (a, m, s) = Self::calc_map_sizes(m); + ax += a; + mx += m; + sx += s; } - Union::Str(ref s, ..) => (ax, mx + 1, sx + s.len()), - _ => (ax, mx + 1, sx), - }) + Union::Str(ref s, ..) => sx += s.len(), + #[cfg(not(feature = "no_closure"))] + Union::Shared(..) => { + unreachable!("shared values discovered within data") + } + _ => (), + } + } + + (ax, mx, sx) } /// Recursively calculate the sizes of a value. /// @@ -74,11 +103,11 @@ impl Dynamic { pub(crate) fn calc_data_sizes(&self, _top: bool) -> (usize, usize, usize) { match self.0 { #[cfg(not(feature = "no_index"))] - Union::Array(ref arr, ..) => Self::calc_array_sizes(&**arr, _top), + Union::Array(ref arr, ..) => Self::calc_array_sizes(&**arr), #[cfg(not(feature = "no_index"))] Union::Blob(ref blob, ..) => (blob.len(), 0, 0), #[cfg(not(feature = "no_object"))] - Union::Map(ref map, ..) => Self::calc_map_sizes(&**map, _top), + Union::Map(ref map, ..) => Self::calc_map_sizes(&**map), Union::Str(ref s, ..) => (0, 0, s.len()), #[cfg(not(feature = "no_closure"))] Union::Shared(..) if _top => self.read_lock::().unwrap().calc_data_sizes(true), diff --git a/src/eval/expr.rs b/src/eval/expr.rs index d04aec44..d99f7d41 100644 --- a/src/eval/expr.rs +++ b/src/eval/expr.rs @@ -286,7 +286,7 @@ impl Engine { Expr::InterpolatedString(x, _) => { let mut concat = SmartString::new_const(); - x.iter().try_for_each(|expr| -> RhaiResultOf<()> { + for expr in &**x { let item = &mut self .eval_expr(global, caches, scope, this_ptr.as_deref_mut(), expr)? .flatten(); @@ -304,9 +304,7 @@ impl Engine { #[cfg(not(feature = "unchecked"))] self.throw_on_size((0, 0, concat.len())) .map_err(|err| err.fill_position(pos))?; - - Ok(()) - })?; + } Ok(self.get_interned_string(concat).into()) } @@ -318,7 +316,7 @@ impl Engine { #[cfg(not(feature = "unchecked"))] let mut total_data_sizes = (0, 0, 0); - x.iter().try_for_each(|item_expr| -> RhaiResultOf<()> { + for item_expr in &**x { let value = self .eval_expr(global, caches, scope, this_ptr.as_deref_mut(), item_expr)? .flatten(); @@ -337,9 +335,7 @@ impl Engine { } array.push(value); - - Ok(()) - })?; + } Ok(Dynamic::from_array(array)) } @@ -351,28 +347,25 @@ impl Engine { #[cfg(not(feature = "unchecked"))] let mut total_data_sizes = (0, 0, 0); - x.0.iter() - .try_for_each(|(key, value_expr)| -> RhaiResultOf<()> { - let value = self - .eval_expr(global, caches, scope, this_ptr.as_deref_mut(), value_expr)? - .flatten(); + for (key, value_expr) in &x.0 { + let value = self + .eval_expr(global, caches, scope, this_ptr.as_deref_mut(), value_expr)? + .flatten(); - #[cfg(not(feature = "unchecked"))] - if self.has_data_size_limit() { - let delta = value.calc_data_sizes(true); - total_data_sizes = ( - total_data_sizes.0 + delta.0, - total_data_sizes.1 + delta.1 + 1, - total_data_sizes.2 + delta.2, - ); - self.throw_on_size(total_data_sizes) - .map_err(|err| err.fill_position(value_expr.position()))?; - } + #[cfg(not(feature = "unchecked"))] + if self.has_data_size_limit() { + let delta = value.calc_data_sizes(true); + total_data_sizes = ( + total_data_sizes.0 + delta.0, + total_data_sizes.1 + delta.1 + 1, + total_data_sizes.2 + delta.2, + ); + self.throw_on_size(total_data_sizes) + .map_err(|err| err.fill_position(value_expr.position()))?; + } - *map.get_mut(key.as_str()).unwrap() = value; - - Ok(()) - })?; + *map.get_mut(key.as_str()).unwrap() = value; + } Ok(Dynamic::from_map(map)) } diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 8bb47110..db2523ff 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -129,9 +129,9 @@ impl Engine { let OpAssignment { hash_op_assign, hash_op, - op_assign: op_assign_token, - op: op_token, - pos: op_pos, + op_assign, + op, + pos, } = op_info; let mut lock_guard = target.write_lock::().unwrap(); @@ -141,15 +141,15 @@ impl Engine { if self.fast_operators() { if let Some((func, need_context)) = - get_builtin_op_assignment_fn(op_assign_token.clone(), args[0], args[1]) + get_builtin_op_assignment_fn(op_assign.clone(), args[0], args[1]) { // Built-in found - let op = op_assign_token.literal_syntax(); auto_restore! { let orig_level = global.level; global.level += 1 } let context = if need_context { + let op = op_assign.literal_syntax(); let source = global.source(); - Some((self, op, source, &*global, *op_pos).into()) + Some((self, op, source, &*global, *pos).into()) } else { None }; @@ -157,23 +157,20 @@ impl Engine { } } - let op_assign = op_assign_token.literal_syntax(); - let op = op_token.literal_syntax(); - let token = Some(op_assign_token.clone()); + let token = Some(op_assign.clone()); + let op_assign = op_assign.literal_syntax(); - match self - .exec_native_fn_call(global, caches, op_assign, token, hash, args, true, *op_pos) + match self.exec_native_fn_call(global, caches, op_assign, token, hash, args, true, *pos) { Ok(_) => (), Err(err) if matches!(*err, ERR::ErrorFunctionNotFound(ref f, ..) if f.starts_with(op_assign)) => { // Expand to `var = var op rhs` - let token = Some(op_token.clone()); + let token = Some(op.clone()); + let op = op.literal_syntax(); *args[0] = self - .exec_native_fn_call( - global, caches, op, token, *hash_op, args, true, *op_pos, - )? + .exec_native_fn_call(global, caches, op, token, *hash_op, args, true, *pos)? .0; } Err(err) => return Err(err), @@ -864,25 +861,23 @@ impl Engine { // Share statement #[cfg(not(feature = "no_closure"))] Stmt::Share(x) => { - x.iter() - .try_for_each(|(name, index, pos)| { - index - .map(|n| scope.len() - n.get()) - .or_else(|| scope.search(name)) - .map_or_else( - || Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into()), - |index| { - let val = scope.get_mut_by_index(index); + for (name, index, pos) in &**x { + if let Some(index) = index + .map(|n| scope.len() - n.get()) + .or_else(|| scope.search(name)) + { + let val = scope.get_mut_by_index(index); - if !val.is_shared() { - // Replace the variable with a shared value. - *val = std::mem::take(val).into_shared(); - } - Ok(()) - }, - ) - }) - .map(|_| Dynamic::UNIT) + if !val.is_shared() { + // Replace the variable with a shared value. + *val = std::mem::take(val).into_shared(); + } + } else { + return Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into()); + } + } + + Ok(Dynamic::UNIT) } _ => unreachable!("statement cannot be evaluated: {:?}", stmt), diff --git a/src/func/call.rs b/src/func/call.rs index b25568df..f1f169c2 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -1118,12 +1118,11 @@ impl Engine { let mut fn_ptr = arg_value.cast::(); // Append the new curried arguments to the existing list. - a_expr.iter().try_for_each(|expr| -> Result<_, RhaiError> { + for expr in a_expr { let (value, ..) = self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?; fn_ptr.add_curry(value); - Ok(()) - })?; + } return Ok(fn_ptr.into()); } @@ -1229,14 +1228,11 @@ impl Engine { // If so, do it separately because we cannot convert the first argument (if it is a simple // variable access) to &mut because `scope` is needed. if capture_scope && !scope.is_empty() { - first_arg - .iter() - .copied() - .chain(a_expr.iter()) - .try_for_each(|expr| { - self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr) - .map(|(value, ..)| arg_values.push(value.flatten())) - })?; + for expr in first_arg.iter().copied().chain(a_expr.iter()) { + let (value, ..) = + self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?; + arg_values.push(value.flatten()); + } args.extend(curry.iter_mut()); args.extend(arg_values.iter_mut()); @@ -1265,10 +1261,11 @@ impl Engine { self.run_debugger(global, caches, scope, this_ptr.as_deref_mut(), first_expr)?; // func(x, ...) -> x.func(...) - a_expr.iter().try_for_each(|expr| { - self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr) - .map(|(value, ..)| arg_values.push(value.flatten())) - })?; + for expr in a_expr { + let (value, ..) = + self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?; + arg_values.push(value.flatten()); + } let mut target = self.search_namespace(global, caches, scope, this_ptr, first_expr)?; @@ -1289,13 +1286,11 @@ impl Engine { } } else { // func(..., ...) - first_arg - .into_iter() - .chain(a_expr.iter()) - .try_for_each(|expr| { - self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr) - .map(|(value, ..)| arg_values.push(value.flatten())) - })?; + for expr in first_arg.into_iter().chain(a_expr.iter()) { + let (value, ..) = + self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?; + arg_values.push(value.flatten()); + } args.extend(curry.iter_mut()); } @@ -1345,10 +1340,11 @@ impl Engine { // func(x, ...) -> x.func(...) arg_values.push(Dynamic::UNIT); - args_expr.iter().skip(1).try_for_each(|expr| { - self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr) - .map(|(value, ..)| arg_values.push(value.flatten())) - })?; + for expr in args_expr.iter().skip(1) { + let (value, ..) = + self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?; + arg_values.push(value.flatten()); + } // Get target reference to first argument let first_arg = &args_expr[0]; @@ -1374,10 +1370,11 @@ impl Engine { } } else { // func(..., ...) or func(mod::x, ...) - args_expr.iter().try_for_each(|expr| { - self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr) - .map(|(value, ..)| arg_values.push(value.flatten())) - })?; + for expr in args_expr { + let (value, ..) = + self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?; + arg_values.push(value.flatten()); + } args.extend(arg_values.iter_mut()); } } diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index b8396991..08c61b9e 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -237,7 +237,7 @@ pub mod array_functions { #[cfg(not(feature = "unchecked"))] if _ctx.engine().max_array_size() > 0 { let pad = len - array.len(); - let (a, m, s) = Dynamic::calc_array_sizes(array, true); + let (a, m, s) = Dynamic::calc_array_sizes(array); let (ax, mx, sx) = item.calc_data_sizes(true); _ctx.engine() diff --git a/src/parser.rs b/src/parser.rs index 39c51d67..6d58af31 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -546,11 +546,11 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, lib: &mut FnLib, + settings: ParseSettings, id: ImmutableString, no_args: bool, capture_parent_scope: bool, namespace: Namespace, - settings: ParseSettings, ) -> ParseResult { let (token, token_pos) = if no_args { &(Token::RightParen, Position::NONE) @@ -743,10 +743,10 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, lib: &mut FnLib, + settings: ParseSettings, lhs: Expr, options: ASTFlags, check_index_type: bool, - settings: ParseSettings, ) -> ParseResult { let mut settings = settings; @@ -869,7 +869,7 @@ impl Engine { _ => unreachable!("`[` or `?[`"), }; let idx_expr = self.parse_index_chain( - input, state, lib, idx_expr, options, false, settings, + input, state, lib, settings, idx_expr, options, false, )?; // Indexing binds to right Ok(Expr::Index( @@ -1307,8 +1307,8 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, lib: &mut FnLib, - is_property: bool, settings: ParseSettings, + is_property: bool, ) -> ParseResult { let (token, token_pos) = input.peek().expect(NEVER_ENDS); @@ -1460,7 +1460,7 @@ impl Engine { }; let result = - self.parse_anon_fn(input, new_state, state, lib, new_settings.level_up()?); + self.parse_anon_fn(input, new_state, lib, new_settings.level_up()?, state); // Restore the strings interner by swapping it back std::mem::swap(state.interned_strings, new_state.interned_strings); @@ -1468,28 +1468,22 @@ impl Engine { let (expr, fn_def) = result?; #[cfg(not(feature = "no_closure"))] - new_state - .external_vars - .as_deref() - .into_iter() - .flatten() - .try_for_each(|Ident { name, pos }| { - let (index, is_func) = state.access_var(name, lib, *pos); + for Ident { name, pos } in new_state.external_vars.as_deref().into_iter().flatten() + { + let (index, is_func) = state.access_var(name, lib, *pos); - if !is_func - && index.is_none() - && !settings.has_flag(ParseSettingFlags::CLOSURE_SCOPE) - && settings.has_option(LangOptions::STRICT_VAR) - && !state.scope.contains(name) - { - // If the parent scope is not inside another capturing closure - // then we can conclude that the captured variable doesn't exist. - // Under Strict Variables mode, this is not allowed. - Err(PERR::VariableUndefined(name.to_string()).into_err(*pos)) - } else { - Ok(()) - } - })?; + if !is_func + && index.is_none() + && !settings.has_flag(ParseSettingFlags::CLOSURE_SCOPE) + && settings.has_option(LangOptions::STRICT_VAR) + && !state.scope.contains(name) + { + // If the parent scope is not inside another capturing closure + // then we can conclude that the captured variable doesn't exist. + // Under Strict Variables mode, this is not allowed. + return Err(PERR::VariableUndefined(name.to_string()).into_err(*pos)); + } + } let hash_script = calc_fn_hash(None, &fn_def.name, fn_def.params.len()); lib.insert(hash_script, fn_def); @@ -1696,7 +1690,7 @@ impl Engine { return Ok(root_expr); } - self.parse_postfix(input, state, lib, root_expr, settings) + self.parse_postfix(input, state, lib, settings, root_expr) } /// Tail processing of all possible postfix operators of a primary expression. @@ -1705,8 +1699,8 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, lib: &mut FnLib, - mut lhs: Expr, settings: ParseSettings, + mut lhs: Expr, ) -> ParseResult { let mut settings = settings; @@ -1753,14 +1747,14 @@ impl Engine { let (.., ns, _, name) = *x; settings.pos = pos; - self.parse_fn_call(input, state, lib, name, no_args, true, ns, settings)? + self.parse_fn_call(input, state, lib, settings, name, no_args, true, ns)? } // Function call (Expr::Variable(x, .., pos), t @ (Token::LeftParen | Token::Unit)) => { let (.., ns, _, name) = *x; let no_args = t == Token::Unit; settings.pos = pos; - self.parse_fn_call(input, state, lib, name, no_args, false, ns, settings)? + self.parse_fn_call(input, state, lib, settings, name, no_args, false, ns)? } // module access #[cfg(not(feature = "no_module"))] @@ -1786,7 +1780,7 @@ impl Engine { _ => unreachable!("`[` or `?[`"), }; let settings = settings.level_up()?; - self.parse_index_chain(input, state, lib, expr, opt, true, settings)? + self.parse_index_chain(input, state, lib, settings, expr, opt, true)? } // Property access #[cfg(not(feature = "no_object"))] @@ -1807,7 +1801,7 @@ impl Engine { (.., pos) => return Err(PERR::PropertyExpected.into_err(*pos)), } - let rhs = self.parse_primary(input, state, lib, true, settings.level_up()?)?; + let rhs = self.parse_primary(input, state, lib, settings.level_up()?, true)?; let op_flags = match op { Token::Period => ASTFlags::NONE, Token::Elvis => ASTFlags::NEGATED, @@ -1984,7 +1978,7 @@ impl Engine { // Token::EOF => Err(PERR::UnexpectedEOF.into_err(settings.pos)), // All other tokens - _ => self.parse_primary(input, state, lib, false, settings), + _ => self.parse_primary(input, state, lib, settings, false), } } @@ -2234,9 +2228,9 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, lib: &mut FnLib, + settings: ParseSettings, parent_precedence: Option, lhs: Expr, - settings: ParseSettings, ) -> ParseResult { let mut settings = settings; settings.pos = lhs.position(); @@ -2294,7 +2288,7 @@ impl Engine { // If same precedence, then check if the operator binds right let rhs = if (precedence == next_precedence && bind_right) || precedence < next_precedence { - self.parse_binary_op(input, state, lib, precedence, rhs, settings)? + self.parse_binary_op(input, state, lib, settings, precedence, rhs)? } else { // Otherwise bind to left (even if next operator has the same precedence) rhs @@ -2629,7 +2623,7 @@ impl Engine { let precedence = Precedence::new(1); let settings = settings.level_up()?; let lhs = self.parse_unary(input, state, lib, settings)?; - self.parse_binary_op(input, state, lib, precedence, lhs, settings) + self.parse_binary_op(input, state, lib, settings, precedence, lhs) } /// Parse an if statement. @@ -2863,9 +2857,9 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, lib: &mut FnLib, + settings: ParseSettings, access: AccessMode, is_export: bool, - settings: ParseSettings, ) -> ParseResult { // let/const... (specified in `var_type`) let mut settings = settings; @@ -3016,7 +3010,7 @@ impl Engine { let pos = *pos; let settings = settings.level_up()?; let mut stmt = - self.parse_let(input, state, lib, AccessMode::ReadWrite, true, settings)?; + self.parse_let(input, state, lib, settings, AccessMode::ReadWrite, true)?; stmt.set_position(pos); return Ok(stmt); } @@ -3024,7 +3018,7 @@ impl Engine { let pos = *pos; let settings = settings.level_up()?; let mut stmt = - self.parse_let(input, state, lib, AccessMode::ReadOnly, true, settings)?; + self.parse_let(input, state, lib, settings, AccessMode::ReadOnly, true)?; stmt.set_position(pos); return Ok(stmt); } @@ -3344,8 +3338,8 @@ impl Engine { input, new_state, lib, - access, new_settings, + access, #[cfg(feature = "metadata")] comments, )?; @@ -3455,9 +3449,9 @@ impl Engine { Token::Try => self.parse_try_catch(input, state, lib, settings.level_up()?), - Token::Let => self.parse_let(input, state, lib, ReadWrite, false, settings.level_up()?), + Token::Let => self.parse_let(input, state, lib, settings.level_up()?, ReadWrite, false), Token::Const => { - self.parse_let(input, state, lib, ReadOnly, false, settings.level_up()?) + self.parse_let(input, state, lib, settings.level_up()?, ReadOnly, false) } #[cfg(not(feature = "no_module"))] @@ -3555,8 +3549,8 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, lib: &mut FnLib, - access: crate::FnAccess, settings: ParseSettings, + access: crate::FnAccess, #[cfg(feature = "metadata")] comments: impl IntoIterator, ) -> ParseResult { let settings = settings.level_up()?; @@ -3712,9 +3706,9 @@ impl Engine { &self, input: &mut TokenStream, state: &mut ParseState, - _parent: &mut ParseState, lib: &mut FnLib, settings: ParseSettings, + _parent: &mut ParseState, ) -> ParseResult<(Expr, Shared)> { let settings = settings.level_up()?; let mut params_list = StaticVec::::new_const(); diff --git a/src/types/fn_ptr.rs b/src/types/fn_ptr.rs index 83539f83..155eaa27 100644 --- a/src/types/fn_ptr.rs +++ b/src/types/fn_ptr.rs @@ -371,6 +371,7 @@ impl FnPtr { /// of arguments to call it directly (one version attaches extra arguments). #[cfg(not(feature = "internals"))] #[inline(always)] + #[allow(dead_code)] pub(crate) fn call_raw_with_extra_args( &self, fn_name: &str, diff --git a/src/types/interner.rs b/src/types/interner.rs index ce704bc4..118950cf 100644 --- a/src/types/interner.rs +++ b/src/types/interner.rs @@ -112,20 +112,22 @@ impl StringsInterner { // We leave at least two entries, one for the empty string, and one for the string // that has just been inserted. while self.cache.len() > MAX_INTERNED_STRINGS - 3 { - let (_, _, n) = self - .cache - .iter() - .fold((0, usize::MAX, 0), |(x, c, n), (&k, v)| { - if k != skip_hash - && (v.strong_count() < c || (v.strong_count() == c && v.len() > x)) - { - (v.len(), v.strong_count(), k) - } else { - (x, c, n) - } - }); + let mut max_len = 0; + let mut min_count = usize::MAX; + let mut index = 0; - self.cache.remove(&n); + for (&k, v) in &self.cache { + if k != skip_hash + && (v.strong_count() < min_count + || (v.strong_count() == min_count && v.len() > max_len)) + { + max_len = v.len(); + min_count = v.strong_count(); + index = k; + } + } + + self.cache.remove(&index); } }