From 31292e683db953d5a08915b32e62aad05b985c0d Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 23 Nov 2022 13:24:14 +0800 Subject: [PATCH] Satisfy Clippy. --- build.template | 2 +- codegen/Cargo.toml | 1 + src/api/call_fn.rs | 32 +++++++++++---------- src/api/compile.rs | 6 ++-- src/api/definitions/mod.rs | 52 +++++++++++++++++------------------ src/api/eval.rs | 7 +++-- src/api/json.rs | 7 +++-- src/api/mod.rs | 2 +- src/api/register.rs | 6 ++-- src/api/run.rs | 4 +-- src/api/type_names.rs | 4 +-- src/ast/ast.rs | 4 +-- src/ast/expr.rs | 18 ++++-------- src/config/hashing.rs | 4 +-- src/config/hashing_env.rs | 2 +- src/eval/cache.rs | 2 +- src/eval/chaining.rs | 8 +++++- src/eval/data_check.rs | 2 +- src/eval/debugger.rs | 6 ++-- src/eval/expr.rs | 22 +++++++++------ src/eval/stmt.rs | 45 ++++++++++++++++-------------- src/eval/target.rs | 28 ++++++++++++++----- src/func/builtin.rs | 15 ++++++++-- src/func/call.rs | 45 ++++++++++++++---------------- src/func/callable_function.rs | 9 +++--- src/func/func.rs | 1 - src/func/native.rs | 6 ++-- src/lib.rs | 1 + src/types/restore.rs | 10 +++---- 29 files changed, 193 insertions(+), 158 deletions(-) diff --git a/build.template b/build.template index bce322e8..783764e1 100644 --- a/build.template +++ b/build.template @@ -1,3 +1,3 @@ //! This file is automatically recreated during build time by `build.rs` from `build.template`. -pub(crate) const AHASH_SEED: Option<[u64; 4]> = {{AHASH_SEED}}; +pub const AHASH_SEED: Option<[u64; 4]> = {{AHASH_SEED}}; diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml index c1efde59..25e62112 100644 --- a/codegen/Cargo.toml +++ b/codegen/Cargo.toml @@ -5,6 +5,7 @@ edition = "2018" resolver = "2" authors = ["jhwgh1968", "Stephen Chung"] description = "Procedural macros support package for Rhai, a scripting language and engine for Rust" +keywords = ["rhai", "scripting", "scripting-engine", "scripting-language", "embedded", "plugin", "macros", "code-generation"] homepage = "https://rhai.rs/book/plugins/index.html" repository = "https://github.com/rhaiscript/rhai" license = "MIT OR Apache-2.0" diff --git a/src/api/call_fn.rs b/src/api/call_fn.rs index 0d0d5edf..02b062ab 100644 --- a/src/api/call_fn.rs +++ b/src/api/call_fn.rs @@ -18,6 +18,7 @@ use std::{ /// Options for calling a script-defined function via [`Engine::call_fn_with_options`]. #[derive(Debug, Hash)] #[non_exhaustive] +#[must_use] pub struct CallFnOptions<'t> { /// A value for binding to the `this` pointer (if any). pub this_ptr: Option<&'t mut Dynamic>, @@ -120,7 +121,7 @@ impl Engine { name: impl AsRef, args: impl FuncArgs, ) -> RhaiResultOf { - self.call_fn_with_options(Default::default(), scope, ast, name, args) + self.call_fn_with_options(CallFnOptions::default(), scope, ast, name, args) } /// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments. /// @@ -255,20 +256,23 @@ impl Engine { #[cfg(not(feature = "no_closure"))] crate::func::ensure_no_data_race(name, args, false).map(|_| Dynamic::UNIT)?; - if let Some(fn_def) = ast.shared_lib().get_script_fn(name, args.len()) { - self.call_script_fn( - global, - caches, - scope, - this_ptr, - fn_def, - args, - rewind_scope, - Position::NONE, + ast.shared_lib() + .get_script_fn(name, args.len()) + .map_or_else( + || Err(ERR::ErrorFunctionNotFound(name.into(), Position::NONE).into()), + |fn_def| { + self.call_script_fn( + global, + caches, + scope, + this_ptr, + fn_def, + args, + rewind_scope, + Position::NONE, + ) + }, ) - } else { - Err(ERR::ErrorFunctionNotFound(name.into(), Position::NONE).into()) - } }); #[cfg(feature = "debugging")] diff --git a/src/api/compile.rs b/src/api/compile.rs index 2d187160..0f14e199 100644 --- a/src/api/compile.rs +++ b/src/api/compile.rs @@ -1,7 +1,7 @@ //! Module that defines the public compilation API of [`Engine`]. use crate::parser::{ParseResult, ParseState}; -use crate::{Engine, OptimizationLevel, Scope, AST}; +use crate::{Engine, OptimizationLevel, Scope, StringsInterner, AST}; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -221,7 +221,7 @@ impl Engine { scripts.as_ref(), self.token_mapper.as_ref().map(<_>::as_ref), ); - let mut state = ParseState::new(self, scope, Default::default(), tokenizer_control); + let mut state = ParseState::new(self, scope, StringsInterner::default(), tokenizer_control); let mut _ast = self.parse(&mut stream.peekable(), &mut state, optimization_level)?; #[cfg(feature = "metadata")] _ast.set_doc(state.tokenizer_control.borrow().global_comments.join("\n")); @@ -294,7 +294,7 @@ impl Engine { self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref)); let mut peekable = stream.peekable(); - let mut state = ParseState::new(self, scope, Default::default(), tokenizer_control); + let mut state = ParseState::new(self, scope, StringsInterner::default(), tokenizer_control); self.parse_global_expr(&mut peekable, &mut state, |_| {}, self.optimization_level) } } diff --git a/src/api/definitions/mod.rs b/src/api/definitions/mod.rs index 54d9b2d7..0c6a84b1 100644 --- a/src/api/definitions/mod.rs +++ b/src/api/definitions/mod.rs @@ -77,7 +77,6 @@ pub struct DefinitionsConfig { impl Default for DefinitionsConfig { #[inline(always)] - #[must_use] fn default() -> Self { Self { write_headers: false, @@ -105,13 +104,13 @@ impl Definitions<'_> { /// Headers are always present in content that is expected to be written to a file /// (i.e. `write_to*` and `*_file` methods). #[inline(always)] - pub fn with_headers(mut self, headers: bool) -> Self { + pub const fn with_headers(mut self, headers: bool) -> Self { self.config.write_headers = headers; self } /// Include standard packages when writing definition files. #[inline(always)] - pub fn include_standard_packages(mut self, include_standard_packages: bool) -> Self { + pub const fn include_standard_packages(mut self, include_standard_packages: bool) -> Self { self.config.include_standard_packages = include_standard_packages; self } @@ -129,7 +128,6 @@ impl Definitions<'_> { } /// Get the configuration. #[inline(always)] - #[must_use] pub(crate) const fn config(&self) -> &DefinitionsConfig { &self.config } @@ -177,19 +175,19 @@ impl Definitions<'_> { let mut def_file = String::from("module static;\n\n"); if config.include_standard_packages { - def_file += &self.builtin_functions_operators_impl(&config); + def_file += &Self::builtin_functions_operators_impl(config); def_file += "\n"; - def_file += &self.builtin_functions_impl(&config); + def_file += &Self::builtin_functions_impl(config); def_file += "\n"; } - def_file += &self.static_module_impl(&config); + def_file += &self.static_module_impl(config); def_file += "\n"; #[cfg(not(feature = "no_module"))] { use std::fmt::Write; - for (module_name, module_def) in self.modules_impl(&config) { + for (module_name, module_def) in self.modules_impl(config) { write!( &mut def_file, "\nmodule {module_name} {{\n{module_def}\n}}\n" @@ -199,7 +197,7 @@ impl Definitions<'_> { def_file += "\n"; } - def_file += &self.scope_items_impl(&config); + def_file += &self.scope_items_impl(config); def_file += "\n"; @@ -220,11 +218,11 @@ impl Definitions<'_> { vec![ ( "__builtin__.d.rhai".to_string(), - self.builtin_functions_impl(&config), + Self::builtin_functions_impl(config), ), ( "__builtin-operators__.d.rhai".to_string(), - self.builtin_functions_operators_impl(&config), + Self::builtin_functions_operators_impl(config), ), ] } else { @@ -233,18 +231,18 @@ impl Definitions<'_> { .into_iter() .chain(std::iter::once(( "__static__.d.rhai".to_string(), - self.static_module_impl(&config), + self.static_module_impl(config), ))) .chain(self.scope.iter().map(move |_| { ( "__scope__.d.rhai".to_string(), - self.scope_items_impl(&config), + self.scope_items_impl(config), ) })) .chain( #[cfg(not(feature = "no_module"))] { - self.modules_impl(&config) + self.modules_impl(config) .map(|(name, def)| (format!("{name}.d.rhai"), def)) }, #[cfg(feature = "no_module")] @@ -258,12 +256,12 @@ impl Definitions<'_> { #[inline(always)] #[must_use] pub fn builtin_functions(&self) -> String { - self.builtin_functions_impl(&self.config) + Self::builtin_functions_impl(self.config) } /// Return definitions for all builtin functions. #[must_use] - fn builtin_functions_impl(&self, config: &DefinitionsConfig) -> String { + fn builtin_functions_impl(config: DefinitionsConfig) -> String { let def = include_str!("builtin-functions.d.rhai"); if config.write_headers { @@ -277,12 +275,12 @@ impl Definitions<'_> { #[inline(always)] #[must_use] pub fn builtin_functions_operators(&self) -> String { - self.builtin_functions_operators_impl(&self.config) + Self::builtin_functions_operators_impl(self.config) } /// Return definitions for all builtin operators. #[must_use] - fn builtin_functions_operators_impl(&self, config: &DefinitionsConfig) -> String { + fn builtin_functions_operators_impl(config: DefinitionsConfig) -> String { let def = include_str!("builtin-operators.d.rhai"); if config.write_headers { @@ -296,22 +294,22 @@ impl Definitions<'_> { #[inline(always)] #[must_use] pub fn static_module(&self) -> String { - self.static_module_impl(&self.config) + self.static_module_impl(self.config) } /// Return definitions for all globally available functions and constants. #[must_use] - fn static_module_impl(&self, config: &DefinitionsConfig) -> String { + fn static_module_impl(&self, config: DefinitionsConfig) -> String { let mut s = if config.write_headers { String::from("module static;\n\n") } else { String::new() }; - let exclude_flags = if !self.config.include_standard_packages { - ModuleFlags::STANDARD_LIB - } else { + let exclude_flags = if self.config.include_standard_packages { ModuleFlags::empty() + } else { + ModuleFlags::STANDARD_LIB }; self.engine @@ -333,12 +331,12 @@ impl Definitions<'_> { #[inline(always)] #[must_use] pub fn scope_items(&self) -> String { - self.scope_items_impl(&self.config) + self.scope_items_impl(self.config) } /// Return definitions for all items inside the [`Scope`], if any. #[must_use] - fn scope_items_impl(&self, config: &DefinitionsConfig) -> String { + fn scope_items_impl(&self, config: DefinitionsConfig) -> String { let mut s = if config.write_headers { String::from("module static;\n\n") } else { @@ -358,14 +356,14 @@ impl Definitions<'_> { #[cfg(not(feature = "no_module"))] #[inline(always)] pub fn modules(&self) -> impl Iterator + '_ { - self.modules_impl(&self.config) + self.modules_impl(self.config) } /// Return a (module name, definitions) pair for each registered static [module][Module]. #[cfg(not(feature = "no_module"))] fn modules_impl( &self, - config: &DefinitionsConfig, + config: DefinitionsConfig, ) -> impl Iterator + '_ { let mut m = self .engine diff --git a/src/api/eval.rs b/src/api/eval.rs index a919089d..5c2078d2 100644 --- a/src/api/eval.rs +++ b/src/api/eval.rs @@ -4,7 +4,8 @@ use crate::eval::{Caches, GlobalRuntimeState}; use crate::parser::ParseState; use crate::types::dynamic::Variant; use crate::{ - reify, Dynamic, Engine, OptimizationLevel, Position, RhaiResult, RhaiResultOf, Scope, AST, ERR, + reify, Dynamic, Engine, OptimizationLevel, Position, RhaiResult, RhaiResultOf, Scope, + StringsInterner, AST, ERR, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -69,7 +70,7 @@ impl Engine { ) -> RhaiResultOf { let ast = self.compile_with_scope_and_optimization_level( scope, - &[script], + [script], self.optimization_level, )?; self.eval_ast_with_scope(scope, &ast) @@ -119,7 +120,7 @@ impl Engine { let scripts = [script]; let (stream, tokenizer_control) = self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref)); - let mut state = ParseState::new(self, scope, Default::default(), tokenizer_control); + let mut state = ParseState::new(self, scope, StringsInterner::default(), tokenizer_control); // No need to optimize a lone expression let ast = self.parse_global_expr( diff --git a/src/api/json.rs b/src/api/json.rs index f692e160..65d37719 100644 --- a/src/api/json.rs +++ b/src/api/json.rs @@ -3,7 +3,7 @@ use crate::parser::{ParseSettingFlags, ParseState}; use crate::tokenizer::Token; -use crate::{Engine, LexError, Map, OptimizationLevel, RhaiResultOf, Scope}; +use crate::{Engine, LexError, Map, OptimizationLevel, RhaiResultOf, Scope, StringsInterner}; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -117,7 +117,8 @@ impl Engine { ); let scope = Scope::new(); - let mut state = ParseState::new(self, &scope, Default::default(), tokenizer_control); + let mut state = + ParseState::new(self, &scope, StringsInterner::default(), tokenizer_control); let ast = self.parse_global_expr( &mut stream.peekable(), @@ -165,7 +166,7 @@ pub fn format_map_as_json(map: &Map) -> String { result.push(':'); if let Some(val) = value.read_lock::() { - result.push_str(&format_map_as_json(&*val)); + result.push_str(&format_map_as_json(&val)); } else if value.is_unit() { result.push_str("null"); } else { diff --git a/src/api/mod.rs b/src/api/mod.rs index 633a9800..6f1ad649 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -191,7 +191,7 @@ impl Engine { /// Get the default value of the custom state for each evaluation run. #[inline(always)] #[must_use] - pub fn default_tag(&self) -> &Dynamic { + pub const fn default_tag(&self) -> &Dynamic { &self.def_tag } /// Get a mutable reference to the default value of the custom state for each evaluation run. diff --git a/src/api/register.rs b/src/api/register.rs index 84d8f4fa..0ff7dedf 100644 --- a/src/api/register.rs +++ b/src/api/register.rs @@ -742,10 +742,10 @@ impl Engine { signatures.extend(m.gen_fn_signatures().map(|f| format!("{name}::{f}"))); } - let exclude_flags = if !include_packages { - ModuleFlags::INTERNAL | ModuleFlags::STANDARD_LIB - } else { + let exclude_flags = if include_packages { ModuleFlags::INTERNAL + } else { + ModuleFlags::INTERNAL | ModuleFlags::STANDARD_LIB }; signatures.extend( diff --git a/src/api/run.rs b/src/api/run.rs index a83a3a73..f5fa71e8 100644 --- a/src/api/run.rs +++ b/src/api/run.rs @@ -2,7 +2,7 @@ use crate::eval::{Caches, GlobalRuntimeState}; use crate::parser::ParseState; -use crate::{Engine, RhaiResultOf, Scope, AST}; +use crate::{Engine, RhaiResultOf, Scope, StringsInterner, AST}; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -58,7 +58,7 @@ impl Engine { let scripts = [script]; let (stream, tokenizer_control) = self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref)); - let mut state = ParseState::new(self, scope, Default::default(), tokenizer_control); + let mut state = ParseState::new(self, scope, StringsInterner::default(), tokenizer_control); let ast = self.parse(&mut stream.peekable(), &mut state, self.optimization_level)?; self.run_ast_with_scope(scope, &ast) } diff --git a/src/api/type_names.rs b/src/api/type_names.rs index dda879fc..07434e4d 100644 --- a/src/api/type_names.rs +++ b/src/api/type_names.rs @@ -139,8 +139,8 @@ pub fn format_type(typ: &str, is_return_type: bool) -> std::borrow::Cow { } else { format!("&mut {r}").into() }; - } else if typ.contains(" ") { - let typ = typ.replace(" ", ""); + } else if typ.contains(' ') { + let typ = typ.replace(' ', ""); let r = format_type(&typ, is_return_type); return r.into_owned().into(); } diff --git a/src/ast/ast.rs b/src/ast/ast.rs index 71b07669..1d3b993d 100644 --- a/src/ast/ast.rs +++ b/src/ast/ast.rs @@ -772,7 +772,7 @@ impl AST { /// Not available under `no_function`. #[cfg(not(feature = "no_function"))] #[inline] - pub fn iter_functions<'a>(&'a self) -> impl Iterator + 'a { + pub fn iter_functions(&self) -> impl Iterator { self.lib .iter_script_fn() .map(|(.., fn_def)| fn_def.as_ref().into()) @@ -942,7 +942,7 @@ impl Borrow for AST { #[inline(always)] #[must_use] fn borrow(&self) -> &crate::Module { - &self.shared_lib() + self.shared_lib() } } diff --git a/src/ast/expr.rs b/src/ast/expr.rs index fc8c942c..3636cb9e 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -173,7 +173,7 @@ impl FnCallHashes { /// The hash returned is never zero. #[inline(always)] #[must_use] - pub fn native(&self) -> u64 { + pub const fn native(&self) -> u64 { self.native.get() } /// Get the script hash. @@ -837,18 +837,12 @@ impl Expr { #[cfg(not(feature = "no_custom_syntax"))] Self::Custom(..) => false, - Self::Variable(..) => match token { - Token::LeftParen => true, - Token::Unit => true, - Token::Bang => true, - Token::DoubleColon => true, - _ => false, - }, + Self::Variable(..) => matches!( + token, + Token::LeftParen | Token::Unit | Token::Bang | Token::DoubleColon + ), - Self::Property(..) => match token { - Token::LeftParen => true, - _ => false, - }, + Self::Property(..) => matches!(token, Token::LeftParen), } } /// Recursively walk this expression. diff --git a/src/config/hashing.rs b/src/config/hashing.rs index 314814a6..717f9654 100644 --- a/src/config/hashing.rs +++ b/src/config/hashing.rs @@ -165,7 +165,7 @@ where unsafe impl Sync for SusLock where T: 'static {} unsafe impl Send for SusLock where T: 'static {} -impl RefUnwindSafe for SusLock where T: 'static {} +impl RefUnwindSafe for SusLock {} impl Drop for SusLock where @@ -174,7 +174,7 @@ where #[inline] fn drop(&mut self) { if self.initialized.load(Ordering::SeqCst) { - unsafe { (&mut *self.data.get()).assume_init_drop() }; + unsafe { (*self.data.get()).assume_init_drop() }; } } } diff --git a/src/config/hashing_env.rs b/src/config/hashing_env.rs index 59930ad8..9890487c 100644 --- a/src/config/hashing_env.rs +++ b/src/config/hashing_env.rs @@ -1,3 +1,3 @@ //! This file is automatically recreated during build time by `build.rs` from `build.template`. -pub(crate) const AHASH_SEED: Option<[u64; 4]> = None; +pub const AHASH_SEED: Option<[u64; 4]> = None; diff --git a/src/eval/cache.rs b/src/eval/cache.rs index 96160d7e..affe2b69 100644 --- a/src/eval/cache.rs +++ b/src/eval/cache.rs @@ -72,7 +72,7 @@ impl Caches { /// Push an empty function resolution cache onto the stack and make it current. #[inline(always)] pub fn push_fn_resolution_cache(&mut self) { - self.0.push(Default::default()); + self.0.push(FnResolutionCache::default()); } /// Rewind the function resolution caches stack to a particular size. #[inline(always)] diff --git a/src/eval/chaining.rs b/src/eval/chaining.rs index d61c78ab..63551fc4 100644 --- a/src/eval/chaining.rs +++ b/src/eval/chaining.rs @@ -168,6 +168,7 @@ impl Engine { ERR::ErrorBitFieldBounds(crate::INT_BITS, end, idx_pos).into() })?; + #[allow(clippy::cast_possible_truncation)] if end <= start { (0, 0) } else if end == crate::INT_BITS && start == 0 { @@ -193,6 +194,7 @@ impl Engine { ERR::ErrorBitFieldBounds(crate::INT_BITS, end, idx_pos).into() })?; + #[allow(clippy::cast_possible_truncation)] if end < start { (0, 0) } else if end == crate::INT_BITS - 1 && start == 0 { @@ -237,6 +239,7 @@ impl Engine { Ok(Target::Bit { source: target, value: bit_value.into(), + #[allow(clippy::cast_possible_truncation)] bit: bit as u8, }) } @@ -249,12 +252,14 @@ impl Engine { .map_err(|typ| self.make_type_mismatch_err::(typ, idx_pos))?; let (ch, offset) = if index >= 0 { + #[allow(clippy::absurd_extreme_comparisons)] if index >= crate::MAX_USIZE_INT { return Err( ERR::ErrorStringBounds(s.chars().count(), index, idx_pos).into() ); } + #[allow(clippy::cast_sign_loss)] let offset = index as usize; ( s.chars().nth(offset).ok_or_else(|| { @@ -265,12 +270,13 @@ impl Engine { } else { let abs_index = index.unsigned_abs(); - if abs_index as u64 > usize::MAX as u64 { + if abs_index > usize::MAX as u64 { return Err( ERR::ErrorStringBounds(s.chars().count(), index, idx_pos).into() ); } + #[allow(clippy::cast_possible_truncation)] let offset = abs_index as usize; ( // Count from end if negative diff --git a/src/eval/data_check.rs b/src/eval/data_check.rs index 30a75fad..cf6c8ece 100644 --- a/src/eval/data_check.rs +++ b/src/eval/data_check.rs @@ -59,7 +59,7 @@ impl Dynamic { } 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), + Union::Shared(..) if _top => self.read_lock::().unwrap().calc_data_sizes(true), #[cfg(not(feature = "no_closure"))] Union::Shared(..) => { unreachable!("shared values discovered within data: {}", self) diff --git a/src/eval/debugger.rs b/src/eval/debugger.rs index bf74af3d..d43da7da 100644 --- a/src/eval/debugger.rs +++ b/src/eval/debugger.rs @@ -193,7 +193,7 @@ impl BreakPoint { /// Is this [`BreakPoint`] enabled? #[inline(always)] #[must_use] - pub fn is_enabled(&self) -> bool { + pub const fn is_enabled(&self) -> bool { match self { #[cfg(not(feature = "no_position"))] Self::AtPosition { enabled, .. } => *enabled, @@ -268,7 +268,7 @@ impl Debugger { /// Create a new [`Debugger`]. #[inline(always)] #[must_use] - pub fn new(status: DebuggerStatus, state: Dynamic) -> Self { + pub const fn new(status: DebuggerStatus, state: Dynamic) -> Self { Self { status, break_points: Vec::new(), @@ -297,7 +297,7 @@ impl Debugger { pos: Position, ) { self.call_stack.push(CallStackFrame { - fn_name: fn_name.into(), + fn_name, args, source, pos, diff --git a/src/eval/expr.rs b/src/eval/expr.rs index 9fcfddde..7cf213fb 100644 --- a/src/eval/expr.rs +++ b/src/eval/expr.rs @@ -156,7 +156,7 @@ impl Engine { .any(|(_, _, f, ..)| f == v.3.as_str()) => { let val: Dynamic = - crate::FnPtr::new_unchecked(v.3.as_str(), Default::default()).into(); + crate::FnPtr::new_unchecked(v.3.as_str(), crate::StaticVec::default()).into(); return Ok(val.into()); } Expr::Variable(v, None, ..) => v.0.map_or(0, NonZeroUsize::get), @@ -186,14 +186,20 @@ impl Engine { match scope.search(var_name) { Some(index) => index, None => { - return match self.global_modules.iter().find_map(|m| m.get_var(var_name)) { - Some(val) => Ok(val.into()), - None => Err(ERR::ErrorVariableNotFound( - var_name.to_string(), - expr.position(), + return self + .global_modules + .iter() + .find_map(|m| m.get_var(var_name)) + .map_or_else( + || { + Err(ERR::ErrorVariableNotFound( + var_name.to_string(), + expr.position(), + ) + .into()) + }, + |val| Ok(val.into()), ) - .into()), - } } } }; diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 1b4e7050..dca988dc 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -533,6 +533,7 @@ impl Engine { let index_value = x as INT; #[cfg(not(feature = "unchecked"))] + #[allow(clippy::absurd_extreme_comparisons)] if index_value > crate::MAX_USIZE_INT { return Err(ERR::ErrorArithmetic( format!("for-loop counter overflow: {x}"), @@ -799,10 +800,10 @@ impl Engine { Err(ERR::ErrorModuleNotFound(path.to_string(), path_pos).into()) })?; - let (export, must_be_indexed) = if !export.is_empty() { - (export.name.clone(), true) - } else { + let (export, must_be_indexed) = if export.is_empty() { (self.const_empty_string(), false) + } else { + (export.name.clone(), true) }; if !must_be_indexed || module.is_indexed() { @@ -824,13 +825,14 @@ impl Engine { Stmt::Export(x, ..) => { let (Ident { name, pos, .. }, Ident { name: alias, .. }) = &**x; // Mark scope variables as public - if let Some(index) = scope.search(name) { - let alias = if alias.is_empty() { name } else { alias }.clone(); - scope.add_alias_by_index(index, alias.into()); - Ok(Dynamic::UNIT) - } else { - Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into()) - } + scope.search(name).map_or_else( + || Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into()), + |index| { + let alias = if alias.is_empty() { name } else { alias }.clone(); + scope.add_alias_by_index(index, alias); + Ok(Dynamic::UNIT) + }, + ) } // Share statement @@ -838,20 +840,21 @@ impl Engine { Stmt::Share(x) => { x.iter() .try_for_each(|(name, index, pos)| { - if let Some(index) = index + index .map(|n| scope.len() - n.get()) .or_else(|| scope.search(name)) - { - let val = scope.get_mut_by_index(index); + .map_or_else( + || Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into()), + |index| { + 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(()) - } else { - Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into()) - } + if !val.is_shared() { + // Replace the variable with a shared value. + *val = std::mem::take(val).into_shared(); + } + Ok(()) + }, + ) }) .map(|_| Dynamic::UNIT) } diff --git a/src/eval/target.rs b/src/eval/target.rs index 199cf8a7..59a89411 100644 --- a/src/eval/target.rs +++ b/src/eval/target.rs @@ -15,6 +15,11 @@ use std::{ /// Values going over bounds are limited to the actual length. #[cfg(not(feature = "no_index"))] #[inline] +#[allow( + clippy::cast_sign_loss, + clippy::absurd_extreme_comparisons, + clippy::cast_possible_truncation +)] pub fn calc_offset_len(length: usize, start: crate::INT, len: crate::INT) -> (usize, usize) { let start = if start < 0 { let abs_start = start.unsigned_abs(); @@ -47,6 +52,11 @@ pub fn calc_offset_len(length: usize, start: crate::INT, len: crate::INT) -> (us /// Values going over bounds call the provided closure to return a default value or an error. #[inline] #[allow(dead_code)] +#[allow( + clippy::cast_sign_loss, + clippy::cast_possible_truncation, + clippy::absurd_extreme_comparisons +)] pub fn calc_index( length: usize, start: crate::INT, @@ -54,13 +64,14 @@ pub fn calc_index( err_func: impl FnOnce() -> Result, ) -> Result { if start < 0 && negative_count_from_end { - let abs_start = start.unsigned_abs() as usize; - - // Count from end if negative - if abs_start <= length { - return Ok(length - abs_start); - } + let abs_start = start.unsigned_abs(); + return Ok(if abs_start as u64 > crate::MAX_USIZE_INT as u64 { + 0 + } else { + length - usize::min(abs_start as usize, length) + }); } + if start <= crate::MAX_USIZE_INT && (start as usize) < length { return Ok(start as usize); } @@ -313,7 +324,10 @@ impl<'a> Target<'a> { let value = &mut *source.write_lock::().expect("`Blob`"); - value[*index] = (new_byte & 0x00ff) as u8; + #[allow(clippy::cast_sign_loss)] + { + value[*index] = (new_byte & 0x00ff) as u8; + } } #[cfg(not(feature = "no_index"))] Self::StringChar { diff --git a/src/func/builtin.rs b/src/func/builtin.rs index a4b00050..118dd37e 100644 --- a/src/func/builtin.rs +++ b/src/func/builtin.rs @@ -1,7 +1,10 @@ //! Built-in implementations for common operators. +#![allow(clippy::float_cmp)] + use super::call::FnCallArgs; use super::native::FnBuiltin; +#[allow(clippy::enum_glob_use)] use crate::tokenizer::{Token, Token::*}; use crate::{ Dynamic, ExclusiveRange, ImmutableString, InclusiveRange, NativeCallContext, RhaiResult, @@ -68,13 +71,11 @@ fn is_numeric(type_id: TypeId) -> bool { /// A function that returns `true`. #[inline(always)] -#[must_use] fn const_true_fn(_: NativeCallContext, _: &mut [&mut Dynamic]) -> RhaiResult { Ok(Dynamic::TRUE) } /// A function that returns `false`. #[inline(always)] -#[must_use] fn const_false_fn(_: NativeCallContext, _: &mut [&mut Dynamic]) -> RhaiResult { Ok(Dynamic::FALSE) } @@ -143,6 +144,7 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option< if type1 == type2 { if type1 == TypeId::of::() { #[cfg(not(feature = "unchecked"))] + #[allow(clippy::wildcard_imports)] use crate::packages::arithmetic::arith_basic::INT::functions::*; #[cfg(not(feature = "unchecked"))] @@ -340,6 +342,7 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option< ($x:ty, $xx:ident, $y:ty, $yy:ident) => { if (type1, type2) == (TypeId::of::<$x>(), TypeId::of::<$y>()) { #[cfg(not(feature = "unchecked"))] + #[allow(clippy::wildcard_imports)] use crate::packages::arithmetic::decimal_functions::builtin::*; #[cfg(not(feature = "unchecked"))] @@ -632,6 +635,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt if type1 == type2 { if type1 == TypeId::of::() { #[cfg(not(feature = "unchecked"))] + #[allow(clippy::wildcard_imports)] use crate::packages::arithmetic::arith_basic::INT::functions::*; #[cfg(not(feature = "unchecked"))] @@ -720,6 +724,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt #[cfg(not(feature = "no_index"))] if type1 == TypeId::of::() { + #[allow(clippy::wildcard_imports)] use crate::packages::array_basic::array_functions::*; use crate::Array; @@ -751,6 +756,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt #[cfg(not(feature = "no_index"))] if type1 == TypeId::of::() { + #[allow(clippy::wildcard_imports)] use crate::packages::blob_basic::blob_functions::*; use crate::Blob; @@ -801,6 +807,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt ($x:ident, $xx:ident, $y:ty, $yy:ident) => { if (type1, type2) == (TypeId::of::<$x>(), TypeId::of::<$y>()) { #[cfg(not(feature = "unchecked"))] + #[allow(clippy::wildcard_imports)] use crate::packages::arithmetic::decimal_functions::builtin::*; #[cfg(not(feature = "unchecked"))] @@ -887,6 +894,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt // array op= any #[cfg(not(feature = "no_index"))] if type1 == TypeId::of::() { + #[allow(clippy::wildcard_imports)] use crate::packages::array_basic::array_functions::*; use crate::Array; @@ -916,6 +924,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt // blob op= int if (type1, type2) == (TypeId::of::(), TypeId::of::()) { + #[allow(clippy::wildcard_imports)] use crate::packages::blob_basic::blob_functions::*; return match op { @@ -935,6 +944,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt // blob op= char if (type1, type2) == (TypeId::of::(), TypeId::of::()) { + #[allow(clippy::wildcard_imports)] use crate::packages::blob_basic::blob_functions::*; return match op { @@ -954,6 +964,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt // blob op= string if (type1, type2) == (TypeId::of::(), TypeId::of::()) { + #[allow(clippy::wildcard_imports)] use crate::packages::blob_basic::blob_functions::*; return match op { diff --git a/src/func/call.rs b/src/func/call.rs index 4e6ef6cb..932f4f3f 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -90,11 +90,7 @@ impl<'a> ArgBackup<'a> { /// exiting the current scope. Otherwise it is undefined behavior as the shorter lifetime will leak. #[inline(always)] pub fn restore_first_arg(&mut self, args: &mut FnCallArgs<'a>) { - if let Some(p) = self.orig_mut.take() { - args[0] = p; - } else { - unreachable!("`Some`"); - } + args[0] = self.orig_mut.take().expect("`Some`"); } } @@ -116,7 +112,7 @@ pub fn ensure_no_data_race(fn_name: &str, args: &FnCallArgs, is_ref_mut: bool) - if let Some((n, ..)) = args .iter() .enumerate() - .skip(if is_ref_mut { 1 } else { 0 }) + .skip(usize::from(is_ref_mut)) .find(|(.., a)| a.is_locked()) { return Err(ERR::ErrorDataRace( @@ -277,7 +273,7 @@ impl Engine { Some(token) if token.is_op_assignment() => { let (first_arg, rest_args) = args.split_first().unwrap(); - get_builtin_op_assignment_fn(token, *first_arg, rest_args[0]) + get_builtin_op_assignment_fn(token, first_arg, rest_args[0]) .map(|f| FnResolutionCacheEntry { func: CallableFunction::Method(Shared::new(f)), source: None, @@ -344,7 +340,7 @@ impl Engine { name: &str, op_token: Option<&Token>, hash: u64, - mut args: &mut FnCallArgs, + args: &mut FnCallArgs, is_ref_mut: bool, pos: Position, ) -> RhaiResultOf<(Dynamic, bool)> { @@ -381,7 +377,7 @@ impl Engine { } let args = - &mut *RestoreOnDrop::lock_if(swap, &mut args, move |a| backup.restore_first_arg(a)); + &mut *RestoreOnDrop::lock_if(swap, args, move |a| backup.restore_first_arg(a)); #[cfg(feature = "debugging")] if self.debugger.is_some() { @@ -423,7 +419,7 @@ impl Engine { _ => false, }; if trigger { - let scope = &mut &mut Scope::new(); + let scope = &mut Scope::new(); let mut this = Dynamic::NULL; let node = crate::ast::Stmt::Noop(pos); let node = (&node).into(); @@ -597,12 +593,13 @@ impl Engine { let num_params = _args[1].as_int().expect("`INT`"); return Ok(( - if num_params < 0 || num_params > crate::MAX_USIZE_INT { - false - } else { + if (0..=crate::MAX_USIZE_INT).contains(&num_params) { + #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] let hash_script = calc_fn_hash(None, fn_name.as_str(), num_params as usize); self.has_script_fn(global, caches, hash_script) + } else { + false } .into(), false, @@ -647,12 +644,11 @@ impl Engine { } let mut empty_scope; - let scope = match _scope { - Some(scope) => scope, - None => { - empty_scope = Scope::new(); - &mut empty_scope - } + let scope = if let Some(scope) = _scope { + scope + } else { + empty_scope = Scope::new(); + &mut empty_scope }; let orig_source = mem::replace(&mut global.source, source.clone()); @@ -676,7 +672,7 @@ impl Engine { backup.change_first_arg_to_copy(_args); } - let args = &mut *RestoreOnDrop::lock_if(swap, &mut _args, move |a| { + let args = &mut *RestoreOnDrop::lock_if(swap, _args, move |a| { backup.restore_first_arg(a) }); @@ -901,7 +897,7 @@ impl Engine { call_args = &mut _arg_values; } // Recalculate the hash based on the new function name and new arguments - hash = if !is_anon && !is_valid_function_name(&fn_name) { + hash = if !is_anon && !is_valid_function_name(fn_name) { FnCallHashes::from_native(calc_fn_hash( None, fn_name, @@ -963,7 +959,7 @@ impl Engine { ) -> RhaiResult { let mut first_arg = first_arg; let mut a_expr = args_expr; - let mut total_args = if first_arg.is_some() { 1 } else { 0 } + a_expr.len(); + let mut total_args = usize::from(first_arg.is_some()) + a_expr.len(); let mut curry = FnArgsVec::new_const(); let mut name = fn_name; let mut hashes = hashes; @@ -1077,9 +1073,10 @@ impl Engine { .as_int() .map_err(|typ| self.make_type_mismatch_err::(typ, arg_pos))?; - return Ok(if num_params < 0 || num_params > crate::MAX_USIZE_INT { + return Ok(if !(0..=crate::MAX_USIZE_INT).contains(&num_params) { false } else { + #[allow(clippy::cast_sign_loss)] let hash_script = calc_fn_hash(None, &fn_name, num_params as usize); self.has_script_fn(global, caches, hash_script) } @@ -1437,7 +1434,7 @@ impl Engine { // No optimizations because we only run it once let ast = self.compile_with_scope_and_optimization_level( &Scope::new(), - &[script], + [script], #[cfg(not(feature = "no_optimize"))] OptimizationLevel::None, #[cfg(feature = "no_optimize")] diff --git a/src/func/callable_function.rs b/src/func/callable_function.rs index 893709b6..4d441e63 100644 --- a/src/func/callable_function.rs +++ b/src/func/callable_function.rs @@ -132,9 +132,7 @@ impl CallableFunction { #[cfg(not(feature = "no_function"))] match self { - Self::Pure(..) | Self::Method(..) => true, - Self::Plugin(..) => true, - Self::Iterator(..) => true, + Self::Pure(..) | Self::Method(..) | Self::Plugin(..) | Self::Iterator(..) => true, Self::Script(..) => false, } } @@ -147,8 +145,9 @@ impl CallableFunction { #[cfg(not(feature = "no_function"))] match self { - Self::Plugin(..) => FnAccess::Public, - Self::Pure(..) | Self::Method(..) | Self::Iterator(..) => FnAccess::Public, + Self::Plugin(..) | Self::Pure(..) | Self::Method(..) | Self::Iterator(..) => { + FnAccess::Public + } Self::Script(f) => f.access, } } diff --git a/src/func/func.rs b/src/func/func.rs index 7d211879..97bcfb04 100644 --- a/src/func/func.rs +++ b/src/func/func.rs @@ -80,7 +80,6 @@ pub trait Func { /// # Ok(()) /// # } /// ``` - #[must_use] fn create_from_script(self, script: &str, entry_point: &str) -> ParseResult; } diff --git a/src/func/native.rs b/src/func/native.rs index 7363606a..22a5579b 100644 --- a/src/func/native.rs +++ b/src/func/native.rs @@ -151,7 +151,7 @@ impl<'a> NativeCallContext<'a> { #[cfg(not(feature = "no_module"))] #[inline(always)] #[must_use] - pub fn new_with_all_fields( + pub const fn new_with_all_fields( engine: &'a Engine, fn_name: &'a str, source: Option<&'a str>, @@ -240,7 +240,7 @@ impl<'a> NativeCallContext<'a> { /// Custom state kept in a [`Dynamic`]. #[inline(always)] #[must_use] - pub fn tag(&self) -> Option<&Dynamic> { + pub const fn tag(&self) -> Option<&Dynamic> { Some(&self.global.tag) } /// Get an iterator over the current set of modules imported via `import` statements @@ -278,7 +278,7 @@ impl<'a> NativeCallContext<'a> { #[cfg(not(feature = "no_function"))] #[inline] pub fn iter_namespaces(&self) -> impl Iterator { - self.global.lib.iter().map(|m| m.as_ref()) + self.global.lib.iter().map(AsRef::as_ref) } /// _(internals)_ The current stack of namespaces containing definitions of all script-defined functions. /// Exported under the `internals` feature only. diff --git a/src/lib.rs b/src/lib.rs index 2ddb652a..2880e6be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,6 +65,7 @@ #![warn(clippy::undocumented_unsafe_blocks)] #![allow(clippy::unit_arg)] #![allow(clippy::missing_errors_doc)] +#![allow(clippy::missing_panics_doc)] #![allow(clippy::used_underscore_binding)] #![allow(clippy::inline_always)] #![allow(clippy::module_name_repetitions)] diff --git a/src/types/restore.rs b/src/types/restore.rs index 6d0ad595..6d99848a 100644 --- a/src/types/restore.rs +++ b/src/types/restore.rs @@ -6,12 +6,12 @@ use std::prelude::v1::*; /// Run custom restoration logic upon the end of scope. #[must_use] -pub struct RestoreOnDrop<'a, T, R: FnOnce(&mut T)> { +pub struct RestoreOnDrop<'a, T: ?Sized, R: FnOnce(&mut T)> { value: &'a mut T, restore: Option, } -impl<'a, T, R: FnOnce(&mut T)> RestoreOnDrop<'a, T, R> { +impl<'a, T: ?Sized, R: FnOnce(&mut T)> RestoreOnDrop<'a, T, R> { /// Create a new [`RestoreOnDrop`] that locks a mutable reference and runs restoration logic at /// the end of scope only when `need_restore` is `true`. /// @@ -39,7 +39,7 @@ impl<'a, T, R: FnOnce(&mut T)> RestoreOnDrop<'a, T, R> { } } -impl<'a, T, R: FnOnce(&mut T)> Drop for RestoreOnDrop<'a, T, R> { +impl<'a, T: ?Sized, R: FnOnce(&mut T)> Drop for RestoreOnDrop<'a, T, R> { #[inline(always)] fn drop(&mut self) { if let Some(restore) = self.restore.take() { @@ -48,7 +48,7 @@ impl<'a, T, R: FnOnce(&mut T)> Drop for RestoreOnDrop<'a, T, R> { } } -impl<'a, T, R: FnOnce(&mut T)> Deref for RestoreOnDrop<'a, T, R> { +impl<'a, T: ?Sized, R: FnOnce(&mut T)> Deref for RestoreOnDrop<'a, T, R> { type Target = T; #[inline(always)] @@ -57,7 +57,7 @@ impl<'a, T, R: FnOnce(&mut T)> Deref for RestoreOnDrop<'a, T, R> { } } -impl<'a, T, R: FnOnce(&mut T)> DerefMut for RestoreOnDrop<'a, T, R> { +impl<'a, T: ?Sized, R: FnOnce(&mut T)> DerefMut for RestoreOnDrop<'a, T, R> { #[inline(always)] fn deref_mut(&mut self) -> &mut Self::Target { self.value