diff --git a/src/ast.rs b/src/ast.rs index ed161df0..2a19abc1 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1651,7 +1651,7 @@ impl Stmt { _ => (), } - path.pop().expect("`path` contains current node"); + path.pop().expect("contains current node"); true } @@ -1727,7 +1727,7 @@ impl OpAssignment<'_> { pub fn new(op: Token) -> Self { let op_raw = op .map_op_assignment() - .expect("token is op-assignment operator") + .expect("op-assignment") .literal_syntax(); let op_assignment = op.literal_syntax(); @@ -1842,13 +1842,19 @@ pub struct FnCallExpr { pub args: StaticVec, /// List of function call arguments that are constants. /// - /// Any arguments in `args` that is [`Expr::Stack`][Expr::Stack] indexes into this + /// Any arguments in `args` that is [`Expr::Stack`] indexes into this /// array to find the constant for use as its argument value. + /// + /// # Notes + /// + /// Constant arguments are very common in function calls, and keeping each constant in + /// an [`Expr::DynamicConstant`] involves an additional allocation. Keeping the constant + /// values in an inlined array avoids these extra allocations. pub constants: smallvec::SmallVec<[Dynamic; 2]>, /// Function name. pub name: Identifier, /// Does this function call capture the parent scope? - pub capture: bool, + pub capture_parent_scope: bool, } impl FnCallExpr { @@ -1858,7 +1864,7 @@ impl FnCallExpr { pub const fn is_qualified(&self) -> bool { self.namespace.is_some() } - /// Convert this into a [`FnCall`][Expr::FnCall]. + /// Convert this into an [`Expr::FnCall`]. #[inline(always)] #[must_use] pub fn into_fn_call_expr(self, pos: Position) -> Expr { @@ -1996,8 +2002,9 @@ impl FloatWrapper { #[derive(Clone, Hash)] pub enum Expr { /// Dynamic constant. - /// Used to hold either an [`Array`] or [`Map`][crate::Map] literal for quick cloning. - /// All other primitive data types should use the appropriate variants for better speed. + /// + /// Used to hold complex constants such as [`Array`] or [`Map`][crate::Map] for quick cloning. + /// Primitive data types should use the appropriate variants to avoid an allocation. DynamicConstant(Box, Position), /// Boolean constant. BoolConstant(bool, Position), @@ -2045,13 +2052,11 @@ pub enum Expr { (ImmutableString, Position), )>, ), - /// Stack slot + /// Stack slot for function calls. See [`FnCallExpr`] for more details. /// - /// # Notes - /// - /// This variant does not map to any language structure. It is currently only used in function - /// calls with constant arguments where the `usize` number indexes into an array containing a - /// list of constant arguments for the function call. See [`FnCallExpr`] for more details. + /// This variant does not map to any language structure. It is used in function calls with + /// constant arguments where the `usize` number indexes into an array containing a list of + /// constant arguments for the function call. Stack(usize, Position), /// { [statement][Stmt] ... } Stmt(Box), @@ -2130,8 +2135,8 @@ impl fmt::Debug for Expr { if !x.constants.is_empty() { ff.field("constants", &x.constants); } - if x.capture { - ff.field("capture", &x.capture); + if x.capture_parent_scope { + ff.field("capture_parent_scope", &x.capture_parent_scope); } ff.finish() } @@ -2186,10 +2191,10 @@ impl Expr { #[cfg(not(feature = "no_index"))] Self::Array(x, _) if self.is_constant() => { let mut arr = Array::with_capacity(x.len()); - arr.extend(x.iter().map(|v| { - v.get_literal_value() - .expect("constant array has constant value") - })); + arr.extend( + x.iter() + .map(|v| v.get_literal_value().expect("constant value")), + ); Dynamic::from_array(arr) } @@ -2197,10 +2202,8 @@ impl Expr { Self::Map(x, _) if self.is_constant() => { let mut map = x.1.clone(); x.0.iter().for_each(|(k, v)| { - *map.get_mut(k.name.as_str()) - .expect("template contains all keys") = v - .get_literal_value() - .expect("constant map has constant value") + *map.get_mut(k.name.as_str()).expect("contains all keys") = + v.get_literal_value().expect("constant value") }); Dynamic::from_map(map) } @@ -2479,7 +2482,7 @@ impl Expr { _ => (), } - path.pop().expect("`path` contains current node"); + path.pop().expect("contains current node"); true } diff --git a/src/engine.rs b/src/engine.rs index 19f6b9ad..99845865 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -228,12 +228,8 @@ impl Imports { self.global_constants = Some(dict.into()); } - crate::fn_native::shared_write_lock( - self.global_constants - .as_mut() - .expect("`global_constants` is `Some`"), - ) - .insert(name.into(), value); + crate::fn_native::shared_write_lock(self.global_constants.as_mut().expect("`Some`")) + .insert(name.into(), value); } /// Get the pre-calculated index getter hash. #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] @@ -600,9 +596,7 @@ impl<'a> Target<'a> { )) })?; - let value = &mut *value - .write_lock::() - .expect("`BitField` holds `INT`"); + let value = &mut *value.write_lock::().expect("`INT`"); let index = *index; @@ -630,7 +624,7 @@ impl<'a> Target<'a> { let s = &mut *s .write_lock::() - .expect("`StringChar` holds `ImmutableString`"); + .expect("`ImmutableString`"); let index = *index; @@ -653,10 +647,7 @@ impl<'a> From<&'a mut Dynamic> for Target<'a> { if value.is_shared() { // Cloning is cheap for a shared value let container = value.clone(); - return Self::LockGuard(( - value.write_lock::().expect("cast to `Dynamic`"), - container, - )); + return Self::LockGuard((value.write_lock::().expect("`Dynamic`"), container)); } Self::RefMut(value) @@ -786,9 +777,7 @@ impl EvalState { // Push a new function resolution cache if the stack is empty self.push_fn_resolution_cache(); } - self.fn_resolution_caches - .last_mut() - .expect("at least one function resolution cache") + self.fn_resolution_caches.last_mut().expect("not empty") } /// Push an empty function resolution cache onto the stack and make it current. #[allow(dead_code)] @@ -803,9 +792,7 @@ impl EvalState { /// Panics if there is no more function resolution cache in the stack. #[inline(always)] pub fn pop_fn_resolution_cache(&mut self) { - self.fn_resolution_caches - .pop() - .expect("at least one function resolution cache"); + self.fn_resolution_caches.pop().expect("not empty"); } } @@ -1188,10 +1175,10 @@ impl Engine { if let Some(index) = index { let offset = mods.len() - index.get(); - Some(mods.get(offset).expect("offset within range")) + Some(mods.get(offset).expect("within range")) } else { mods.find(root) - .map(|n| mods.get(n).expect("index is valid")) + .map(|n| mods.get(n).expect("valid index")) .or_else(|| self.global_sub_modules.get(root).cloned()) } } @@ -1327,7 +1314,7 @@ impl Engine { level: 0, }; match resolve_var( - expr.get_variable_name(true).expect("`expr` is `Variable`"), + expr.get_variable_name(true).expect("`Variable`"), index, &context, ) { @@ -1344,7 +1331,7 @@ impl Engine { scope.len() - index } else { // Find the variable in the scope - let var_name = expr.get_variable_name(true).expect("`expr` is `Variable`"); + let var_name = expr.get_variable_name(true).expect("`Variable`"); scope .get_index(var_name) .ok_or_else(|| EvalAltResult::ErrorVariableNotFound(var_name.to_string(), var_pos))? @@ -1378,16 +1365,14 @@ impl Engine { let _terminate_chaining = terminate_chaining; // Pop the last index value - let idx_val = idx_values.pop().expect("index chain is never empty"); + let idx_val = idx_values.pop().expect("not empty"); match chain_type { #[cfg(not(feature = "no_index"))] ChainType::Indexing => { let pos = rhs.position(); let root_pos = idx_val.position(); - let idx_val = idx_val - .into_index_value() - .expect("`chain_type` is `ChainType::Index`"); + let idx_val = idx_val.into_index_value().expect("`ChainType::Index`"); match rhs { // xxx[idx].expr... | xxx[idx][expr]... @@ -1440,8 +1425,7 @@ impl Engine { } // xxx[rhs] op= new_val _ if new_val.is_some() => { - let ((new_val, new_pos), (op_info, op_pos)) = - new_val.expect("`new_val` is `Some`"); + let ((new_val, new_pos), (op_info, op_pos)) = new_val.expect("`Some`"); let mut idx_val_for_setter = idx_val.clone(); let try_setter = match self.get_indexed_mut( @@ -1495,7 +1479,7 @@ impl Engine { let FnCallExpr { name, hashes, .. } = x.as_ref(); let call_args = &mut idx_val .into_fn_call_args() - .expect("`chain_type` is `ChainType::Dot` with `Expr::FnCallExpr`"); + .expect("`ChainType::Dot` with `Expr::FnCallExpr`"); self.make_method_call( mods, state, lib, name, *hashes, target, call_args, *pos, level, ) @@ -1511,8 +1495,7 @@ impl Engine { // {xxx:map}.id op= ??? Expr::Property(x) if target.is::() && new_val.is_some() => { let (name, pos) = &x.2; - let ((new_val, new_pos), (op_info, op_pos)) = - new_val.expect("`new_val` is `Some`"); + let ((new_val, new_pos), (op_info, op_pos)) = new_val.expect("`Some`"); let index = name.into(); { let val_target = &mut self.get_indexed_mut( @@ -1539,8 +1522,7 @@ impl Engine { // xxx.id op= ??? Expr::Property(x) if new_val.is_some() => { let ((getter, hash_get), (setter, hash_set), (name, pos)) = x.as_ref(); - let ((mut new_val, new_pos), (op_info, op_pos)) = - new_val.expect("`new_val` is `Some`"); + let ((mut new_val, new_pos), (op_info, op_pos)) = new_val.expect("`Some`"); if op_info.is_some() { let hash = FnCallHashes::from_native(*hash_get); @@ -2281,9 +2263,7 @@ impl Engine { Expr::Map(x, _) => { let mut map = x.1.clone(); for (Ident { name: key, .. }, expr) in &x.0 { - let value_ref = map - .get_mut(key.as_str()) - .expect("template contains all keys"); + let value_ref = map.get_mut(key.as_str()).expect("contains all keys"); *value_ref = self .eval_expr(scope, mods, state, lib, this_ptr, expr, level)? .flatten(); @@ -2313,7 +2293,7 @@ impl Engine { Expr::FnCall(x, pos) => { let FnCallExpr { name, - capture, + capture_parent_scope: capture, hashes, args, constants, @@ -2356,14 +2336,8 @@ impl Engine { Expr::Custom(custom, _) => { let expressions: StaticVec<_> = custom.inputs.iter().map(Into::into).collect(); - let key_token = custom - .tokens - .first() - .expect("custom syntax stream contains at least one token"); - let custom_def = self - .custom_syntax - .get(key_token) - .expect("custom syntax leading token matches with definition"); + let key_token = custom.tokens.first().expect("not empty"); + let custom_def = self.custom_syntax.get(key_token).expect("must match"); let mut context = EvalContext { engine: self, scope, @@ -2497,7 +2471,7 @@ impl Engine { let target_is_shared = false; if target_is_shared { - lock_guard = target.write_lock::().expect("cast to `Dynamic`"); + lock_guard = target.write_lock::().expect("`Dynamic`"); lhs_ptr_inner = &mut *lock_guard; } else { lhs_ptr_inner = &mut *target; @@ -2567,9 +2541,7 @@ impl Engine { let (mut lhs_ptr, pos) = self.search_namespace(scope, mods, state, lib, this_ptr, lhs_expr)?; - let var_name = lhs_expr - .get_variable_name(false) - .expect("`lhs_ptr` is `Variable`"); + let var_name = lhs_expr.get_variable_name(false).expect("`Variable`"); if !lhs_ptr.is_ref() { return Err(EvalAltResult::ErrorAssignmentToConstant( @@ -2829,7 +2801,7 @@ impl Engine { if x > INT::MAX as usize { return Err(EvalAltResult::ErrorArithmetic( format!("for-loop counter overflow: {}", x), - counter.as_ref().expect("`counter` is `Some`").pos, + counter.as_ref().expect("`Some`").pos, ) .into()); } @@ -2837,7 +2809,7 @@ impl Engine { let mut counter_var = scope .get_mut_by_index(c) .write_lock::() - .expect("counter holds `INT`"); + .expect("`INT`"); *counter_var = x as INT; } @@ -2850,7 +2822,7 @@ impl Engine { let loop_var_is_shared = false; if loop_var_is_shared { - let mut value_ref = loop_var.write_lock().expect("cast to `Dynamic`"); + let mut value_ref = loop_var.write_lock().expect("`Dynamic`"); *value_ref = value; } else { *loop_var = value; @@ -2911,7 +2883,7 @@ impl Engine { Stmt::FnCall(x, pos) => { let FnCallExpr { name, - capture, + capture_parent_scope: capture, hashes, args, constants, @@ -2958,16 +2930,11 @@ impl Engine { if err_pos.is_none() { // No position info } else { - let line = err_pos - .line() - .expect("non-NONE `Position` has line number") - as INT; + let line = err_pos.line().expect("line number") as INT; let position = if err_pos.is_beginning_of_line() { 0 } else { - err_pos - .position() - .expect("non-NONE `Position` has character position") + err_pos.position().expect("character position") } as INT; err_map.insert("line".into(), line.into()); err_map.insert("position".into(), position.into()); diff --git a/src/engine_api.rs b/src/engine_api.rs index d9d716da..3dc9d82e 100644 --- a/src/engine_api.rs +++ b/src/engine_api.rs @@ -25,20 +25,13 @@ impl Engine { #[inline(always)] #[allow(dead_code)] pub(crate) fn global_namespace(&self) -> &Module { - self.global_modules - .first() - .expect("global_modules not empty") + self.global_modules.first().expect("not empty") } /// Get a mutable reference to the global namespace module /// (which is the first module in `global_modules`). #[inline(always)] pub(crate) fn global_namespace_mut(&mut self) -> &mut Module { - Shared::get_mut( - self.global_modules - .first_mut() - .expect("global_modules not empty"), - ) - .expect("global namespace never shared") + Shared::get_mut(self.global_modules.first_mut().expect("not empty")).expect("not shared") } /// Register a custom function with the [`Engine`]. /// @@ -957,8 +950,8 @@ impl Engine { } } else { let mut iter = name.as_ref().splitn(2, separator.as_ref()); - let sub_module = iter.next().expect("name contains separator").trim(); - let remainder = iter.next().expect("name contains separator").trim(); + let sub_module = iter.next().expect("contains separator").trim(); + let remainder = iter.next().expect("contains separator").trim(); if !root.contains_key(sub_module) { let mut m = Module::new(); @@ -966,9 +959,7 @@ impl Engine { m.build_index(); root.insert(sub_module.into(), m.into()); } else { - let m = root - .remove(sub_module) - .expect("root contains the sub-module"); + let m = root.remove(sub_module).expect("contains sub-module"); let mut m = crate::fn_native::shared_take_or_clone(m); register_static_module_raw(m.sub_modules_mut(), remainder, module); m.build_index(); @@ -1073,7 +1064,7 @@ impl Engine { imports: &mut BTreeSet, ) { ast.walk( - &mut |path| match path.last().expect("`path` contains the current node") { + &mut |path| match path.last().expect("contains current node") { // Collect all `import` statements with a string constant path ASTNode::Stmt(Stmt::Import(Expr::StringConstant(s, _), _, _)) if !resolver.contains_path(s) && !imports.contains(s.as_str()) => diff --git a/src/fn_call.rs b/src/fn_call.rs index b56a5487..fb3dc56e 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -255,7 +255,7 @@ impl Engine { }) } else { let (first_arg, rest_args) = - args.split_first().expect("has two arguments"); + args.split_first().expect("two arguments"); get_builtin_op_assignment_fn(fn_name, *first_arg, rest_args[0]) .map(|f| FnResolutionCacheEntry { @@ -273,7 +273,7 @@ impl Engine { None => { let hash_params = calc_fn_params_hash( args.as_ref() - .expect("no permutations if no arguments") + .expect("no permutations") .iter() .enumerate() .map(|(i, a)| { @@ -333,7 +333,7 @@ impl Engine { backup = Some(ArgBackup::new()); backup .as_mut() - .expect("`backup` is `Some`") + .expect("`Some`") .change_first_arg_to_copy(args); } @@ -680,10 +680,8 @@ impl Engine { crate::engine::KEYWORD_IS_DEF_FN if args.len() == 2 && args[0].is::() && args[1].is::() => { - let fn_name = args[0] - .read_lock::() - .expect("`args[0]` is `FnPtr`"); - let num_params = args[1].as_int().expect("`args[1]` is `INT`"); + let fn_name = args[0].read_lock::().expect("`FnPtr`"); + let num_params = args[1].as_int().expect("`INT`"); return Ok(( if num_params < 0 { @@ -736,7 +734,7 @@ impl Engine { let result = if _is_method_call { // Method call of script function - map first argument to `this` - let (first_arg, rest_args) = args.split_first_mut().expect("has arguments"); + let (first_arg, rest_args) = args.split_first_mut().expect("not empty"); let orig_source = mods.source.take(); mods.source = source; @@ -767,7 +765,7 @@ impl Engine { backup = Some(ArgBackup::new()); backup .as_mut() - .expect("`backup` is `Some`") + .expect("`Some`") .change_first_arg_to_copy(args); } @@ -883,7 +881,7 @@ impl Engine { let (result, updated) = match fn_name { KEYWORD_FN_PTR_CALL if target.is::() => { // FnPtr call - let fn_ptr = target.read_lock::().expect("`obj` is `FnPtr`"); + let fn_ptr = target.read_lock::().expect("`FnPtr`"); // Redirect function name let fn_name = fn_ptr.fn_name(); let args_len = call_args.len() + fn_ptr.curry().len(); @@ -948,7 +946,7 @@ impl Engine { )); } - let fn_ptr = target.read_lock::().expect("`obj` is `FnPtr`"); + let fn_ptr = target.read_lock::().expect("`FnPtr`"); // Curry call Ok(( @@ -1243,7 +1241,7 @@ impl Engine { // avoid cloning the value if curry.is_empty() && !args_expr.is_empty() && args_expr[0].is_variable_access(false) { // func(x, ...) -> x.func(...) - let (first_expr, rest_expr) = args_expr.split_first().expect("has arguments"); + let (first_expr, rest_expr) = args_expr.split_first().expect("not empty"); for index in 0..rest_expr.len() { let (value, _) = self.get_arg_value( @@ -1273,7 +1271,7 @@ impl Engine { } else { // Turn it into a method call only if the object is not shared and not a simple value is_ref_mut = true; - let obj_ref = target.take_ref().expect("`target` is reference"); + let obj_ref = target.take_ref().expect("reference"); args.push(obj_ref); args.extend(arg_values.iter_mut()); } @@ -1352,9 +1350,9 @@ impl Engine { 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 - let (first, rest) = arg_values.split_first_mut().expect("has arguments"); + let (first, rest) = arg_values.split_first_mut().expect("not empty"); first_arg_value = Some(first); - let obj_ref = target.take_ref().expect("`target` is reference"); + let obj_ref = target.take_ref().expect("reference"); args.push(obj_ref); args.extend(rest.iter_mut()); } diff --git a/src/fn_native.rs b/src/fn_native.rs index 9d8dab30..7225e5c9 100644 --- a/src/fn_native.rs +++ b/src/fn_native.rs @@ -298,9 +298,7 @@ pub fn shared_try_take(value: Shared) -> Result> { #[must_use] #[allow(dead_code)] pub fn shared_take(value: Shared) -> T { - shared_try_take(value) - .ok() - .expect("no outstanding references") + shared_try_take(value).ok().expect("not shared") } /// Lock a [`Shared`] resource. diff --git a/src/fn_register.rs b/src/fn_register.rs index 60bcbec8..8fab0805 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -34,7 +34,7 @@ pub struct Mut(T); #[must_use] pub fn by_ref(data: &mut Dynamic) -> DynamicWriteLock { // Directly cast the &mut Dynamic into DynamicWriteLock to access the underlying data. - data.write_lock::().expect("data type was checked") + data.write_lock::().expect("checked") } /// Dereference into value. @@ -44,15 +44,13 @@ pub fn by_value(data: &mut Dynamic) -> T { if TypeId::of::() == TypeId::of::<&str>() { // If T is `&str`, data must be `ImmutableString`, so map directly to it data.flatten_in_place(); - let ref_str = data.as_str_ref().expect("argument type is &str"); + let ref_str = data.as_str_ref().expect("&str"); let ref_t = unsafe { mem::transmute::<_, &T>(&ref_str) }; ref_t.clone() } else if TypeId::of::() == TypeId::of::() { // If T is `String`, data must be `ImmutableString`, so map directly to it - let value = mem::take(data) - .into_string() - .expect("data type was checked"); - unsafe_try_cast(value).expect("data type was checked") + let value = mem::take(data).into_string().expect("`ImmutableString`"); + unsafe_try_cast(value).expect("checked") } else { // We consume the argument and then replace it with () - the argument is not supposed to be used again. // This way, we avoid having to clone the argument again, because it is already a clone when passed here. @@ -99,6 +97,8 @@ fn is_setter(_fn_name: &str) -> bool { false } +const EXPECT_ARGS: &str = "arguments"; + macro_rules! def_register { () => { def_register!(imp from_pure :); @@ -128,7 +128,7 @@ macro_rules! def_register { // The arguments are assumed to be of the correct number and types! let mut _drain = args.iter_mut(); - $($let $par = ($clone)(_drain.next().expect("arguments list is fixed")); )* + $($let $par = ($clone)(_drain.next().expect(EXPECT_ARGS)); )* // Call the function with each argument value let r = self($($arg),*); @@ -156,7 +156,7 @@ macro_rules! def_register { // The arguments are assumed to be of the correct number and types! let mut _drain = args.iter_mut(); - $($let $par = ($clone)(_drain.next().expect("arguments list is fixed")); )* + $($let $par = ($clone)(_drain.next().expect(EXPECT_ARGS)); )* // Call the function with each argument value let r = self(ctx, $($arg),*); @@ -184,7 +184,7 @@ macro_rules! def_register { // The arguments are assumed to be of the correct number and types! let mut _drain = args.iter_mut(); - $($let $par = ($clone)(_drain.next().expect("arguments list is fixed")); )* + $($let $par = ($clone)(_drain.next().expect(EXPECT_ARGS)); )* // Call the function with each argument value self($($arg),*).map(Dynamic::from) @@ -209,7 +209,7 @@ macro_rules! def_register { // The arguments are assumed to be of the correct number and types! let mut _drain = args.iter_mut(); - $($let $par = ($clone)(_drain.next().expect("arguments list is fixed")); )* + $($let $par = ($clone)(_drain.next().expect(EXPECT_ARGS)); )* // Call the function with each argument value self(ctx, $($arg),*).map(Dynamic::from) diff --git a/src/module/mod.rs b/src/module/mod.rs index d0a35342..78ffba6b 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -1426,7 +1426,7 @@ impl Module { match aliases.len() { 0 => (), 1 => { - let alias = aliases.pop().expect("list has one item"); + let alias = aliases.pop().expect("not empty"); module.set_var(alias, value); } _ => aliases.into_iter().for_each(|alias| { diff --git a/src/optimize.rs b/src/optimize.rs index 32d8021b..3afd75d5 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -288,23 +288,18 @@ fn optimize_stmt_block( && !last_stmt.returns_value() => { state.set_dirty(); - statements - .pop() - .expect("`statements` contains at least two elements"); + statements.pop().expect(">= 2 elements"); } // { ...; return val; } -> { ...; val } [.., Stmt::Return(options, ref mut expr, pos)] if reduce_return && !options.contains(AST_OPTION_BREAK_OUT) => { state.set_dirty(); - *statements - .last_mut() - .expect("`statements` contains at least two elements") = - if let Some(expr) = expr { - Stmt::Expr(mem::take(expr)) - } else { - Stmt::Noop(pos) - }; + *statements.last_mut().expect(">= 2 elements") = if let Some(expr) = expr { + Stmt::Expr(mem::take(expr)) + } else { + Stmt::Noop(pos) + }; } // { ...; stmt; noop } -> done [.., ref second_last_stmt, Stmt::Noop(_)] @@ -319,14 +314,10 @@ fn optimize_stmt_block( { state.set_dirty(); if second_last_stmt.returns_value() { - *statements - .last_mut() - .expect("`statements` contains at least two elements") = + *statements.last_mut().expect(">= 2 elements") = Stmt::Noop(last_stmt.position()); } else { - statements - .pop() - .expect("`statements` contains at least two elements"); + statements.pop().expect(">= 2 elements"); } } _ => break, @@ -344,9 +335,7 @@ fn optimize_stmt_block( if reduce_return && !options.contains(AST_OPTION_BREAK_OUT) => { state.set_dirty(); - statements - .pop() - .expect("`statements` contains at least two elements"); + statements.pop().expect(">= 2 elements"); } // { ...; return pure_val; } -> { ... } [.., Stmt::Return(options, Some(ref expr), _)] @@ -355,15 +344,11 @@ fn optimize_stmt_block( && expr.is_pure() => { state.set_dirty(); - statements - .pop() - .expect("`statements` contains at least two elements"); + statements.pop().expect(">= 2 elements"); } [.., ref last_stmt] if is_pure(last_stmt) => { state.set_dirty(); - statements - .pop() - .expect("`statements` contains at least one element"); + statements.pop().expect("not empty"); } _ => break, } @@ -405,18 +390,14 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b match x.2 { Expr::FnCall(ref mut x2, _) => { state.set_dirty(); - let op = Token::lookup_from_syntax(&x2.name).expect("`x2` is operator"); - let op_assignment = op.make_op_assignment().expect("`op` is operator"); + let op = Token::lookup_from_syntax(&x2.name).expect("operator"); + let op_assignment = op.make_op_assignment().expect("operator"); x.1 = Some(OpAssignment::new(op_assignment)); let value = mem::take(&mut x2.args[1]); if let Expr::Stack(slot, pos) = value { - let value = mem::take( - x2.constants - .get_mut(slot) - .expect("`constants[slot]` is valid"), - ); + let value = mem::take(x2.constants.get_mut(slot).expect("valid slot")); x.2 = Expr::from_dynamic(value, pos); } else { x.2 = value; @@ -804,13 +785,13 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { (Expr::StringConstant(s, pos), Expr::IntegerConstant(i, _)) if *i >= 0 && (*i as usize) < s.chars().count() => { // String literal indexing - get the character state.set_dirty(); - *expr = Expr::CharConstant(s.chars().nth(*i as usize).expect("character position is valid"), *pos); + *expr = Expr::CharConstant(s.chars().nth(*i as usize).expect("valid index"), *pos); } // string[-int] (Expr::StringConstant(s, pos), Expr::IntegerConstant(i, _)) if *i < 0 && i.checked_abs().map(|n| n as usize <= s.chars().count()).unwrap_or(false) => { // String literal indexing - get the character state.set_dirty(); - *expr = Expr::CharConstant(s.chars().rev().nth(i.abs() as usize - 1).expect("character position is valid"), *pos); + *expr = Expr::CharConstant(s.chars().rev().nth(i.abs() as usize - 1).expect("valid index"), *pos); } // var[rhs] (Expr::Variable(_, _, _), rhs) => optimize_expr(rhs, state, true), @@ -960,7 +941,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { if fn_name.is::() { state.set_dirty(); let fn_ptr = FnPtr::new_unchecked( - fn_name.as_str_ref().expect("`fn_name` is `ImmutableString`").into(), + fn_name.as_str_ref().expect("`ImmutableString`").into(), StaticVec::new() ); *expr = Expr::DynamicConstant(Box::new(fn_ptr.into()), *pos); @@ -1004,7 +985,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { if let Some(result) = get_builtin_binary_op_fn(x.name.as_ref(), &arg_values[0], &arg_values[1]) .and_then(|f| { let context = (state.engine, x.name.as_ref(), state.lib).into(); - let (first, second) = arg_values.split_first_mut().expect("`arg_values` is not empty"); + let (first, second) = arg_values.split_first_mut().expect("not empty"); (f)(context, &mut [ first, &mut second[0] ]).ok() }) { state.set_dirty(); @@ -1077,7 +1058,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { // constant-name Expr::Variable(_, pos, x) if x.1.is_none() && state.find_constant(&x.2).is_some() => { // Replace constant with value - *expr = Expr::from_dynamic(state.find_constant(&x.2).expect("constant exists").clone(), *pos); + *expr = Expr::from_dynamic(state.find_constant(&x.2).expect("exists").clone(), *pos); state.set_dirty(); } diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 1fd0b94b..39665b99 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -849,16 +849,16 @@ mod array_functions { if type_id == TypeId::of::() { array.sort_by(|a, b| { - let a = a.as_int().expect("a is INT"); - let b = b.as_int().expect("b is INT"); + let a = a.as_int().expect("`INT`"); + let b = b.as_int().expect("`INT`"); a.cmp(&b) }); return Ok(()); } if type_id == TypeId::of::() { array.sort_by(|a, b| { - let a = a.as_char().expect("a is char"); - let b = b.as_char().expect("b is char"); + let a = a.as_char().expect("char"); + let b = b.as_char().expect("char"); a.cmp(&b) }); return Ok(()); @@ -866,20 +866,16 @@ mod array_functions { #[cfg(not(feature = "no_float"))] if type_id == TypeId::of::() { array.sort_by(|a, b| { - let a = a.as_float().expect("a is FLOAT"); - let b = b.as_float().expect("b is FLOAT"); + let a = a.as_float().expect("`FLOAT`"); + let b = b.as_float().expect("`FLOAT`"); a.partial_cmp(&b).unwrap_or(Ordering::Equal) }); return Ok(()); } if type_id == TypeId::of::() { array.sort_by(|a, b| { - let a = a - .read_lock::() - .expect("a is ImmutableString"); - let b = b - .read_lock::() - .expect("b is ImmutableString"); + let a = a.read_lock::().expect("`ImmutableString`"); + let b = b.read_lock::().expect("`ImmutableString`"); a.as_str().cmp(b.as_str()) }); return Ok(()); @@ -887,16 +883,16 @@ mod array_functions { #[cfg(feature = "decimal")] if type_id == TypeId::of::() { array.sort_by(|a, b| { - let a = a.as_decimal().expect("a is Decimal"); - let b = b.as_decimal().expect("b is Decimal"); + let a = a.as_decimal().expect("`Decimal`"); + let b = b.as_decimal().expect("`Decimal`"); a.cmp(&b) }); return Ok(()); } if type_id == TypeId::of::() { array.sort_by(|a, b| { - let a = a.as_bool().expect("a is bool"); - let b = b.as_bool().expect("b is bool"); + let a = a.as_bool().expect("`bool`"); + let b = b.as_bool().expect("`bool`"); a.cmp(&b) }); return Ok(()); diff --git a/src/packages/string_basic.rs b/src/packages/string_basic.rs index 1959decc..facc8360 100644 --- a/src/packages/string_basic.rs +++ b/src/packages/string_basic.rs @@ -31,9 +31,9 @@ pub fn print_with_func( value: &mut Dynamic, ) -> crate::ImmutableString { match ctx.call_fn_raw(fn_name, true, false, &mut [value]) { - Ok(result) if result.is::() => result - .into_immutable_string() - .expect("result is `ImmutableString`"), + Ok(result) if result.is::() => { + result.into_immutable_string().expect("`ImmutableString`") + } Ok(result) => ctx.engine().map_type_name(result.type_name()).into(), Err(_) => ctx.engine().map_type_name(value.type_name()).into(), } diff --git a/src/packages/string_more.rs b/src/packages/string_more.rs index 67e9ff4f..59aae414 100644 --- a/src/packages/string_more.rs +++ b/src/packages/string_more.rs @@ -175,7 +175,7 @@ mod string_functions { #[rhai_fn(name = "to_upper")] pub fn to_upper_char(character: char) -> char { let mut stream = character.to_uppercase(); - let ch = stream.next().expect("at least one character"); + let ch = stream.next().expect("not empty"); if stream.next().is_some() { character } else { @@ -189,9 +189,7 @@ mod string_functions { #[rhai_fn(name = "to_lower")] pub fn to_lower_char(character: char) -> char { let mut stream = character.to_lowercase(); - let ch = stream - .next() - .expect("there should be at least one character"); + let ch = stream.next().expect("not empty"); if stream.next().is_some() { character } else { diff --git a/src/parse.rs b/src/parse.rs index 4ea4d317..7258f2f3 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -456,7 +456,7 @@ fn parse_fn_call( state: &mut ParseState, lib: &mut FunctionsLib, id: Identifier, - capture: bool, + capture_parent_scope: bool, namespace: Option, settings: ParseSettings, ) -> Result { @@ -503,7 +503,7 @@ fn parse_fn_call( return Ok(FnCallExpr { name: state.get_identifier(id), - capture, + capture_parent_scope, namespace, hashes, args, @@ -553,7 +553,7 @@ fn parse_fn_call( return Ok(FnCallExpr { name: state.get_identifier(id), - capture, + capture_parent_scope, namespace, hashes, args, @@ -1727,9 +1727,7 @@ fn make_dot_expr( } // lhs.module::id - syntax error (_, Expr::Variable(_, _, x)) => { - return Err( - PERR::PropertyExpected.into_err(x.1.expect("the namespace is `Some`").0[0].pos) - ) + return Err(PERR::PropertyExpected.into_err(x.1.expect("`Some`").0[0].pos)) } // lhs.prop (lhs, prop @ Expr::Property(_)) => { @@ -1801,7 +1799,7 @@ fn make_dot_expr( .into_err(pos)) } // lhs.func!(...) - (_, Expr::FnCall(x, pos)) if x.capture => { + (_, Expr::FnCall(x, pos)) if x.capture_parent_scope => { return Err(PERR::MalformedCapture( "method-call style does not support capturing".into(), ) @@ -1901,7 +1899,6 @@ fn parse_binary_op( let op_base = FnCallExpr { name: state.get_identifier(op.as_ref()), hashes: FnCallHashes::from_native(hash), - capture: false, ..Default::default() }; @@ -1934,8 +1931,8 @@ fn parse_binary_op( | Token::GreaterThanEqualsTo => FnCallExpr { args, ..op_base }.into_fn_call_expr(pos), Token::Or => { - let rhs = args.pop().expect("`||` has two arguments"); - let current_lhs = args.pop().expect("`||` has two arguments"); + let rhs = args.pop().expect("two arguments"); + let current_lhs = args.pop().expect("two arguments"); Expr::Or( BinaryExpr { lhs: current_lhs.ensure_bool_expr()?, @@ -1946,8 +1943,8 @@ fn parse_binary_op( ) } Token::And => { - let rhs = args.pop().expect("`&&` has two arguments"); - let current_lhs = args.pop().expect("`&&` has two arguments"); + let rhs = args.pop().expect("two arguments"); + let current_lhs = args.pop().expect("two arguments"); Expr::And( BinaryExpr { lhs: current_lhs.ensure_bool_expr()?, @@ -2423,7 +2420,7 @@ fn parse_for( }, counter_var.map(|name| Ident { name, - pos: counter_pos.expect("`counter_var` is `Some`"), + pos: counter_pos.expect("`Some`"), }), body.into(), )), @@ -2980,10 +2977,7 @@ fn parse_try_catch( if err_var.is_some() { // Remove the error variable from the stack - state - .stack - .pop() - .expect("stack contains at least one entry"); + state.stack.pop().expect("not empty"); } Ok(Stmt::TryCatch( diff --git a/src/scope.rs b/src/scope.rs index 2a03bb8e..408922fa 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -405,7 +405,7 @@ impl<'a> Scope<'a> { self.push(name, value); } Some((index, AccessMode::ReadWrite)) => { - let value_ref = self.values.get_mut(index).expect("index is valid"); + let value_ref = self.values.get_mut(index).expect("valid index"); *value_ref = Dynamic::from(value); } } @@ -445,7 +445,7 @@ impl<'a> Scope<'a> { } Some((_, AccessMode::ReadOnly)) => panic!("variable {} is constant", name.as_ref()), Some((index, AccessMode::ReadWrite)) => { - let value_ref = self.values.get_mut(index).expect("index is valid"); + let value_ref = self.values.get_mut(index).expect("valid index"); *value_ref = Dynamic::from(value); } } @@ -491,7 +491,7 @@ impl<'a> Scope<'a> { #[inline] #[must_use] pub(crate) fn get_mut_by_index(&mut self, index: usize) -> &mut Dynamic { - self.values.get_mut(index).expect("index is out of bounds") + self.values.get_mut(index).expect("valid index") } /// Update the access type of an entry in the [`Scope`]. /// @@ -501,7 +501,7 @@ impl<'a> Scope<'a> { #[cfg(not(feature = "no_module"))] #[inline] pub(crate) fn add_entry_alias(&mut self, index: usize, alias: Identifier) -> &mut Self { - let (_, aliases) = self.names.get_mut(index).expect("index is out of bounds"); + let (_, aliases) = self.names.get_mut(index).expect("valid index"); match aliases { None => { let mut list = StaticVec::new(); diff --git a/src/serde/de.rs b/src/serde/de.rs index e038c260..fc255f02 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -568,7 +568,7 @@ where ) -> Result> { // Deserialize each value item coming out of the iterator. seed.deserialize(&mut DynamicDeserializer::from_dynamic( - self.values.next().expect("value should exist"), + self.values.next().expect("exists"), )) } } diff --git a/src/serde/metadata.rs b/src/serde/metadata.rs index 2c37f2d3..ee3e4b9e 100644 --- a/src/serde/metadata.rs +++ b/src/serde/metadata.rs @@ -53,27 +53,21 @@ struct FnParam { impl PartialOrd for FnParam { fn partial_cmp(&self, other: &Self) -> Option { - Some( - match self - .name - .partial_cmp(&other.name) - .expect("String::partial_cmp should succeed") - { - Ordering::Less => Ordering::Less, - Ordering::Greater => Ordering::Greater, - Ordering::Equal => match (self.typ.is_none(), other.typ.is_none()) { - (true, true) => Ordering::Equal, - (true, false) => Ordering::Greater, - (false, true) => Ordering::Less, - (false, false) => self - .typ - .as_ref() - .expect("`typ` is not `None`") - .partial_cmp(other.typ.as_ref().expect("`typ` is not `None`")) - .expect("String::partial_cmp should succeed"), - }, + Some(match self.name.partial_cmp(&other.name).expect("succeed") { + Ordering::Less => Ordering::Less, + Ordering::Greater => Ordering::Greater, + Ordering::Equal => match (self.typ.is_none(), other.typ.is_none()) { + (true, true) => Ordering::Equal, + (true, false) => Ordering::Greater, + (false, true) => Ordering::Less, + (false, false) => self + .typ + .as_ref() + .expect("`Some`") + .partial_cmp(other.typ.as_ref().expect("`Some`")) + .expect("succeed"), }, - ) + }) } } diff --git a/src/token.rs b/src/token.rs index 122dd792..13144243 100644 --- a/src/token.rs +++ b/src/token.rs @@ -1223,9 +1223,7 @@ pub fn parse_string_literal( #[cfg(not(feature = "no_position"))] { - let start_position = start - .position() - .expect("string must have starting position"); + let start_position = start.position().expect("start position"); skip_whitespace_until = start_position + 1; } } @@ -1247,8 +1245,7 @@ pub fn parse_string_literal( // Whitespace to skip #[cfg(not(feature = "no_position"))] _ if next_char.is_whitespace() - && pos.position().expect("character must have position") - < skip_whitespace_until => {} + && pos.position().expect("position") < skip_whitespace_until => {} // All other characters _ => { @@ -1395,14 +1392,10 @@ fn get_next_token_inner( #[cfg(not(feature = "no_function"))] #[cfg(feature = "metadata")] - let return_comment = - return_comment || is_doc_comment(comment.as_ref().expect("`include_comments` is true")); + let return_comment = return_comment || is_doc_comment(comment.as_ref().expect("`Some`")); if return_comment { - return Some(( - Token::Comment(comment.expect("`return_comment` is true").into()), - start_pos, - )); + return Some((Token::Comment(comment.expect("`Some`").into()), start_pos)); } if state.comment_level > 0 { // Reached EOF without ending comment block @@ -1452,7 +1445,7 @@ fn get_next_token_inner( } #[cfg(any(not(feature = "no_float"), feature = "decimal"))] '.' => { - stream.get_next().expect("it is `.`"); + stream.get_next().expect("`.`"); // Check if followed by digits or something that cannot start a property name match stream.peek_next().unwrap_or('\0') { @@ -1486,7 +1479,7 @@ fn get_next_token_inner( } #[cfg(not(feature = "no_float"))] 'e' => { - stream.get_next().expect("it is `e`"); + stream.get_next().expect("`e`"); // Check if followed by digits or +/- match stream.peek_next().unwrap_or('\0') { @@ -1499,7 +1492,7 @@ fn get_next_token_inner( '+' | '-' => { result.push(next_char); pos.advance(); - result.push(stream.get_next().expect("it is `+` or `-`")); + result.push(stream.get_next().expect("`+` or `-`")); pos.advance(); } // Not a floating-point number @@ -1647,7 +1640,7 @@ fn get_next_token_inner( |(err, err_pos)| (Token::LexError(err), err_pos), |(result, _)| { let mut chars = result.chars(); - let first = chars.next().expect("`chars` is not empty"); + let first = chars.next().expect("not empty"); if chars.next().is_some() { (