From 2f948a784c262541bd10c892191ac9ffb7696f9a Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 27 Jul 2022 18:04:59 +0800 Subject: [PATCH] Clean up more clippy. --- codegen/src/attrs.rs | 6 +- src/api/custom_syntax.rs | 2 +- src/api/definitions/mod.rs | 29 +++--- src/api/json.rs | 1 + src/api/options.rs | 11 ++- src/api/register.rs | 24 +++-- src/api/run.rs | 2 +- src/api/type_names.rs | 6 +- src/ast/ast.rs | 15 +-- src/ast/expr.rs | 10 +- src/ast/ident.rs | 1 + src/ast/namespace.rs | 6 +- src/ast/script_fn.rs | 8 +- src/ast/stmt.rs | 4 +- src/engine.rs | 2 +- src/eval/debugger.rs | 7 +- src/eval/eval_context.rs | 4 +- src/eval/expr.rs | 4 +- src/eval/global_state.rs | 12 +-- src/eval/stmt.rs | 32 +++--- src/func/builtin.rs | 18 ++-- src/func/call.rs | 65 ++++++------- src/func/hashing.rs | 4 +- src/func/native.rs | 2 +- src/func/register.rs | 2 +- src/func/script.rs | 6 +- src/module/mod.rs | 151 +++++++++++++++-------------- src/module/resolvers/collection.rs | 2 +- src/module/resolvers/dummy.rs | 1 + src/module/resolvers/file.rs | 8 +- src/module/resolvers/stat.rs | 9 +- src/optimizer.rs | 45 ++++----- src/packages/array_basic.rs | 42 ++++---- src/packages/blob_basic.rs | 50 +++++----- src/packages/iter_basic.rs | 4 +- src/packages/lang_core.rs | 14 +-- src/packages/map_basic.rs | 10 +- src/packages/mod.rs | 1 + src/packages/string_more.rs | 32 +++--- src/parser.rs | 51 +++++----- src/serde/de.rs | 6 +- src/serde/metadata.rs | 2 +- src/tokenizer.rs | 32 +++--- src/types/dynamic.rs | 32 +++--- src/types/fn_ptr.rs | 8 +- src/types/immutable_string.rs | 5 +- src/types/scope.rs | 1 + 47 files changed, 412 insertions(+), 377 deletions(-) diff --git a/codegen/src/attrs.rs b/codegen/src/attrs.rs index dfdfc8a9..da376cf2 100644 --- a/codegen/src/attrs.rs +++ b/codegen/src/attrs.rs @@ -120,14 +120,14 @@ pub fn inner_item_attributes( // Find the #[rhai_fn] attribute which will turn be read for function parameters. if let Some(index) = attrs .iter() - .position(|a| a.path.get_ident().map(|i| *i == attr_name).unwrap_or(false)) + .position(|a| a.path.get_ident().map_or(false, |i| *i == attr_name)) { let rhai_fn_attr = attrs.remove(index); // Cannot have more than one #[rhai_fn] if let Some(duplicate) = attrs .iter() - .find(|a| a.path.get_ident().map(|i| *i == attr_name).unwrap_or(false)) + .find(|a| a.path.get_ident().map_or(false, |i| *i == attr_name)) { return Err(syn::Error::new( duplicate.span(), @@ -177,7 +177,7 @@ pub fn doc_attributes(attrs: &[syn::Attribute]) -> syn::Result> { pub fn collect_cfg_attr(attrs: &[syn::Attribute]) -> Vec { attrs .iter() - .filter(|&a| a.path.get_ident().map(|i| *i == "cfg").unwrap_or(false)) + .filter(|&a| a.path.get_ident().map_or(false, |i| *i == "cfg")) .cloned() .collect() } diff --git a/src/api/custom_syntax.rs b/src/api/custom_syntax.rs index 1ec9dd28..b84a0c26 100644 --- a/src/api/custom_syntax.rs +++ b/src/api/custom_syntax.rs @@ -252,7 +252,7 @@ impl Engine { } // Standard keyword in first position but not disabled _ if segments.is_empty() - && token.as_ref().map_or(false, |v| v.is_standard_keyword()) + && token.as_ref().map_or(false, Token::is_standard_keyword) && (self.disabled_symbols.is_empty() || !self.disabled_symbols.contains(s)) => { return Err(LexError::ImproperSymbol( diff --git a/src/api/definitions/mod.rs b/src/api/definitions/mod.rs index db44936f..d7342053 100644 --- a/src/api/definitions/mod.rs +++ b/src/api/definitions/mod.rs @@ -291,20 +291,18 @@ impl FuncInfo { } first = false; - let (param_name, param_type) = self - .metadata - .params_info - .get(i) - .map(|s| { - let mut s = s.splitn(2, ':'); - ( - s.next().unwrap_or("_").split(' ').last().unwrap(), - s.next() - .map(|ty| def_type_name(ty, def.engine)) - .unwrap_or(Cow::Borrowed("?")), - ) - }) - .unwrap_or(("_", "?".into())); + let (param_name, param_type) = + self.metadata + .params_info + .get(i) + .map_or(("_", "?".into()), |s| { + let mut s = s.splitn(2, ':'); + ( + s.next().unwrap_or("_").split(' ').last().unwrap(), + s.next() + .map_or(Cow::Borrowed("?"), |ty| def_type_name(ty, def.engine)), + ) + }); if operator { write!(writer, "{param_type}")?; @@ -338,8 +336,7 @@ fn def_type_name<'a>(ty: &'a str, engine: &'a Engine) -> Cow<'a, str> { let ty = ty .strip_prefix("RhaiResultOf<") .and_then(|s| s.strip_suffix('>')) - .map(str::trim) - .unwrap_or(ty); + .map_or(ty, str::trim); let ty = ty .replace("Iterator String { let mut result = String::from('{'); diff --git a/src/api/options.rs b/src/api/options.rs index 960c6424..4397e066 100644 --- a/src/api/options.rs +++ b/src/api/options.rs @@ -51,17 +51,20 @@ impl Engine { /// Is `if`-expression allowed? /// Default is `true`. #[inline(always)] + #[must_use] pub const fn allow_if_expression(&self) -> bool { self.options.contains(LangOptions::IF_EXPR) } /// Set whether `if`-expression is allowed. #[inline(always)] + #[must_use] pub fn set_allow_if_expression(&mut self, enable: bool) { - self.options.set(LangOptions::IF_EXPR, enable) + self.options.set(LangOptions::IF_EXPR, enable); } /// Is `switch` expression allowed? /// Default is `true`. #[inline(always)] + #[must_use] pub const fn allow_switch_expression(&self) -> bool { self.options.contains(LangOptions::SWITCH_EXPR) } @@ -73,6 +76,7 @@ impl Engine { /// Is statement-expression allowed? /// Default is `true`. #[inline(always)] + #[must_use] pub const fn allow_statement_expression(&self) -> bool { self.options.contains(LangOptions::STMT_EXPR) } @@ -87,6 +91,7 @@ impl Engine { /// Not available under `no_function`. #[cfg(not(feature = "no_function"))] #[inline(always)] + #[must_use] pub const fn allow_anonymous_fn(&self) -> bool { self.options.contains(LangOptions::ANON_FN) } @@ -101,6 +106,7 @@ impl Engine { /// Is looping allowed? /// Default is `true`. #[inline(always)] + #[must_use] pub const fn allow_looping(&self) -> bool { self.options.contains(LangOptions::LOOPING) } @@ -112,6 +118,7 @@ impl Engine { /// Is variables shadowing allowed? /// Default is `true`. #[inline(always)] + #[must_use] pub const fn allow_shadowing(&self) -> bool { self.options.contains(LangOptions::SHADOW) } @@ -123,6 +130,7 @@ impl Engine { /// Is strict variables mode enabled? /// Default is `false`. #[inline(always)] + #[must_use] pub const fn strict_variables(&self) -> bool { self.options.contains(LangOptions::STRICT_VAR) } @@ -137,6 +145,7 @@ impl Engine { /// Not available under `no_object`. #[cfg(not(feature = "no_object"))] #[inline(always)] + #[must_use] pub const fn fail_on_invalid_map_property(&self) -> bool { self.options .contains(LangOptions::FAIL_ON_INVALID_MAP_PROPERTY) diff --git a/src/api/register.rs b/src/api/register.rs index 485cec44..7a782229 100644 --- a/src/api/register.rs +++ b/src/api/register.rs @@ -70,7 +70,7 @@ impl Engine { #[cfg(feature = "metadata")] let param_type_names: crate::StaticVec<_> = - param_type_names.iter().map(|ty| ty.as_str()).collect(); + param_type_names.iter().map(String::as_str).collect(); #[cfg(feature = "metadata")] let param_type_names = Some(param_type_names.as_ref()); @@ -128,7 +128,7 @@ impl Engine { #[cfg(feature = "metadata")] let param_type_names: crate::StaticVec<_> = - param_type_names.iter().map(|ty| ty.as_str()).collect(); + param_type_names.iter().map(String::as_str).collect(); #[cfg(feature = "metadata")] let param_type_names = Some(param_type_names.as_ref()); @@ -989,16 +989,7 @@ impl Engine { let separator = crate::tokenizer::Token::DoubleColon.syntax(); let separator = separator.as_ref(); - if !name.contains(separator) { - if !module.is_indexed() { - // Index the module (making a clone copy if necessary) if it is not indexed - let mut module = crate::func::shared_take_or_clone(module); - module.build_index(); - root.insert(name.into(), module.into()); - } else { - root.insert(name.into(), module); - } - } else { + if name.contains(separator) { let mut iter = name.splitn(2, separator); let sub_module = iter.next().expect("contains separator").trim(); let remainder = iter.next().expect("contains separator").trim(); @@ -1015,6 +1006,13 @@ impl Engine { m.build_index(); root.insert(sub_module.into(), m.into()); } + } else if module.is_indexed() { + root.insert(name.into(), module); + } else { + // Index the module (making a clone copy if necessary) if it is not indexed + let mut module = crate::func::shared_take_or_clone(module); + module.build_index(); + root.insert(name.into(), module.into()); } } @@ -1039,7 +1037,7 @@ impl Engine { #[cfg(not(feature = "no_module"))] for (name, m) in &self.global_sub_modules { - signatures.extend(m.gen_fn_signatures().map(|f| format!("{}::{}", name, f))) + signatures.extend(m.gen_fn_signatures().map(|f| format!("{}::{}", name, f))); } signatures.extend( diff --git a/src/api/run.rs b/src/api/run.rs index 5352e761..babb3295 100644 --- a/src/api/run.rs +++ b/src/api/run.rs @@ -51,7 +51,7 @@ impl Engine { #[cfg(not(feature = "no_function"))] ast.as_ref(), ]; - let lib = if lib.first().map(|m: &&Module| m.is_empty()).unwrap_or(true) { + let lib = if lib.first().map_or(true, |m: &&Module| m.is_empty()) { &lib[0..0] } else { &lib diff --git a/src/api/type_names.rs b/src/api/type_names.rs index 8d333d7e..db63ffbd 100644 --- a/src/api/type_names.rs +++ b/src/api/type_names.rs @@ -147,10 +147,10 @@ impl Engine { if let Some(x) = name.strip_prefix("&mut ") { let r = self.format_type_name(x); - return if x != r { - format!("&mut {}", r).into() - } else { + return if x == r { name.into() + } else { + format!("&mut {}", r).into() }; } diff --git a/src/ast/ast.rs b/src/ast/ast.rs index 854ce431..fc9e3257 100644 --- a/src/ast/ast.rs +++ b/src/ast/ast.rs @@ -554,19 +554,19 @@ impl AST { lib }; - let mut _ast = if !other.source.is_empty() { + let mut _ast = if other.source.is_empty() { + Self::new( + merged, + #[cfg(not(feature = "no_function"))] + lib, + ) + } else { Self::new_with_source( merged, #[cfg(not(feature = "no_function"))] lib, other.source.clone(), ) - } else { - Self::new( - merged, - #[cfg(not(feature = "no_function"))] - lib, - ) }; #[cfg(not(feature = "no_module"))] @@ -977,6 +977,7 @@ impl Eq for ASTNode<'_> {} impl ASTNode<'_> { /// Get the [`Position`] of this [`ASTNode`]. + #[must_use] pub fn position(&self) -> Position { match self { ASTNode::Stmt(stmt) => stmt.position(), diff --git a/src/ast/expr.rs b/src/ast/expr.rs index edb66068..4d6a4b69 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -326,10 +326,10 @@ impl FromStr for FloatWrapper { #[cfg(not(feature = "no_float"))] impl FloatWrapper { /// Maximum floating-point number for natural display before switching to scientific notation. - pub const MAX_NATURAL_FLOAT_FOR_DISPLAY: f32 = 10000000000000.0; + pub const MAX_NATURAL_FLOAT_FOR_DISPLAY: f32 = 10_000_000_000_000.0; /// Minimum floating-point number for natural display before switching to scientific notation. - pub const MIN_NATURAL_FLOAT_FOR_DISPLAY: f32 = 0.0000000000001; + pub const MIN_NATURAL_FLOAT_FOR_DISPLAY: f32 = 0.000_000_000_000_1; /// Create a new [`FloatWrapper`]. #[inline(always)] @@ -728,10 +728,10 @@ impl Expr { match self { #[cfg(not(feature = "no_module"))] Self::Variable(x, ..) => { - if !x.1.is_empty() { - x.1.position() - } else { + if x.1.is_empty() { self.position() + } else { + x.1.position() } } diff --git a/src/ast/ident.rs b/src/ast/ident.rs index 4fb0d3f2..415de2bc 100644 --- a/src/ast/ident.rs +++ b/src/ast/ident.rs @@ -58,6 +58,7 @@ impl Ident { /// Get the name of the identifier as a string slice. #[inline(always)] + #[must_use] pub fn as_str(&self) -> &str { self.name.as_str() } diff --git a/src/ast/namespace.rs b/src/ast/namespace.rs index 9bf328dd..800dba52 100644 --- a/src/ast/namespace.rs +++ b/src/ast/namespace.rs @@ -42,7 +42,7 @@ impl fmt::Debug for Namespace { &self .path .iter() - .map(|m| m.as_str()) + .map(Ident::as_str) .collect::>() .join(Token::DoubleColon.literal_syntax()), ) @@ -59,7 +59,7 @@ impl fmt::Display for Namespace { &self .path .iter() - .map(|m| m.as_str()) + .map(Ident::as_str) .collect::>() .join(Token::DoubleColon.literal_syntax()), ) @@ -126,7 +126,7 @@ impl Namespace { /// Set the [`Scope`][crate::Scope] index offset. #[inline(always)] pub(crate) fn set_index(&mut self, index: Option) { - self.index = index + self.index = index; } /// Get the [position][Position] of this [`Namespace`]. /// diff --git a/src/ast/script_fn.rs b/src/ast/script_fn.rs index e7c44a87..f56a7450 100644 --- a/src/ast/script_fn.rs +++ b/src/ast/script_fn.rs @@ -2,7 +2,7 @@ #![cfg(not(feature = "no_function"))] use super::{FnAccess, StmtBlock}; -use crate::{Identifier, StaticVec}; +use crate::{Identifier, SmartString, StaticVec}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{fmt, hash::Hash}; @@ -71,7 +71,7 @@ impl fmt::Display for ScriptFnDef { self.name, self.params .iter() - .map(|s| s.as_str()) + .map(SmartString::as_str) .collect::>() .join(", ") ) @@ -120,7 +120,7 @@ impl fmt::Display for ScriptFnMetadata<'_> { self.name, self.params .iter() - .cloned() + .copied() .collect::>() .join(", ") ) @@ -132,7 +132,7 @@ impl<'a> From<&'a ScriptFnDef> for ScriptFnMetadata<'a> { fn from(value: &'a ScriptFnDef) -> Self { Self { name: &value.name, - params: value.params.iter().map(|s| s.as_str()).collect(), + params: value.params.iter().map(SmartString::as_str).collect(), access: value.access, #[cfg(feature = "metadata")] comments: value.comments.iter().map(<_>::as_ref).collect(), diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index 8f1e1f7e..e853701a 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -507,7 +507,7 @@ impl<'a> IntoIterator for &'a StmtBlock { impl Extend for StmtBlock { #[inline(always)] fn extend>(&mut self, iter: T) { - self.block.extend(iter) + self.block.extend(iter); } } @@ -799,7 +799,7 @@ impl Stmt { Self::For(x, ..) => x.2.is_pure() && x.3.iter().all(Stmt::is_pure), Self::Var(..) | Self::Assignment(..) | Self::FnCall(..) => false, - Self::Block(block, ..) => block.iter().all(|stmt| stmt.is_pure()), + Self::Block(block, ..) => block.iter().all(Stmt::is_pure), Self::BreakLoop(..) | Self::Return(..) => false, Self::TryCatch(x, ..) => { x.try_block.iter().all(Stmt::is_pure) && x.catch_block.iter().all(Stmt::is_pure) diff --git a/src/engine.rs b/src/engine.rs index 2589f309..c9c12eef 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -169,7 +169,7 @@ impl fmt::Debug for Engine { &self .custom_syntax .keys() - .map(|s| s.as_str()) + .map(crate::SmartString::as_str) .collect::(), ); diff --git a/src/eval/debugger.rs b/src/eval/debugger.rs index 69e55389..2198dda2 100644 --- a/src/eval/debugger.rs +++ b/src/eval/debugger.rs @@ -147,10 +147,10 @@ impl fmt::Display for BreakPoint { pos, enabled, } => { - if !source.is_empty() { - write!(f, "{} @ {:?}", source, pos)?; - } else { + if source.is_empty() { write!(f, "@ {:?}", pos)?; + } else { + write!(f, "{} @ {:?}", source, pos)?; } if !*enabled { f.write_str(" (disabled)")?; @@ -201,6 +201,7 @@ impl fmt::Display for BreakPoint { impl BreakPoint { /// Is this [`BreakPoint`] enabled? #[inline(always)] + #[must_use] pub fn is_enabled(&self) -> bool { match self { #[cfg(not(feature = "no_position"))] diff --git a/src/eval/eval_context.rs b/src/eval/eval_context.rs index e57b87a2..94cf564a 100644 --- a/src/eval/eval_context.rs +++ b/src/eval/eval_context.rs @@ -113,7 +113,7 @@ impl<'a, 's, 'ps, 'g, 'pg, 'c, 'pc, 't, 'pt> EvalContext<'a, 's, 'ps, 'g, 'pg, ' /// Get an iterator over the namespaces containing definition of all script-defined functions. #[inline] pub fn iter_namespaces(&self) -> impl Iterator { - self.lib.iter().cloned() + self.lib.iter().copied() } /// _(internals)_ The current set of namespaces containing definitions of all script-defined functions. /// Exported under the `internals` feature only. @@ -133,7 +133,7 @@ impl<'a, 's, 'ps, 'g, 'pg, 'c, 'pc, 't, 'pt> EvalContext<'a, 's, 'ps, 'g, 'pg, ' #[inline(always)] #[must_use] pub fn this_ptr_mut(&mut self) -> &mut Option<&'pt mut Dynamic> { - &mut self.this_ptr + self.this_ptr } /// The current nesting level of function calls. #[inline(always)] diff --git a/src/eval/expr.rs b/src/eval/expr.rs index 2980760e..b46367df 100644 --- a/src/eval/expr.rs +++ b/src/eval/expr.rs @@ -149,7 +149,7 @@ impl Engine { } _ if global.always_search_scope => (0, expr.start_position()), Expr::Variable(.., Some(i), pos) => (i.get() as usize, *pos), - Expr::Variable(v, None, pos) => (v.0.map(NonZeroUsize::get).unwrap_or(0), *pos), + Expr::Variable(v, None, pos) => (v.0.map_or(0, NonZeroUsize::get), *pos), _ => unreachable!("Expr::Variable expected but gets {:?}", expr), }; @@ -485,7 +485,7 @@ impl Engine { let custom_def = self.custom_syntax.get(key_token).ok_or_else(|| { Box::new(ERR::ErrorCustomSyntax( format!("Invalid custom syntax prefix: {}", key_token), - custom.tokens.iter().map(|s| s.to_string()).collect(), + custom.tokens.iter().map(<_>::to_string).collect(), *pos, )) })?; diff --git a/src/eval/global_state.rs b/src/eval/global_state.rs index 35b15416..225f724c 100644 --- a/src/eval/global_state.rs +++ b/src/eval/global_state.rs @@ -284,26 +284,26 @@ impl GlobalRuntimeState<'_> { #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[must_use] pub(crate) fn hash_idx_get(&mut self) -> u64 { - if self.fn_hash_indexing != (0, 0) { - self.fn_hash_indexing.0 - } else { + if self.fn_hash_indexing == (0, 0) { let n1 = crate::calc_fn_hash(crate::engine::FN_IDX_GET, 2); let n2 = crate::calc_fn_hash(crate::engine::FN_IDX_SET, 3); self.fn_hash_indexing = (n1, n2); n1 + } else { + self.fn_hash_indexing.0 } } /// Get the pre-calculated index setter hash. #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[must_use] pub(crate) fn hash_idx_set(&mut self) -> u64 { - if self.fn_hash_indexing != (0, 0) { - self.fn_hash_indexing.1 - } else { + if self.fn_hash_indexing == (0, 0) { let n1 = crate::calc_fn_hash(crate::engine::FN_IDX_GET, 2); let n2 = crate::calc_fn_hash(crate::engine::FN_IDX_SET, 3); self.fn_hash_indexing = (n1, n2); n2 + } else { + self.fn_hash_indexing.1 } } } diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 86a06e04..9154a92e 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -368,21 +368,21 @@ impl Engine { match guard_val { Ok(true) => { - if !if_block.is_empty() { + if if_block.is_empty() { + Ok(Dynamic::UNIT) + } else { self.eval_stmt_block( scope, global, caches, lib, this_ptr, if_block, true, level, ) - } else { - Ok(Dynamic::UNIT) } } Ok(false) => { - if !else_block.is_empty() { + if else_block.is_empty() { + Ok(Dynamic::UNIT) + } else { self.eval_stmt_block( scope, global, caches, lib, this_ptr, else_block, true, level, ) - } else { - Ok(Dynamic::UNIT) } } err => err.map(Into::into), @@ -510,7 +510,10 @@ impl Engine { Stmt::While(x, ..) if matches!(x.0, Expr::Unit(..)) => loop { let (.., body) = &**x; - if !body.is_empty() { + if body.is_empty() { + #[cfg(not(feature = "unchecked"))] + self.inc_operations(&mut global.num_operations, body.position())?; + } else { match self .eval_stmt_block(scope, global, caches, lib, this_ptr, body, true, level) { @@ -521,9 +524,6 @@ impl Engine { _ => break Err(err), }, } - } else { - #[cfg(not(feature = "unchecked"))] - self.inc_operations(&mut global.num_operations, body.position())?; } }, @@ -624,11 +624,11 @@ impl Engine { if let Some(func) = func { // Add the loop variables let orig_scope_len = scope.len(); - let counter_index = if !counter.is_empty() { + let counter_index = if counter.is_empty() { + usize::MAX + } else { scope.push(counter.name.clone(), 0 as INT); scope.len() - 1 - } else { - usize::MAX }; scope.push(var_name.name.clone(), ()); @@ -979,13 +979,13 @@ impl Engine { if let Ok(module) = module_result { if !export.is_empty() { - if !module.is_indexed() { + if module.is_indexed() { + global.push_import(export.name.clone(), module); + } else { // Index the module (making a clone copy if necessary) if it is not indexed let mut m = crate::func::shared_take_or_clone(module); m.build_index(); global.push_import(export.name.clone(), m); - } else { - global.push_import(export.name.clone(), module); } } diff --git a/src/func/builtin.rs b/src/func/builtin.rs index 3e728764..2214cfda 100644 --- a/src/func/builtin.rs +++ b/src/func/builtin.rs @@ -287,7 +287,7 @@ pub fn get_builtin_binary_op_fn(op: &str, x: &Dynamic, y: &Dynamic) -> Option Some(|_, args| { let blob = &*args[0].read_lock::().expect(BUILTIN); - let x = (args[1].as_int().expect("`INT`") & 0x000000ff) as u8; + let x = (args[1].as_int().expect("`INT`") & 0x0000_00ff) as u8; Ok((!blob.is_empty() && blob.contains(&x)).into()) }), _ => None, @@ -517,16 +517,14 @@ pub fn get_builtin_binary_op_fn(op: &str, x: &Dynamic, y: &Dynamic) -> Option().expect(BUILTIN); let blob2 = &*args[1].read_lock::().expect(BUILTIN); - Ok(Dynamic::from_blob(if !blob2.is_empty() { - if blob1.is_empty() { - blob2.clone() - } else { - let mut blob = blob1.clone(); - blob.extend(blob2); - blob - } - } else { + Ok(Dynamic::from_blob(if blob2.is_empty() { blob1.clone() + } else if blob1.is_empty() { + blob2.clone() + } else { + let mut blob = blob1.clone(); + blob.extend(blob2); + blob })) }), "==" => Some(impl_op!(Blob == Blob)), diff --git a/src/func/call.rs b/src/func/call.rs index 44fbea99..fd1545b8 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -140,10 +140,10 @@ impl Engine { #[cfg(not(feature = "no_module"))] let (ns, sep) = ( namespace.to_string(), - if !namespace.is_empty() { - crate::tokenizer::Token::DoubleColon.literal_syntax() - } else { + if namespace.is_empty() { "" + } else { + crate::tokenizer::Token::DoubleColon.literal_syntax() }, ); #[cfg(feature = "no_module")] @@ -169,7 +169,7 @@ impl Engine { /// /// Search order: /// 1) AST - script functions in the AST - /// 2) Global namespace - functions registered via Engine::register_XXX + /// 2) Global namespace - functions registered via `Engine::register_XXX` /// 3) Global registered modules - packages /// 4) Imported modules - functions marked with global namespace /// 5) Static registered modules @@ -280,16 +280,7 @@ impl Engine { } return args.and_then(|args| { - if !is_op_assignment { - get_builtin_binary_op_fn(fn_name, args[0], args[1]).map(|f| { - FnResolutionCacheEntry { - func: CallableFunction::from_method( - Box::new(f) as Box - ), - source: None, - } - }) - } else { + if is_op_assignment { let (first_arg, rest_args) = args.split_first().unwrap(); get_builtin_op_assignment_fn(fn_name, *first_arg, rest_args[0]).map( @@ -300,6 +291,15 @@ impl Engine { source: None, }, ) + } else { + get_builtin_binary_op_fn(fn_name, args[0], args[1]).map(|f| { + FnResolutionCacheEntry { + func: CallableFunction::from_method( + Box::new(f) as Box + ), + source: None, + } + }) } }); } @@ -312,11 +312,11 @@ impl Engine { .enumerate() .map(|(i, a)| { let mask = 1usize << (num_args - i - 1); - if bitmask & mask != 0 { + if bitmask & mask == 0 { + a.type_id() + } else { // Replace with `Dynamic` TypeId::of::() - } else { - a.type_id() } }), ); @@ -371,7 +371,7 @@ impl Engine { ); if func.is_some() { - let is_method = func.map(|f| f.func.is_method()).unwrap_or(false); + let is_method = func.map_or(false, |f| f.func.is_method()); // Push a new call stack frame #[cfg(feature = "debugging")] @@ -680,8 +680,7 @@ impl Engine { &mut global.source, source .as_ref() - .map(|s| (**s).clone()) - .unwrap_or(crate::Identifier::new_const()), + .map_or(crate::Identifier::new_const(), |s| (**s).clone()), ); let result = if _is_method_call { @@ -841,14 +840,12 @@ impl Engine { ) } KEYWORD_FN_PTR_CALL => { - if !call_args.is_empty() { - if !call_args[0].is::() { - let typ = self.map_type_name(call_args[0].type_name()); - return Err(self.make_type_mismatch_err::(typ, first_arg_pos)); - } - } else { + if call_args.is_empty() { let typ = self.map_type_name(target.type_name()); return Err(self.make_type_mismatch_err::(typ, fn_call_pos)); + } else if !call_args[0].is::() { + let typ = self.map_type_name(call_args[0].type_name()); + return Err(self.make_type_mismatch_err::(typ, first_arg_pos)); } // FnPtr call on object @@ -1036,10 +1033,10 @@ impl Engine { // Recalculate hash let args_len = total_args + curry.len(); - hashes = if !hashes.is_native_only() { - calc_fn_hash(name, args_len).into() - } else { + hashes = if hashes.is_native_only() { FnCallHashes::from_native(calc_fn_hash(name, args_len)) + } else { + calc_fn_hash(name, args_len).into() }; } // Handle Fn() @@ -1236,7 +1233,7 @@ impl Engine { if target_is_shared || target.is_temp_value() { arg_values.insert(0, target.take_or_clone().flatten()); - args.extend(arg_values.iter_mut()) + args.extend(arg_values.iter_mut()); } else { // Turn it into a method call only if the object is not shared and not a simple value is_ref_mut = true; @@ -1370,11 +1367,11 @@ impl Engine { while bitmask < max_bitmask { let hash_params = calc_fn_params_hash(args.iter().enumerate().map(|(i, a)| { let mask = 1usize << (num_args - i - 1); - if bitmask & mask != 0 { + if bitmask & mask == 0 { + a.type_id() + } else { // Replace with `Dynamic` TypeId::of::() - } else { - a.type_id() } })); let hash_qualified_fn = combine_hashes(hash, hash_params); @@ -1392,7 +1389,7 @@ impl Engine { } // Clone first argument if the function is not a method after-all - if !func.map(|f| f.is_method()).unwrap_or(true) { + if !func.map_or(true, CallableFunction::is_method) { if let Some(first) = first_arg_value { *first = args[0].clone(); args[0] = first; diff --git a/src/func/hashing.rs b/src/func/hashing.rs index 32908661..108b1035 100644 --- a/src/func/hashing.rs +++ b/src/func/hashing.rs @@ -47,7 +47,7 @@ impl Hasher for StraightHasher { self.0 = u64::from_ne_bytes(key); if self.0 == 0 { - self.0 = ALT_ZERO_HASH + self.0 = ALT_ZERO_HASH; } } } @@ -175,7 +175,7 @@ pub fn calc_fn_params_hash(params: impl IntoIterator) -> u64 { let mut len = 0; params.into_iter().for_each(|t| { len += 1; - t.hash(s) + t.hash(s); }); len.hash(s); diff --git a/src/func/native.rs b/src/func/native.rs index b8604786..a69ca830 100644 --- a/src/func/native.rs +++ b/src/func/native.rs @@ -252,7 +252,7 @@ impl<'a> NativeCallContext<'a> { /// in reverse order. #[inline] pub fn iter_namespaces(&self) -> impl Iterator { - self.lib.iter().rev().cloned() + self.lib.iter().rev().copied() } /// _(internals)_ The current set of namespaces containing definitions of all script-defined functions. /// Exported under the `internals` feature only. diff --git a/src/func/register.rs b/src/func/register.rs index 6417a224..41944cf6 100644 --- a/src/func/register.rs +++ b/src/func/register.rs @@ -28,7 +28,7 @@ use std::{any::TypeId, mem}; pub struct Mut(T); //pub struct Ref(T); -/// Dereference into DynamicWriteLock +/// Dereference into [`DynamicWriteLock`] #[inline(always)] #[must_use] pub fn by_ref(data: &mut Dynamic) -> DynamicWriteLock { diff --git a/src/func/script.rs b/src/func/script.rs index 6fd3da58..5202e61a 100644 --- a/src/func/script.rs +++ b/src/func/script.rs @@ -128,7 +128,7 @@ impl Engine { } else { caches.push_fn_resolution_cache(); lib_merged.push(&**fn_lib); - lib_merged.extend(lib.iter().cloned()); + lib_merged.extend(lib.iter().copied()); &lib_merged }, Some(mem::replace(&mut global.constants, constants.clone())), @@ -205,7 +205,7 @@ impl Engine { scope.rewind(orig_scope_len); } else if !args.is_empty() { // Remove arguments only, leaving new variables in the scope - scope.remove_range(orig_scope_len, args.len()) + scope.remove_range(orig_scope_len, args.len()); } #[cfg(not(feature = "no_module"))] global.truncate_imports(orig_imports_len); @@ -233,7 +233,7 @@ impl Engine { ) -> bool { let cache = caches.fn_resolution_cache_mut(); - if let Some(result) = cache.get(&hash_script).map(|v| v.is_some()) { + if let Some(result) = cache.get(&hash_script).map(Option::is_some) { return result; } diff --git a/src/module/mod.rs b/src/module/mod.rs index d9d6bd4a..76e5428d 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -8,7 +8,7 @@ use crate::func::{ use crate::types::{dynamic::Variant, CustomTypesCollection}; use crate::{ calc_fn_hash, calc_fn_params_hash, calc_qualified_fn_hash, combine_hashes, Dynamic, Identifier, - ImmutableString, NativeCallContext, RhaiResultOf, Shared, StaticVec, + ImmutableString, NativeCallContext, RhaiResultOf, Shared, SmartString, StaticVec, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -181,7 +181,15 @@ impl FuncInfo { let return_type = Self::format_type(&self.metadata.return_type, true); - if !self.metadata.params_info.is_empty() { + if self.metadata.params_info.is_empty() { + for x in 0..self.metadata.params { + sig.push('_'); + if x < self.metadata.params - 1 { + sig.push_str(", "); + } + } + sig.push(')'); + } else { let params: StaticVec<_> = self .metadata .params_info @@ -203,14 +211,6 @@ impl FuncInfo { .collect(); sig.push_str(¶ms.join(", ")); sig.push(')'); - } else { - for x in 0..self.metadata.params { - sig.push('_'); - if x < self.metadata.params - 1 { - sig.push_str(", "); - } - } - sig.push(')'); } if !self.func.is_script() && !return_type.is_empty() { @@ -238,7 +238,7 @@ pub fn calc_native_fn_hash<'a>( params: &[TypeId], ) -> u64 { let hash_script = calc_qualified_fn_hash(modules, fn_name, params.len()); - let hash_params = calc_fn_params_hash(params.iter().cloned()); + let hash_params = calc_fn_params_hash(params.iter().copied()); combine_hashes(hash_script, hash_params) } @@ -298,7 +298,7 @@ impl fmt::Debug for Module { &self .modules .keys() - .map(|m| m.as_str()) + .map(SmartString::as_str) .collect::>(), ) .field("vars", &self.variables) @@ -584,6 +584,7 @@ impl Module { /// assert_eq!(module.get_custom_type(name), Some("MyType")); /// ``` #[inline(always)] + #[must_use] pub fn get_custom_type(&self, key: &str) -> Option<&str> { self.custom_types.get(key) } @@ -647,7 +648,7 @@ impl Module { FnAccess::Public => true, FnAccess::Private => false, }) - .map(|f| f.gen_signature()) + .map(FuncInfo::gen_signature) } /// Does a variable exist in the [`Module`]? @@ -663,10 +664,10 @@ impl Module { #[inline(always)] #[must_use] pub fn contains_var(&self, name: &str) -> bool { - if !self.variables.is_empty() { - self.variables.contains_key(name) - } else { + if self.variables.is_empty() { false + } else { + self.variables.contains_key(name) } } @@ -699,10 +700,10 @@ impl Module { #[inline(always)] #[must_use] pub fn get_var(&self, name: &str) -> Option { - if !self.variables.is_empty() { - self.variables.get(name).cloned() - } else { + if self.variables.is_empty() { None + } else { + self.variables.get(name).cloned() } } @@ -739,10 +740,10 @@ impl Module { #[cfg(not(feature = "no_module"))] #[inline] pub(crate) fn get_qualified_var(&self, hash_var: u64) -> Option { - if !self.all_variables.is_empty() { - self.all_variables.get(&hash_var).cloned() - } else { + if self.all_variables.is_empty() { None + } else { + self.all_variables.get(&hash_var).cloned() } } @@ -794,14 +795,14 @@ impl Module { name: impl AsRef, num_params: usize, ) -> Option<&Shared> { - if !self.functions.is_empty() { + if self.functions.is_empty() { + None + } else { let name = name.as_ref(); self.iter_fn() .find(|f| f.metadata.params == num_params && f.metadata.name == name) .and_then(|f| f.func.get_script_fn_def()) - } else { - None } } @@ -840,10 +841,10 @@ impl Module { #[inline(always)] #[must_use] pub fn contains_sub_module(&self, name: &str) -> bool { - if !self.modules.is_empty() { - self.modules.contains_key(name) - } else { + if self.modules.is_empty() { false + } else { + self.modules.contains_key(name) } } @@ -861,10 +862,10 @@ impl Module { #[inline] #[must_use] pub fn get_sub_module(&self, name: &str) -> Option<&Module> { - if !self.modules.is_empty() { - self.modules.get(name).map(|m| &**m) - } else { + if self.modules.is_empty() { None + } else { + self.modules.get(name).map(|m| &**m) } } @@ -908,10 +909,10 @@ impl Module { #[inline(always)] #[must_use] pub fn contains_fn(&self, hash_fn: u64) -> bool { - if !self.functions.is_empty() { - self.functions.contains_key(&hash_fn) - } else { + if self.functions.is_empty() { false + } else { + self.functions.contains_key(&hash_fn) } } @@ -1061,7 +1062,7 @@ impl Module { let mut param_types: StaticVec<_> = arg_types .as_ref() .iter() - .cloned() + .copied() .enumerate() .map(|(i, type_id)| Self::map_type(!is_method || i > 0, type_id)) .collect(); @@ -1327,8 +1328,10 @@ impl Module { where A: Variant + Clone, T: Variant + Clone, - F: RegisterNativeFunction>, - F: Fn(&mut A) -> RhaiResultOf + SendSync + 'static, + F: RegisterNativeFunction> + + Fn(&mut A) -> RhaiResultOf + + SendSync + + 'static, { self.set_fn( crate::engine::make_getter(name.as_ref()).as_str(), @@ -1369,8 +1372,10 @@ impl Module { where A: Variant + Clone, B: Variant + Clone, - F: RegisterNativeFunction>, - F: Fn(&mut A, B) -> RhaiResultOf<()> + SendSync + 'static, + F: RegisterNativeFunction> + + Fn(&mut A, B) -> RhaiResultOf<()> + + SendSync + + 'static, { self.set_fn( crate::engine::make_setter(name.as_ref()).as_str(), @@ -1416,8 +1421,10 @@ impl Module { A: Variant + Clone, B: Variant + Clone, T: Variant + Clone, - F: RegisterNativeFunction>, - F: Fn(&mut A, B) -> RhaiResultOf + SendSync + 'static, + F: RegisterNativeFunction> + + Fn(&mut A, B) -> RhaiResultOf + + SendSync + + 'static, { #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { @@ -1478,8 +1485,10 @@ impl Module { A: Variant + Clone, B: Variant + Clone, C: Variant + Clone, - F: RegisterNativeFunction>, - F: Fn(&mut A, B, C) -> RhaiResultOf<()> + SendSync + 'static, + F: RegisterNativeFunction> + + Fn(&mut A, B, C) -> RhaiResultOf<()> + + SendSync + + 'static, { #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { @@ -1563,10 +1572,10 @@ impl Module { #[inline] #[must_use] pub(crate) fn get_fn(&self, hash_native: u64) -> Option<&CallableFunction> { - if !self.functions.is_empty() { - self.functions.get(&hash_native).map(|f| &f.func) - } else { + if self.functions.is_empty() { None + } else { + self.functions.get(&hash_native).map(|f| &f.func) } } @@ -1574,10 +1583,10 @@ impl Module { #[inline(always)] #[must_use] pub(crate) fn contains_dynamic_fn(&self, hash_script: u64) -> bool { - if !self.dynamic_functions.is_empty() { - self.dynamic_functions.contains(&hash_script) - } else { + if self.dynamic_functions.is_empty() { false + } else { + self.dynamic_functions.contains(&hash_script) } } @@ -1587,10 +1596,10 @@ impl Module { #[inline(always)] #[must_use] pub fn contains_qualified_fn(&self, hash_fn: u64) -> bool { - if !self.all_functions.is_empty() { - self.all_functions.contains_key(&hash_fn) - } else { + if self.all_functions.is_empty() { false + } else { + self.all_functions.contains_key(&hash_fn) } } @@ -1601,10 +1610,10 @@ impl Module { #[inline] #[must_use] pub(crate) fn get_qualified_fn(&self, hash_qualified_fn: u64) -> Option<&CallableFunction> { - if !self.all_functions.is_empty() { - self.all_functions.get(&hash_qualified_fn) - } else { + if self.all_functions.is_empty() { None + } else { + self.all_functions.get(&hash_qualified_fn) } } @@ -1683,7 +1692,7 @@ impl Module { self.functions.entry(k).or_insert_with(|| v.clone()); } self.dynamic_functions - .extend(other.dynamic_functions.iter().cloned()); + .extend(other.dynamic_functions.iter().copied()); for (&k, v) in &other.type_iterators { self.type_iterators.entry(k).or_insert_with(|| v.clone()); } @@ -1745,7 +1754,7 @@ impl Module { ); // This may introduce entries that are superfluous because the function has been filtered away. self.dynamic_functions - .extend(other.dynamic_functions.iter().cloned()); + .extend(other.dynamic_functions.iter().copied()); self.type_iterators .extend(other.type_iterators.iter().map(|(&k, v)| (k, v.clone()))); @@ -2145,14 +2154,14 @@ impl Module { if !f.func.is_script() { let hash_qualified_fn = calc_native_fn_hash( - path.iter().cloned(), + path.iter().copied(), f.metadata.name.as_str(), &f.param_types, ); functions.insert(hash_qualified_fn, f.func.clone()); } else if cfg!(not(feature = "no_function")) { let hash_qualified_script = crate::calc_qualified_fn_hash( - path.iter().cloned(), + path.iter().copied(), f.metadata.name.as_str(), f.metadata.params, ); @@ -2192,10 +2201,10 @@ impl Module { #[inline(always)] #[must_use] pub fn contains_qualified_iter(&self, id: TypeId) -> bool { - if !self.all_type_iterators.is_empty() { - self.all_type_iterators.contains_key(&id) - } else { + if self.all_type_iterators.is_empty() { false + } else { + self.all_type_iterators.contains_key(&id) } } @@ -2203,10 +2212,10 @@ impl Module { #[inline(always)] #[must_use] pub fn contains_iter(&self, id: TypeId) -> bool { - if !self.type_iterators.is_empty() { - self.type_iterators.contains_key(&id) - } else { + if self.type_iterators.is_empty() { false + } else { + self.type_iterators.contains_key(&id) } } @@ -2273,10 +2282,10 @@ impl Module { #[inline] #[must_use] pub(crate) fn get_qualified_iter(&self, id: TypeId) -> Option<&IteratorFn> { - if !self.all_type_iterators.is_empty() { - self.all_type_iterators.get(&id).map(|f| &**f) - } else { + if self.all_type_iterators.is_empty() { None + } else { + self.all_type_iterators.get(&id).map(|f| &**f) } } @@ -2284,10 +2293,10 @@ impl Module { #[inline] #[must_use] pub(crate) fn get_iter(&self, id: TypeId) -> Option<&IteratorFn> { - if !self.type_iterators.is_empty() { - self.type_iterators.get(&id).map(|f| &**f) - } else { + if self.type_iterators.is_empty() { None + } else { + self.type_iterators.get(&id).map(|f| &**f) } } } diff --git a/src/module/resolvers/collection.rs b/src/module/resolvers/collection.rs index 1889cff4..aa39329f 100644 --- a/src/module/resolvers/collection.rs +++ b/src/module/resolvers/collection.rs @@ -42,7 +42,7 @@ impl ModuleResolversCollection { /// ``` #[inline(always)] #[must_use] - pub const fn new() -> Self { + pub fn new() -> Self { Self(Vec::new()) } /// Append a [module resolver][ModuleResolver] to the end. diff --git a/src/module/resolvers/dummy.rs b/src/module/resolvers/dummy.rs index f36148bc..f5782ebc 100644 --- a/src/module/resolvers/dummy.rs +++ b/src/module/resolvers/dummy.rs @@ -31,6 +31,7 @@ impl DummyModuleResolver { /// engine.set_module_resolver(resolver); /// ``` #[inline(always)] + #[must_use] pub const fn new() -> Self { Self } diff --git a/src/module/resolvers/file.rs b/src/module/resolvers/file.rs index 7bb31b62..69731944 100644 --- a/src/module/resolvers/file.rs +++ b/src/module/resolvers/file.rs @@ -244,10 +244,10 @@ impl FileModuleResolver { let cache = locked_read(&self.cache); - if !cache.is_empty() { - cache.contains_key(path.as_ref()) - } else { + if cache.is_empty() { false + } else { + cache.contains_key(path.as_ref()) } } /// Empty the internal cache. @@ -277,7 +277,7 @@ impl FileModuleResolver { file_path = self .base_path .clone() - .or_else(|| source_path.map(|p| p.into())) + .or_else(|| source_path.map(Into::into)) .unwrap_or_default(); file_path.push(path); } else { diff --git a/src/module/resolvers/stat.rs b/src/module/resolvers/stat.rs index 60a89950..3f556db2 100644 --- a/src/module/resolvers/stat.rs +++ b/src/module/resolvers/stat.rs @@ -66,10 +66,10 @@ impl StaticModuleResolver { #[inline(always)] #[must_use] pub fn contains_path(&self, path: &str) -> bool { - if !self.0.is_empty() { - self.0.contains_key(path) - } else { + if self.0.is_empty() { false + } else { + self.0.contains_key(path) } } /// Get an iterator of all the [modules][Module]. @@ -85,7 +85,7 @@ impl StaticModuleResolver { /// Get an iterator of all the [module][Module] paths. #[inline] pub fn paths(&self) -> impl Iterator { - self.0.keys().map(|s| s.as_str()) + self.0.keys().map(SmartString::as_str) } /// Get an iterator of all the [modules][Module]. #[inline(always)] @@ -100,6 +100,7 @@ impl StaticModuleResolver { } /// Is this [`StaticModuleResolver`] empty? #[inline(always)] + #[must_use] pub fn is_empty(&self) -> bool { self.0.is_empty() } diff --git a/src/optimizer.rs b/src/optimizer.rs index bb82dea8..590e760d 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -103,7 +103,7 @@ impl<'a> OptimizerState<'a> { /// Prune the list of constants back to a specified size. #[inline(always)] pub fn restore_var(&mut self, len: usize) { - self.variables.truncate(len) + self.variables.truncate(len); } /// Add a new variable to the list. #[inline(always)] @@ -113,7 +113,7 @@ impl<'a> OptimizerState<'a> { access: AccessMode, value: Option, ) { - self.variables.push((name.into(), access, value)) + self.variables.push((name.into(), access, value)); } /// Look up a constant from the list. #[inline] @@ -169,7 +169,7 @@ fn has_native_fn_override( hash_script: u64, arg_types: impl AsRef<[TypeId]>, ) -> bool { - let hash_params = calc_fn_params_hash(arg_types.as_ref().iter().cloned()); + let hash_params = calc_fn_params_hash(arg_types.as_ref().iter().copied()); let hash = combine_hashes(hash_script, hash_params); // First check the global namespace and packages, but skip modules that are standard because @@ -433,7 +433,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b if !x.0.is_op_assignment() && x.1.lhs.is_variable_access(true) && matches!(&x.1.rhs, Expr::FnCall(x2, ..) - if Token::lookup_from_syntax(&x2.name).map(|t| t.has_op_assignment()).unwrap_or(false) + if Token::lookup_from_syntax(&x2.name).map_or(false, |t| t.has_op_assignment()) && x2.args.len() == 2 && x2.args[0].get_variable_name(true) == x.1.lhs.get_variable_name(true) ) => @@ -721,12 +721,11 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b } } // Remove if no entry left - match list.is_empty() { - true => { - state.set_dirty(); - false - } - false => true, + if list.is_empty() { + state.set_dirty(); + false + } else { + true } }); @@ -766,7 +765,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b Stmt::While(x, ..) if matches!(x.0, Expr::BoolConstant(false, ..)) => match x.0 { Expr::BoolConstant(false, pos) => { state.set_dirty(); - *stmt = Stmt::Noop(pos) + *stmt = Stmt::Noop(pos); } _ => unreachable!("`Expr::BoolConstant"), }, @@ -785,14 +784,14 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b Stmt::BreakLoop(options, pos) if options.contains(ASTFlags::BREAK) => { // Only a single break statement - turn into running the guard expression once state.set_dirty(); - if !condition.is_unit() { + if condition.is_unit() { + *stmt = Stmt::Noop(pos); + } else { let mut statements = vec![Stmt::Expr(mem::take(condition).into())]; if preserve_result { - statements.push(Stmt::Noop(pos)) + statements.push(Stmt::Noop(pos)); } *stmt = (statements, Span::new(pos, Position::NONE)).into(); - } else { - *stmt = Stmt::Noop(pos); }; } _ => (), @@ -835,7 +834,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b } // let id = expr; Stmt::Var(x, options, ..) if !options.contains(ASTFlags::CONSTANT) => { - optimize_expr(&mut x.1, state, false) + optimize_expr(&mut x.1, state, false); } // import expr as var; #[cfg(not(feature = "no_module"))] @@ -969,8 +968,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { // All other items can be thrown away. state.set_dirty(); *expr = mem::take(&mut m.0).into_iter().find(|(x, ..)| x.as_str() == prop) - .map(|(.., mut expr)| { expr.set_position(*pos); expr }) - .unwrap_or_else(|| Expr::Unit(*pos)); + .map_or_else(|| Expr::Unit(*pos), |(.., mut expr)| { expr.set_position(*pos); expr }); } // var.rhs (Expr::Variable(..), rhs) => optimize_expr(rhs, state, true), @@ -1015,8 +1013,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { // All other items can be thrown away. state.set_dirty(); *expr = mem::take(&mut m.0).into_iter().find(|(x, ..)| x.as_str() == s.as_str()) - .map(|(.., mut expr)| { expr.set_position(*pos); expr }) - .unwrap_or_else(|| Expr::Unit(*pos)); + .map_or_else(|| Expr::Unit(*pos), |(.., mut expr)| { expr.set_position(*pos); expr }); } // int[int] (Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, ..)) if *i >= 0 && (*i as usize) < crate::INT_BITS => { @@ -1148,7 +1145,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { _ => Dynamic::UNIT }; - if let Ok(fn_ptr) = fn_name.into_immutable_string().map_err(|err| err.into()).and_then(FnPtr::try_from) { + if let Ok(fn_ptr) = fn_name.into_immutable_string().map_err(Into::into).and_then(FnPtr::try_from) { state.set_dirty(); *expr = Expr::DynamicConstant(Box::new(fn_ptr.into()), *pos); } else { @@ -1338,10 +1335,10 @@ fn optimize_top_level( // Add constants and variables from the scope for (name, constant, value) in scope.iter() { - if !constant { - state.push_var(name, AccessMode::ReadWrite, None); - } else { + if constant { state.push_var(name, AccessMode::ReadOnly, Some(value)); + } else { + state.push_var(name, AccessMode::ReadWrite, None); } } diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index a86c6883..d0a0b671 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -145,16 +145,14 @@ pub mod array_functions { /// ``` #[rhai_fn(name = "+")] pub fn concat(array1: Array, array2: Array) -> Array { - if !array2.is_empty() { - if array1.is_empty() { - array2 - } else { - let mut array = array1; - array.extend(array2); - array - } - } else { + if array2.is_empty() { array1 + } else if array1.is_empty() { + array2 + } else { + let mut array = array1; + array.extend(array2); + array } } /// Add a new element into the array at a particular `index` position. @@ -432,7 +430,7 @@ pub mod array_functions { pub fn splice_range(array: &mut Array, range: ExclusiveRange, replace: Array) { let start = INT::max(range.start, 0); let end = INT::max(range.end, start); - splice(array, start, end - start, replace) + splice(array, start, end - start, replace); } /// Replace an inclusive range of the array with another array. /// @@ -450,7 +448,7 @@ pub mod array_functions { pub fn splice_inclusive_range(array: &mut Array, range: InclusiveRange, replace: Array) { let start = INT::max(*range.start(), 0); let end = INT::max(*range.end(), start); - splice(array, start, end - start + 1, replace) + splice(array, start, end - start + 1, replace); } /// Replace a portion of the array with another array. /// @@ -1739,13 +1737,15 @@ pub mod array_functions { .call_raw(&ctx, None, [x.clone(), y.clone()]) .ok() .and_then(|v| v.as_int().ok()) - .map(|v| match v { - v if v > 0 => Ordering::Greater, - v if v < 0 => Ordering::Less, - 0 => Ordering::Equal, - _ => unreachable!("v is {}", v), - }) - .unwrap_or_else(|| x.type_id().cmp(&y.type_id())) + .map_or_else( + || x.type_id().cmp(&y.type_id()), + |v| match v { + v if v > 0 => Ordering::Greater, + v if v < 0 => Ordering::Less, + 0 => Ordering::Equal, + _ => unreachable!("v is {}", v), + }, + ) }); Ok(()) @@ -2119,7 +2119,7 @@ pub mod array_functions { let mut x = 0; while x < array.len() { - if !filter + if filter .call_raw(&ctx, None, [array[x].clone()]) .or_else(|err| match *err { ERR::ErrorFunctionNotFound(fn_sig, ..) @@ -2140,9 +2140,9 @@ pub mod array_functions { .as_bool() .unwrap_or(false) { - drained.push(array.remove(x)); - } else { x += 1; + } else { + drained.push(array.remove(x)); } i += 1; diff --git a/src/packages/blob_basic.rs b/src/packages/blob_basic.rs index ad26ccac..c3f43aff 100644 --- a/src/packages/blob_basic.rs +++ b/src/packages/blob_basic.rs @@ -86,7 +86,7 @@ pub mod blob_functions { } let mut blob = Blob::new(); - blob.resize(len, (value & 0x000000ff) as u8); + blob.resize(len, (value & 0x0000_00ff) as u8); Ok(blob) } /// Convert the BLOB into an array of integers. @@ -205,7 +205,7 @@ pub mod blob_functions { let (index, ..) = calc_offset_len(blob.len(), index, 0); if index < blob.len() { - blob[index] = (value & 0x000000ff) as u8; + blob[index] = (value & 0x0000_00ff) as u8; } } /// Add a new byte `value` to the end of the BLOB. @@ -223,7 +223,7 @@ pub mod blob_functions { /// ``` #[rhai_fn(name = "push", name = "append")] pub fn push(blob: &mut Blob, value: INT) { - blob.push((value & 0x000000ff) as u8); + blob.push((value & 0x0000_00ff) as u8); } /// Add another BLOB to the end of the BLOB. /// @@ -298,7 +298,7 @@ pub mod blob_functions { /// print(b); // prints "[4242184242]" /// ``` pub fn insert(blob: &mut Blob, index: INT, value: INT) { - let value = (value & 0x000000ff) as u8; + let value = (value & 0x0000_00ff) as u8; if blob.is_empty() { blob.push(value); @@ -338,7 +338,7 @@ pub mod blob_functions { return Ok(()); } - let value = (value & 0x000000ff) as u8; + let value = (value & 0x0000_00ff) as u8; let _ctx = ctx; // Check if blob will be over max size limit @@ -528,7 +528,7 @@ pub mod blob_functions { pub fn splice_range(blob: &mut Blob, range: ExclusiveRange, replace: Blob) { let start = INT::max(range.start, 0); let end = INT::max(range.end, start); - splice(blob, start, end - start, replace) + splice(blob, start, end - start, replace); } /// Replace an inclusive `range` of the BLOB with another BLOB. /// @@ -546,7 +546,7 @@ pub mod blob_functions { pub fn splice_range_inclusive(blob: &mut Blob, range: InclusiveRange, replace: Blob) { let start = INT::max(*range.start(), 0); let end = INT::max(*range.end(), start); - splice(blob, start, end - start + 1, replace) + splice(blob, start, end - start + 1, replace); } /// Replace a portion of the BLOB with another BLOB. /// @@ -1220,7 +1220,7 @@ mod write_int_functions { pub fn write_le_int_range(blob: &mut Blob, range: ExclusiveRange, value: INT) { let start = INT::max(range.start, 0); let end = INT::max(range.end, start); - write_le_int(blob, start, end - start, value) + write_le_int(blob, start, end - start, value); } /// Write an `INT` value to the bytes within an inclusive `range` in the BLOB /// in little-endian byte order. @@ -1239,7 +1239,7 @@ mod write_int_functions { pub fn write_le_int_range_inclusive(blob: &mut Blob, range: InclusiveRange, value: INT) { let start = INT::max(*range.start(), 0); let end = INT::max(*range.end(), start); - write_le_int(blob, start, end - start + 1, value) + write_le_int(blob, start, end - start + 1, value); } /// Write an `INT` value to the bytes beginning at the `start` position in the BLOB /// in little-endian byte order. @@ -1262,7 +1262,7 @@ mod write_int_functions { /// ``` #[rhai_fn(name = "write_le")] pub fn write_le_int(blob: &mut Blob, start: INT, len: INT, value: INT) { - write_int(blob, start, len, value, true) + write_int(blob, start, len, value, true); } /// Write an `INT` value to the bytes within an exclusive `range` in the BLOB /// in big-endian byte order. @@ -1281,7 +1281,7 @@ mod write_int_functions { pub fn write_be_int_range(blob: &mut Blob, range: ExclusiveRange, value: INT) { let start = INT::max(range.start, 0); let end = INT::max(range.end, start); - write_be_int(blob, start, end - start, value) + write_be_int(blob, start, end - start, value); } /// Write an `INT` value to the bytes within an inclusive `range` in the BLOB /// in big-endian byte order. @@ -1300,7 +1300,7 @@ mod write_int_functions { pub fn write_be_int_range_inclusive(blob: &mut Blob, range: InclusiveRange, value: INT) { let start = INT::max(*range.start(), 0); let end = INT::max(*range.end(), start); - write_be_int(blob, start, end - start + 1, value) + write_be_int(blob, start, end - start + 1, value); } /// Write an `INT` value to the bytes beginning at the `start` position in the BLOB /// in big-endian byte order. @@ -1323,7 +1323,7 @@ mod write_int_functions { /// ``` #[rhai_fn(name = "write_be")] pub fn write_be_int(blob: &mut Blob, start: INT, len: INT, value: INT) { - write_int(blob, start, len, value, false) + write_int(blob, start, len, value, false); } } @@ -1360,7 +1360,7 @@ mod write_float_functions { pub fn write_le_float_range(blob: &mut Blob, range: ExclusiveRange, value: FLOAT) { let start = INT::max(range.start, 0); let end = INT::max(range.end, start); - write_le_float(blob, start, end - start, value) + write_le_float(blob, start, end - start, value); } /// Write a `FLOAT` value to the bytes within an inclusive `range` in the BLOB /// in little-endian byte order. @@ -1371,7 +1371,7 @@ mod write_float_functions { pub fn write_le_float_range_inclusive(blob: &mut Blob, range: InclusiveRange, value: FLOAT) { let start = INT::max(*range.start(), 0); let end = INT::max(*range.end(), start); - write_le_float(blob, start, end - start + 1, value) + write_le_float(blob, start, end - start + 1, value); } /// Write a `FLOAT` value to the bytes beginning at the `start` position in the BLOB /// in little-endian byte order. @@ -1386,7 +1386,7 @@ mod write_float_functions { /// * If number of bytes in `range` > number of bytes for `FLOAT`, extra bytes in `range` are not modified. #[rhai_fn(name = "write_le")] pub fn write_le_float(blob: &mut Blob, start: INT, len: INT, value: FLOAT) { - write_float(blob, start, len, value, true) + write_float(blob, start, len, value, true); } /// Write a `FLOAT` value to the bytes within an exclusive `range` in the BLOB /// in big-endian byte order. @@ -1397,7 +1397,7 @@ mod write_float_functions { pub fn write_be_float_range(blob: &mut Blob, range: ExclusiveRange, value: FLOAT) { let start = INT::max(range.start, 0); let end = INT::max(range.end, start); - write_be_float(blob, start, end - start, value) + write_be_float(blob, start, end - start, value); } /// Write a `FLOAT` value to the bytes within an inclusive `range` in the BLOB /// in big-endian byte order. @@ -1408,7 +1408,7 @@ mod write_float_functions { pub fn write_be_float_range_inclusive(blob: &mut Blob, range: InclusiveRange, value: FLOAT) { let start = INT::max(*range.start(), 0); let end = INT::max(*range.end(), start); - write_be_float(blob, start, end - start + 1, value) + write_be_float(blob, start, end - start + 1, value); } /// Write a `FLOAT` value to the bytes beginning at the `start` position in the BLOB /// in big-endian byte order. @@ -1423,7 +1423,7 @@ mod write_float_functions { /// * If number of bytes in `range` > number of bytes for `FLOAT`, extra bytes in `range` are not modified. #[rhai_fn(name = "write_be")] pub fn write_be_float(blob: &mut Blob, start: INT, len: INT, value: FLOAT) { - write_float(blob, start, len, value, false) + write_float(blob, start, len, value, false); } } @@ -1471,7 +1471,7 @@ mod write_string_functions { pub fn write_utf8_string_range(blob: &mut Blob, range: ExclusiveRange, string: &str) { let start = INT::max(range.start, 0); let end = INT::max(range.end, start); - write_string(blob, start, end - start, string, false) + write_string(blob, start, end - start, string, false); } /// Write a string to the bytes within an inclusive `range` in the BLOB in UTF-8 encoding. /// @@ -1489,7 +1489,7 @@ mod write_string_functions { pub fn write_utf8_string_range_inclusive(blob: &mut Blob, range: InclusiveRange, string: &str) { let start = INT::max(*range.start(), 0); let end = INT::max(*range.end(), start); - write_string(blob, start, end - start + 1, string, false) + write_string(blob, start, end - start + 1, string, false); } /// Write a string to the bytes within an inclusive `range` in the BLOB in UTF-8 encoding. /// @@ -1511,7 +1511,7 @@ mod write_string_functions { /// ``` #[rhai_fn(name = "write_utf8")] pub fn write_utf8_string(blob: &mut Blob, start: INT, len: INT, string: &str) { - write_string(blob, start, len, string, false) + write_string(blob, start, len, string, false); } /// Write an ASCII string to the bytes within an exclusive `range` in the BLOB. /// @@ -1532,7 +1532,7 @@ mod write_string_functions { pub fn write_ascii_string_range(blob: &mut Blob, range: ExclusiveRange, string: &str) { let start = INT::max(range.start, 0); let end = INT::max(range.end, start); - write_string(blob, start, end - start, string, true) + write_string(blob, start, end - start, string, true); } /// Write an ASCII string to the bytes within an inclusive `range` in the BLOB. /// @@ -1557,7 +1557,7 @@ mod write_string_functions { ) { let start = INT::max(*range.start(), 0); let end = INT::max(*range.end(), start); - write_string(blob, start, end - start + 1, string, true) + write_string(blob, start, end - start + 1, string, true); } /// Write an ASCII string to the bytes within an exclusive `range` in the BLOB. /// @@ -1579,6 +1579,6 @@ mod write_string_functions { /// ``` #[rhai_fn(name = "write_ascii")] pub fn write_ascii_string(blob: &mut Blob, start: INT, len: INT, string: &str) { - write_string(blob, start, len, string, true) + write_string(blob, start, len, string, true); } } diff --git a/src/packages/iter_basic.rs b/src/packages/iter_basic.rs index be024a4b..f6f0e35b 100644 --- a/src/packages/iter_basic.rs +++ b/src/packages/iter_basic.rs @@ -28,7 +28,7 @@ where } // Range iterator with step -#[derive(Clone, Copy, Hash, Eq, PartialEq)] +#[derive(Clone, Hash, Eq, PartialEq)] pub struct StepRange { pub from: T, pub to: T, @@ -110,7 +110,7 @@ impl Iterator for StepRange { impl FusedIterator for StepRange {} // Bit-field iterator with step -#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[derive(Debug, Clone, Hash, Eq, PartialEq)] pub struct BitRange(INT, INT, usize); impl BitRange { diff --git a/src/packages/lang_core.rs b/src/packages/lang_core.rs index 2390487d..72aca603 100644 --- a/src/packages/lang_core.rs +++ b/src/packages/lang_core.rs @@ -220,7 +220,7 @@ fn collect_fn_metadata( f, ) .into(), - ) + ); }); ctx.engine() @@ -237,7 +237,7 @@ fn collect_fn_metadata( f, ) .into(), - ) + ); }); #[cfg(not(feature = "no_module"))] @@ -255,7 +255,7 @@ fn collect_fn_metadata( f, ) .into(), - ) + ); }); #[cfg(not(feature = "no_module"))] @@ -264,7 +264,7 @@ fn collect_fn_metadata( fn scan_module( list: &mut Array, dict: &BTreeSet, - namespace: Identifier, + namespace: &str, module: &Module, filter: impl Fn( FnNamespace, @@ -278,7 +278,7 @@ fn collect_fn_metadata( module .iter_script_fn() .filter(|(s, a, n, p, f)| filter(*s, *a, n, *p, f)) - .for_each(|(.., f)| list.push(make_metadata(dict, namespace.clone(), f).into())); + .for_each(|(.., f)| list.push(make_metadata(dict, namespace.into(), f).into())); for (ns, m) in module.iter_sub_modules() { let ns = format!( "{}{}{}", @@ -286,12 +286,12 @@ fn collect_fn_metadata( crate::tokenizer::Token::DoubleColon.literal_syntax(), ns ); - scan_module(list, dict, ns.into(), &**m, filter) + scan_module(list, dict, &ns, &**m, filter); } } for (ns, m) in ctx.iter_imports_raw() { - scan_module(&mut list, &dict, ns.clone(), &**m, filter) + scan_module(&mut list, &dict, ns, &**m, filter); } } diff --git a/src/packages/map_basic.rs b/src/packages/map_basic.rs index 85229602..bb990cb4 100644 --- a/src/packages/map_basic.rs +++ b/src/packages/map_basic.rs @@ -92,10 +92,10 @@ mod map_functions { /// print(m); // prints "#{a:1, c:3}" /// ``` pub fn remove(map: &mut Map, property: &str) -> Dynamic { - if !map.is_empty() { - map.remove(property).unwrap_or(Dynamic::UNIT) - } else { + if map.is_empty() { Dynamic::UNIT + } else { + map.remove(property).unwrap_or(Dynamic::UNIT) } } /// Add all property values of another object map into the object map. @@ -160,9 +160,9 @@ mod map_functions { if map.is_empty() { *map = map2; } else { - map2.into_iter().for_each(|(key, value)| { + for (key, value) in map2 { map.entry(key).or_insert(value); - }); + } } } } diff --git a/src/packages/mod.rs b/src/packages/mod.rs index 853ec95a..ef59ae26 100644 --- a/src/packages/mod.rs +++ b/src/packages/mod.rs @@ -98,6 +98,7 @@ macro_rules! def_package { impl $package { #[doc=concat!("Create a new `", stringify!($package), "`")] + #[must_use] pub fn new() -> Self { let mut module = $crate::Module::new(); ::init(&mut module); diff --git a/src/packages/string_more.rs b/src/packages/string_more.rs index 08e86419..c1ceebb3 100644 --- a/src/packages/string_more.rs +++ b/src/packages/string_more.rs @@ -114,7 +114,7 @@ mod string_functions { } } #[rhai_fn(name = "+")] - pub fn add_prepend(utf8: Blob, string: ImmutableString) -> ImmutableString { + pub fn add_prepend(utf8: Blob, string: &str) -> ImmutableString { let s = String::from_utf8_lossy(&utf8); let mut s = match s { std::borrow::Cow::Borrowed(_) => String::from_utf8(utf8).unwrap(), @@ -122,7 +122,7 @@ mod string_functions { }; if !string.is_empty() { - s.push_str(&string); + s.push_str(string); } s.into() @@ -440,7 +440,7 @@ mod string_functions { /// ``` #[rhai_fn(name = "make_upper")] pub fn make_upper_char(character: &mut char) { - *character = to_upper_char(*character) + *character = to_upper_char(*character); } /// Convert the character to lower-case and return it as a new character. /// @@ -476,7 +476,7 @@ mod string_functions { /// ``` #[rhai_fn(name = "make_lower")] pub fn make_lower_char(character: &mut char) { - *character = to_lower_char(*character) + *character = to_lower_char(*character); } /// Return `true` if the string starts with a specified string. @@ -558,10 +558,9 @@ mod string_functions { .len() }; - string[start..] - .find(character) - .map(|index| string[0..start + index].chars().count() as INT) - .unwrap_or(-1 as INT) + string[start..].find(character).map_or(-1 as INT, |index| { + string[0..start + index].chars().count() as INT + }) } /// Find the specified `character` in the string and return the first index where it is found. /// If the `character` is not found, `-1` is returned. @@ -582,8 +581,7 @@ mod string_functions { } else { string .find(character) - .map(|index| string[0..index].chars().count() as INT) - .unwrap_or(-1 as INT) + .map_or(-1 as INT, |index| string[0..index].chars().count() as INT) } } /// Find the specified sub-string in the string, starting from the specified `start` position, @@ -638,8 +636,9 @@ mod string_functions { string[start..] .find(find_string) - .map(|index| string[0..start + index].chars().count() as INT) - .unwrap_or(-1 as INT) + .map_or(-1 as INT, |index| { + string[0..start + index].chars().count() as INT + }) } /// Find the specified `character` in the string and return the first index where it is found. /// If the `character` is not found, `-1` is returned. @@ -660,8 +659,7 @@ mod string_functions { } else { string .find(find_string) - .map(|index| string[0..index].chars().count() as INT) - .unwrap_or(-1 as INT) + .map_or(-1 as INT, |index| string[0..index].chars().count() as INT) } } @@ -840,7 +838,7 @@ mod string_functions { .iter() .skip(offset) .take(len) - .cloned() + .copied() .collect::() .into() } @@ -889,7 +887,7 @@ mod string_functions { pub fn crop_range(string: &mut ImmutableString, range: ExclusiveRange) { let start = INT::max(range.start, 0); let end = INT::max(range.end, start); - crop(string, start, end - start) + crop(string, start, end - start); } /// Remove all characters from the string except those within an inclusive `range`. /// @@ -906,7 +904,7 @@ mod string_functions { pub fn crop_inclusive_range(string: &mut ImmutableString, range: InclusiveRange) { let start = INT::max(*range.start(), 0); let end = INT::max(*range.end(), start); - crop(string, start, end - start + 1) + crop(string, start, end - start + 1); } /// Remove all characters from the string except those within a range. diff --git a/src/parser.rs b/src/parser.rs index 0231715f..ec13dd3e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -130,6 +130,7 @@ impl<'e> ParseState<'e> { /// If the variable is not present in the scope, the first return value is zero. /// /// The second return value indicates whether the barrier has been hit before finding the variable. + #[must_use] pub fn find_var(&self, name: &str) -> (usize, bool) { let mut hit_barrier = false; @@ -175,7 +176,7 @@ impl<'e> ParseState<'e> { }); } } else { - self.allow_capture = true + self.allow_capture = true; } if hit_barrier { @@ -360,7 +361,10 @@ impl Expr { /// Make sure that the next expression is not a statement expression (i.e. wrapped in `{}`). #[inline] -fn ensure_not_statement_expr(input: &mut TokenStream, type_name: impl ToString) -> ParseResult<()> { +fn ensure_not_statement_expr( + input: &mut TokenStream, + type_name: &(impl ToString + ?Sized), +) -> ParseResult<()> { match input.peek().expect(NEVER_ENDS) { (Token::LeftBrace, pos) => Err(PERR::ExprExpected(type_name.to_string()).into_err(*pos)), _ => Ok(()), @@ -519,7 +523,9 @@ impl Engine { } #[cfg(not(feature = "no_module"))] - let hash = if !namespace.is_empty() { + let hash = if namespace.is_empty() { + calc_fn_hash(&id, 0) + } else { let root = namespace.root(); let index = state.find_module(root); @@ -541,9 +547,7 @@ impl Engine { namespace.set_index(index); - crate::calc_qualified_fn_hash(namespace.iter().map(|m| m.as_str()), &id, 0) - } else { - calc_fn_hash(&id, 0) + crate::calc_qualified_fn_hash(namespace.iter().map(Ident::as_str), &id, 0) }; #[cfg(feature = "no_module")] let hash = calc_fn_hash(&id, 0); @@ -586,7 +590,9 @@ impl Engine { eat_token(input, Token::RightParen); #[cfg(not(feature = "no_module"))] - let hash = if !namespace.is_empty() { + let hash = if namespace.is_empty() { + calc_fn_hash(&id, args.len()) + } else { let root = namespace.root(); let index = state.find_module(root); @@ -608,12 +614,10 @@ impl Engine { namespace.set_index(index); crate::calc_qualified_fn_hash( - namespace.iter().map(|m| m.as_str()), + namespace.iter().map(Ident::as_str), &id, args.len(), ) - } else { - calc_fn_hash(&id, args.len()) }; #[cfg(feature = "no_module")] let hash = calc_fn_hash(&id, args.len()); @@ -788,7 +792,7 @@ impl Engine { // Any more indexing following? match input.peek().expect(NEVER_ENDS) { // If another indexing level, right-bind it - (Token::LeftBracket, ..) | (Token::QuestionBracket, ..) => { + (Token::LeftBracket | Token::QuestionBracket, ..) => { let (token, pos) = input.next().expect(NEVER_ENDS); let prev_pos = settings.pos; settings.pos = pos; @@ -1088,7 +1092,10 @@ impl Engine { return Err(PERR::WrongSwitchCaseCondition.into_err(if_pos)); } - (Default::default(), Expr::BoolConstant(true, Position::NONE)) + ( + StaticVec::default(), + Expr::BoolConstant(true, Position::NONE), + ) } _ if def_case.is_some() => { return Err(PERR::WrongSwitchDefaultCase.into_err(def_case_pos)) @@ -1149,7 +1156,9 @@ impl Engine { expressions.push((condition, Expr::Stmt(stmt_block.into())).into()); let index = expressions.len() - 1; - if !case_expr_list.is_empty() { + if case_expr_list.is_empty() { + def_case = Some(index); + } else { for expr in case_expr_list { let value = expr.get_literal_value().ok_or_else(|| { PERR::ExprExpected("a literal".to_string()).into_err(expr.start_position()) @@ -1200,8 +1209,6 @@ impl Engine { .and_modify(|cases| cases.push(index)) .or_insert_with(|| [index].into()); } - } else { - def_case = Some(index); } match input.peek().expect(NEVER_ENDS) { @@ -1690,7 +1697,7 @@ impl Engine { } // Indexing #[cfg(not(feature = "no_index"))] - (expr, token @ Token::LeftBracket) | (expr, token @ Token::QuestionBracket) => { + (expr, token @ (Token::LeftBracket | Token::QuestionBracket)) => { let opt = match token { Token::LeftBracket => ASTFlags::NONE, Token::QuestionBracket => ASTFlags::NEGATED, @@ -1700,7 +1707,7 @@ impl Engine { } // Property access #[cfg(not(feature = "no_object"))] - (expr, op @ Token::Period) | (expr, op @ Token::Elvis) => { + (expr, op @ (Token::Period | Token::Elvis)) => { // Expression after dot must start with an identifier match input.peek().expect(NEVER_ENDS) { (Token::Identifier(..), ..) => { @@ -1745,7 +1752,7 @@ impl Engine { #[cfg(not(feature = "no_module"))] if let Some((.., namespace, hash, name)) = namespaced_variable { if !namespace.is_empty() { - *hash = crate::calc_qualified_var_hash(namespace.iter().map(|v| v.as_str()), name); + *hash = crate::calc_qualified_var_hash(namespace.iter().map(Ident::as_str), name); #[cfg(not(feature = "no_module"))] { @@ -2196,7 +2203,7 @@ impl Engine { Token::Custom(c) => self .custom_keywords .get(c) - .cloned() + .copied() .ok_or_else(|| PERR::Reserved(c.to_string()).into_err(*current_pos))?, Token::Reserved(c) if !is_valid_identifier(c.chars()) => { return Err(PERR::UnknownOperator(c.to_string()).into_err(*current_pos)) @@ -2221,7 +2228,7 @@ impl Engine { Token::Custom(c) => self .custom_keywords .get(c) - .cloned() + .copied() .ok_or_else(|| PERR::Reserved(c.to_string()).into_err(*next_pos))?, Token::Reserved(c) if !is_valid_identifier(c.chars()) => { return Err(PERR::UnknownOperator(c.to_string()).into_err(*next_pos)) @@ -3429,7 +3436,7 @@ impl Engine { } let s = state.get_identifier("", s); state.stack.push(s.clone(), ()); - params.push((s, pos)) + params.push((s, pos)); } (Token::LexError(err), pos) => return Err(err.into_err(pos)), (.., pos) => { @@ -3565,7 +3572,7 @@ impl Engine { } let s = state.get_identifier("", s); state.stack.push(s.clone(), ()); - params_list.push(s) + params_list.push(s); } (Token::LexError(err), pos) => return Err(err.into_err(pos)), (.., pos) => { diff --git a/src/serde/de.rs b/src/serde/de.rs index 178c3bbe..747b0597 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -1,7 +1,9 @@ //! Implement deserialization support of [`Dynamic`][crate::Dynamic] for [`serde`]. use crate::types::dynamic::Union; -use crate::{Dynamic, ImmutableString, LexError, Position, RhaiError, RhaiResultOf, ERR}; +use crate::{ + Dynamic, ImmutableString, LexError, Position, RhaiError, RhaiResultOf, SmartString, ERR, +}; use serde::de::{Error, IntoDeserializer, Visitor}; use serde::{Deserialize, Deserializer}; #[cfg(feature = "no_std")] @@ -420,7 +422,7 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { || self.type_error(), |map| { _visitor.visit_map(IterateMap::new( - map.keys().map(|key| key.as_str()), + map.keys().map(SmartString::as_str), map.values(), )) }, diff --git a/src/serde/metadata.rs b/src/serde/metadata.rs index 4c8cc501..3ce42c2d 100644 --- a/src/serde/metadata.rs +++ b/src/serde/metadata.rs @@ -181,7 +181,7 @@ impl ModuleMetadata<'_> { impl<'a> From<&'a crate::Module> for ModuleMetadata<'a> { fn from(module: &'a crate::Module) -> Self { - let mut functions: Vec<_> = module.iter_fn().map(|f| f.into()).collect(); + let mut functions: Vec<_> = module.iter_fn().map(Into::into).collect(); functions.sort(); Self { diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 682e4285..bd742702 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -210,7 +210,7 @@ impl Position { } /// Print this [`Position`] for debug purposes. #[inline] - pub(crate) fn debug_print(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + pub(crate) fn debug_print(self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { if !self.is_none() { write!(_f, " @ {:?}", self)?; } @@ -1215,7 +1215,7 @@ pub fn parse_string_literal( if allow_interpolation && next_char == '$' && escape.is_empty() - && stream.peek_next().map(|ch| ch == '{').unwrap_or(false) + && stream.peek_next().map_or(false, |ch| ch == '{') { interpolated = true; state.is_within_text_terminated_by = None; @@ -1245,7 +1245,7 @@ pub fn parse_string_literal( match next_char { // \r - ignore if followed by \n - '\r' if stream.peek_next().map(|ch| ch == '\n').unwrap_or(false) => (), + '\r' if stream.peek_next().map_or(false, |ch| ch == '\n') => (), // \... '\\' if !verbatim && escape.is_empty() => { escape.push('\\'); @@ -1271,7 +1271,7 @@ pub fn parse_string_literal( result.push('\r'); } // \x??, \u????, \U???????? - ch @ 'x' | ch @ 'u' | ch @ 'U' if !escape.is_empty() => { + ch @ ('x' | 'u' | 'U') if !escape.is_empty() => { let mut seq = escape.clone(); escape.clear(); seq.push(ch); @@ -1307,7 +1307,7 @@ pub fn parse_string_literal( // \{termination_char} - escaped _ if termination_char == next_char && !escape.is_empty() => { escape.clear(); - result.push(next_char) + result.push(next_char); } // Verbatim @@ -1598,7 +1598,7 @@ fn get_next_token_inner( } } // 0x????, 0o????, 0b???? at beginning - ch @ 'x' | ch @ 'o' | ch @ 'b' | ch @ 'X' | ch @ 'O' | ch @ 'B' + ch @ ('x' | 'o' | 'b' | 'X' | 'O' | 'B') if c == '0' && result.len() <= 1 => { result.push(next_char); @@ -1639,12 +1639,14 @@ fn get_next_token_inner( UNSIGNED_INT::from_str_radix(&out, radix) .map(|v| v as INT) - .map(Token::IntegerConstant) - .unwrap_or_else(|_| { - Token::LexError( - LERR::MalformedNumber(result.into_iter().collect()).into(), - ) - }) + .map_or_else( + |_| { + Token::LexError( + LERR::MalformedNumber(result.into_iter().collect()).into(), + ) + }, + Token::IntegerConstant, + ) } else { let out: String = result.iter().filter(|&&c| c != NUMBER_SEPARATOR).collect(); @@ -1680,7 +1682,7 @@ fn get_next_token_inner( // letter or underscore ... #[cfg(not(feature = "unicode-xid-ident"))] - ('a'..='z', ..) | ('_', ..) | ('A'..='Z', ..) => { + ('a'..='z' | '_' | 'A'..='Z', ..) => { return get_identifier(stream, pos, start_pos, c); } #[cfg(feature = "unicode-xid-ident")] @@ -2161,7 +2163,7 @@ fn get_identifier( } } - let is_valid_identifier = is_valid_identifier(result.iter().cloned()); + let is_valid_identifier = is_valid_identifier(result.iter().copied()); let identifier: String = result.into_iter().collect(); @@ -2384,7 +2386,7 @@ impl<'a> Iterator for TokenIterator<'a> { ("::<", false) => Token::LexError(LERR::ImproperSymbol(s.to_string(), "'::<>' is not a valid symbol. This is not Rust! Should it be '::'?".to_string(), ).into()), - ("(*", false) | ("*)", false) => Token::LexError(LERR::ImproperSymbol(s.to_string(), + ("(*" | "*)", false) => Token::LexError(LERR::ImproperSymbol(s.to_string(), "'(* .. *)' is not a valid comment format. This is not Pascal! Should it be '/* .. */'?".to_string(), ).into()), ("# {", false) => Token::LexError(LERR::ImproperSymbol(s.to_string(), diff --git a/src/types/dynamic.rs b/src/types/dynamic.rs index 5b87393e..d83eb68d 100644 --- a/src/types/dynamic.rs +++ b/src/types/dynamic.rs @@ -739,7 +739,7 @@ impl Dynamic { /// A [`Dynamic`] containing the integer 1,000. pub const THOUSAND: Self = Self::from_int(1000); /// A [`Dynamic`] containing the integer 1,000,000. - pub const MILLION: Self = Self::from_int(1000000); + pub const MILLION: Self = Self::from_int(1_000_000); /// A [`Dynamic`] containing the integer -1. pub const NEGATIVE_ONE: Self = Self::from_int(-1); /// A [`Dynamic`] containing the integer -2. @@ -778,7 +778,7 @@ impl Dynamic { /// /// Not available under `no_float`. #[cfg(not(feature = "no_float"))] - pub const FLOAT_MILLION: Self = Self::from_float(1000000.0); + pub const FLOAT_MILLION: Self = Self::from_float(1_000_000.0); /// A [`Dynamic`] containing `-1.0`. /// /// Not available under `no_float`. @@ -823,7 +823,7 @@ impl Dynamic { /// /// Not available under `no_float`. #[cfg(not(feature = "no_float"))] - pub const FLOAT_MILLIONTH: Self = Self::from_float(0.000001); + pub const FLOAT_MILLIONTH: Self = Self::from_float(0.000_001); /// A [`Dynamic`] containing π. /// /// Not available under `no_float`. @@ -867,16 +867,19 @@ impl Dynamic { /// Create a new [`Dynamic`] from a [`bool`]. #[inline(always)] + #[must_use] pub const fn from_bool(value: bool) -> Self { Self(Union::Bool(value, DEFAULT_TAG_VALUE, ReadWrite)) } /// Create a new [`Dynamic`] from an [`INT`]. #[inline(always)] + #[must_use] pub const fn from_int(value: INT) -> Self { Self(Union::Int(value, DEFAULT_TAG_VALUE, ReadWrite)) } /// Create a new [`Dynamic`] from a [`char`]. #[inline(always)] + #[must_use] pub const fn from_char(value: char) -> Self { Self(Union::Char(value, DEFAULT_TAG_VALUE, ReadWrite)) } @@ -885,6 +888,7 @@ impl Dynamic { /// Not available under `no_float`. #[cfg(not(feature = "no_float"))] #[inline(always)] + #[must_use] pub const fn from_float(value: crate::FLOAT) -> Self { Self(Union::Float( crate::ast::FloatWrapper::new_const(value), @@ -897,24 +901,28 @@ impl Dynamic { /// Exported under the `decimal` feature only. #[cfg(feature = "decimal")] #[inline(always)] + #[must_use] pub fn from_decimal(value: rust_decimal::Decimal) -> Self { Self(Union::Decimal(value.into(), DEFAULT_TAG_VALUE, ReadWrite)) } /// Create a [`Dynamic`] from an [`Array`][crate::Array]. #[cfg(not(feature = "no_index"))] #[inline(always)] + #[must_use] pub fn from_array(array: crate::Array) -> Self { Self(Union::Array(array.into(), DEFAULT_TAG_VALUE, ReadWrite)) } /// Create a [`Dynamic`] from a [`Blob`][crate::Blob]. #[cfg(not(feature = "no_index"))] #[inline(always)] + #[must_use] pub fn from_blob(blob: crate::Blob) -> Self { Self(Union::Blob(blob.into(), DEFAULT_TAG_VALUE, ReadWrite)) } /// Create a [`Dynamic`] from a [`Map`][crate::Map]. #[cfg(not(feature = "no_object"))] #[inline(always)] + #[must_use] pub fn from_map(map: crate::Map) -> Self { Self(Union::Map(map.into(), DEFAULT_TAG_VALUE, ReadWrite)) } @@ -923,6 +931,7 @@ impl Dynamic { /// Not available under `no-std`. #[cfg(not(feature = "no_std"))] #[inline(always)] + #[must_use] pub fn from_timestamp(value: Instant) -> Self { Self(Union::TimeStamp(value.into(), DEFAULT_TAG_VALUE, ReadWrite)) } @@ -993,6 +1002,7 @@ impl Dynamic { } /// Make this [`Dynamic`] read-only (i.e. a constant). #[inline(always)] + #[must_use] pub fn into_read_only(self) -> Self { let mut value = self; value.set_access_mode(AccessMode::ReadOnly); @@ -1388,13 +1398,13 @@ impl Dynamic { Union::Shared(ref cell, ..) => { let value = locked_read(cell); - if (*value).type_id() != TypeId::of::() + return if (*value).type_id() != TypeId::of::() && TypeId::of::() != TypeId::of::() { - return None; + None } else { - return Some(DynamicReadLock(DynamicReadLockInner::Guard(value))); - } + Some(DynamicReadLock(DynamicReadLockInner::Guard(value))) + }; } _ => (), } @@ -1420,13 +1430,13 @@ impl Dynamic { Union::Shared(ref cell, ..) => { let guard = crate::func::locked_write(cell); - if (*guard).type_id() != TypeId::of::() + return if (*guard).type_id() != TypeId::of::() && TypeId::of::() != TypeId::of::() { - return None; + None } else { - return Some(DynamicWriteLock(DynamicWriteLockInner::Guard(guard))); - } + Some(DynamicWriteLock(DynamicWriteLockInner::Guard(guard))) + }; } _ => (), } diff --git a/src/types/fn_ptr.rs b/src/types/fn_ptr.rs index 6b8d6254..3ac75077 100644 --- a/src/types/fn_ptr.rs +++ b/src/types/fn_ptr.rs @@ -24,15 +24,15 @@ pub struct FnPtr { impl fmt::Debug for FnPtr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if !self.is_curried() { - write!(f, "Fn({})", self.fn_name()) - } else { + if self.is_curried() { self.curry .iter() .fold(f.debug_tuple("Fn").field(&self.name), |f, curry| { f.field(curry) }) .finish() + } else { + write!(f, "Fn({})", self.fn_name()) } } } @@ -149,7 +149,7 @@ impl FnPtr { #[cfg(not(feature = "no_function"))] _ast.as_ref(), ]; - let lib = if lib.first().map(|m: &&Module| m.is_empty()).unwrap_or(true) { + let lib = if lib.first().map_or(true, |m: &&Module| m.is_empty()) { &lib[0..0] } else { &lib diff --git a/src/types/immutable_string.rs b/src/types/immutable_string.rs index 8efed30b..b668ee15 100644 --- a/src/types/immutable_string.rs +++ b/src/types/immutable_string.rs @@ -159,7 +159,7 @@ impl FromIterator for ImmutableString { impl<'a> FromIterator<&'a char> for ImmutableString { #[inline] fn from_iter>(iter: T) -> Self { - Self(iter.into_iter().cloned().collect::().into()) + Self(iter.into_iter().copied().collect::().into()) } } @@ -576,6 +576,7 @@ impl PartialOrd for String { impl ImmutableString { /// Create a new [`ImmutableString`]. #[inline(always)] + #[must_use] pub fn new() -> Self { Self(SmartString::new_const().into()) } @@ -583,6 +584,7 @@ impl ImmutableString { /// /// If there are other references to the same string, a cloned copy is returned. #[inline] + #[must_use] pub fn into_owned(mut self) -> String { self.make_mut(); // Make sure it is unique reference shared_take(self.0).into() // Should succeed @@ -620,6 +622,7 @@ impl ImmutableString { /// assert!(!s2.ptr_eq(&s3)); /// ``` #[inline(always)] + #[must_use] pub fn ptr_eq(&self, other: &Self) -> bool { Shared::ptr_eq(&self.0, &other.0) } diff --git a/src/types/scope.rs b/src/types/scope.rs index 8c3b16ac..8939c94b 100644 --- a/src/types/scope.rs +++ b/src/types/scope.rs @@ -436,6 +436,7 @@ impl Scope<'_> { /// assert_eq!(my_scope.is_constant("y"), None); /// ``` #[inline] + #[must_use] pub fn is_constant(&self, name: &str) -> Option { self.get_index(name).map(|(.., access)| match access { AccessMode::ReadWrite => false,