diff --git a/src/ast/ast.rs b/src/ast/ast.rs index f6ebb50c..eb606d3f 100644 --- a/src/ast/ast.rs +++ b/src/ast/ast.rs @@ -69,7 +69,7 @@ impl fmt::Debug for AST { impl AST { /// Create a new [`AST`]. #[cfg(not(feature = "internals"))] - #[inline(always)] + #[inline] #[must_use] pub(crate) fn new( statements: impl IntoIterator, @@ -89,7 +89,7 @@ impl AST { /// _(internals)_ Create a new [`AST`]. /// Exported under the `internals` feature only. #[cfg(feature = "internals")] - #[inline(always)] + #[inline] #[must_use] pub fn new( statements: impl IntoIterator, @@ -108,7 +108,7 @@ impl AST { } /// Create a new [`AST`] with a source name. #[cfg(not(feature = "internals"))] - #[inline(always)] + #[inline] #[must_use] pub(crate) fn new_with_source( statements: impl IntoIterator, @@ -126,7 +126,7 @@ impl AST { /// _(internals)_ Create a new [`AST`] with a source name. /// Exported under the `internals` feature only. #[cfg(feature = "internals")] - #[inline(always)] + #[inline] #[must_use] pub fn new_with_source( statements: impl IntoIterator, @@ -157,7 +157,7 @@ impl AST { } } /// Get the source, if any. - #[inline(always)] + #[inline] #[must_use] pub fn source(&self) -> Option<&str> { if self.source.is_empty() { @@ -664,7 +664,6 @@ impl AST { self.combine_filtered_impl(other, filter) } /// Combine one [`AST`] with another. The second [`AST`] is consumed. - #[inline] fn combine_filtered_impl( &mut self, other: Self, @@ -957,19 +956,21 @@ pub enum ASTNode<'a> { } impl<'a> From<&'a Stmt> for ASTNode<'a> { + #[inline(always)] fn from(stmt: &'a Stmt) -> Self { Self::Stmt(stmt) } } impl<'a> From<&'a Expr> for ASTNode<'a> { + #[inline(always)] fn from(expr: &'a Expr) -> Self { Self::Expr(expr) } } impl PartialEq for ASTNode<'_> { - #[inline(always)] + #[inline] fn eq(&self, other: &Self) -> bool { match (self, other) { (Self::Stmt(x), Self::Stmt(y)) => ptr::eq(*x, *y), @@ -986,8 +987,8 @@ impl ASTNode<'_> { #[must_use] pub fn position(&self) -> Position { match self { - ASTNode::Stmt(stmt) => stmt.position(), - ASTNode::Expr(expr) => expr.position(), + Self::Stmt(stmt) => stmt.position(), + Self::Expr(expr) => expr.position(), } } } diff --git a/src/ast/expr.rs b/src/ast/expr.rs index 037079e8..b7f4a836 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -134,7 +134,7 @@ impl fmt::Debug for FnCallHashes { } impl From for FnCallHashes { - #[inline(always)] + #[inline] fn from(hash: u64) -> Self { let hash = if hash == 0 { ALT_ZERO_HASH } else { hash }; @@ -148,7 +148,7 @@ impl From for FnCallHashes { impl FnCallHashes { /// Create a [`FnCallHashes`] with only the native Rust hash. - #[inline(always)] + #[inline] #[must_use] pub const fn from_native(hash: u64) -> Self { Self { @@ -158,7 +158,7 @@ impl FnCallHashes { } } /// Create a [`FnCallHashes`] with both native Rust and script function hashes. - #[inline(always)] + #[inline] #[must_use] pub const fn from_all(#[cfg(not(feature = "no_function"))] script: u64, native: u64) -> Self { Self { @@ -252,7 +252,7 @@ pub struct FloatWrapper(F); #[cfg(not(feature = "no_float"))] impl Hash for FloatWrapper { - #[inline(always)] + #[inline] fn hash(&self, state: &mut H) { self.0.to_ne_bytes().hash(state); } diff --git a/src/ast/flags.rs b/src/ast/flags.rs index 452a57e6..e26fb55c 100644 --- a/src/ast/flags.rs +++ b/src/ast/flags.rs @@ -18,7 +18,7 @@ pub enum FnAccess { impl FnAccess { /// Is this function private? - #[inline(always)] + #[inline] #[must_use] pub const fn is_private(self) -> bool { match self { @@ -27,7 +27,7 @@ impl FnAccess { } } /// Is this function public? - #[inline(always)] + #[inline] #[must_use] pub const fn is_public(self) -> bool { match self { diff --git a/src/ast/namespace.rs b/src/ast/namespace.rs index ee36d3bd..88ac8600 100644 --- a/src/ast/namespace.rs +++ b/src/ast/namespace.rs @@ -87,7 +87,7 @@ impl DerefMut for Namespace { } impl From> for Namespace { - #[inline(always)] + #[inline] fn from(mut path: Vec) -> Self { path.shrink_to_fit(); Self { @@ -98,7 +98,7 @@ impl From> for Namespace { } impl From> for Namespace { - #[inline(always)] + #[inline] fn from(mut path: StaticVec) -> Self { path.shrink_to_fit(); Self { index: None, path } diff --git a/src/eval/chaining.rs b/src/eval/chaining.rs index abdd0573..2b9d6425 100644 --- a/src/eval/chaining.rs +++ b/src/eval/chaining.rs @@ -50,7 +50,7 @@ impl Engine { idx_values: &mut FnArgsVec, chain_type: ChainType, level: usize, - new_val: Option<(Dynamic, &OpAssignment)>, + new_val: &mut Option<(Dynamic, &OpAssignment)>, ) -> RhaiResultOf<(Dynamic, bool)> { let is_ref_mut = target.is_ref(); @@ -75,7 +75,7 @@ impl Engine { #[cfg(feature = "debugging")] self.run_debugger(scope, global, lib, this_ptr, _parent, level)?; - let idx_val = idx_values.pop().unwrap(); + let idx_val = &mut idx_values.pop().unwrap(); let mut idx_val_for_setter = idx_val.clone(); let idx_pos = x.lhs.start_position(); let rhs_chain = rhs.into(); @@ -119,12 +119,12 @@ impl Engine { #[cfg(feature = "debugging")] self.run_debugger(scope, global, lib, this_ptr, _parent, level)?; - let (new_val, op_info) = new_val.expect("`Some`"); - let idx_val = idx_values.pop().unwrap(); - let mut idx_val2 = idx_val.clone(); + let (new_val, op_info) = new_val.take().expect("`Some`"); + let idx_val = &mut idx_values.pop().unwrap(); + let idx = &mut idx_val.clone(); let try_setter = match self.get_indexed_mut( - global, caches, lib, target, idx_val, pos, true, false, level, + global, caches, lib, target, idx, pos, true, false, level, ) { // Indexed value is not a temp value - update directly Ok(ref mut obj_ptr) => { @@ -143,11 +143,10 @@ impl Engine { }; if let Some(mut new_val) = try_setter { - let idx = &mut idx_val2; - // Is this an op-assignment? if op_info.is_op_assignment() { - let idx = &mut idx.clone(); + let idx = &mut idx_val.clone(); + // Call the index getter to get the current value if let Ok(val) = self.call_indexer_get(global, caches, lib, target, idx, level) @@ -167,8 +166,9 @@ impl Engine { // Try to call index setter let new_val = &mut new_val; + self.call_indexer_set( - global, caches, lib, target, idx, new_val, is_ref_mut, level, + global, caches, lib, target, idx_val, new_val, is_ref_mut, level, )?; } @@ -179,7 +179,7 @@ impl Engine { #[cfg(feature = "debugging")] self.run_debugger(scope, global, lib, this_ptr, _parent, level)?; - let idx_val = idx_values.pop().unwrap(); + let idx_val = &mut idx_values.pop().unwrap(); self.get_indexed_mut( global, caches, lib, target, idx_val, pos, false, true, level, @@ -236,8 +236,8 @@ impl Engine { #[cfg(feature = "debugging")] self.run_debugger(scope, global, lib, this_ptr, rhs, level)?; - let index = x.2.clone().into(); - let (new_val, op_info) = new_val.expect("`Some`"); + let index = &mut x.2.clone().into(); + let (new_val, op_info) = new_val.take().expect("`Some`"); { let val_target = &mut self.get_indexed_mut( global, caches, lib, target, index, *pos, true, false, level, @@ -255,7 +255,7 @@ impl Engine { #[cfg(feature = "debugging")] self.run_debugger(scope, global, lib, this_ptr, rhs, level)?; - let index = x.2.clone().into(); + let index = &mut x.2.clone().into(); let val = self.get_indexed_mut( global, caches, lib, target, index, *pos, false, false, level, )?; @@ -267,7 +267,7 @@ impl Engine { self.run_debugger(scope, global, lib, this_ptr, rhs, level)?; let ((getter, hash_get), (setter, hash_set), name) = &**x; - let (mut new_val, op_info) = new_val.expect("`Some`"); + let (mut new_val, op_info) = new_val.take().expect("`Some`"); if op_info.is_op_assignment() { let args = &mut [target.as_mut()]; @@ -368,7 +368,7 @@ impl Engine { #[cfg(feature = "debugging")] self.run_debugger(scope, global, lib, this_ptr, _node, level)?; - let index = p.2.clone().into(); + let index = &mut p.2.clone().into(); self.get_indexed_mut( global, caches, lib, target, index, pos, false, true, level, )? @@ -558,7 +558,7 @@ impl Engine { this_ptr: &mut Option<&mut Dynamic>, expr: &Expr, level: usize, - new_val: Option<(Dynamic, &OpAssignment)>, + new_val: &mut Option<(Dynamic, &OpAssignment)>, ) -> RhaiResult { let chain_type = ChainType::from(expr); let (crate::ast::BinaryExpr { lhs, rhs }, options, op_pos) = match expr { @@ -595,7 +595,7 @@ impl Engine { // All other patterns - evaluate the arguments chain _ => { self.eval_dot_index_chain_arguments( - scope, global, caches, lib, this_ptr, rhs, options, chain_type, idx_values, 0, + scope, global, caches, lib, this_ptr, rhs, options, chain_type, idx_values, level, )?; } @@ -653,7 +653,6 @@ impl Engine { parent_options: ASTFlags, _parent_chain_type: ChainType, idx_values: &mut FnArgsVec, - size: usize, level: usize, ) -> RhaiResultOf<()> { #[cfg(not(feature = "unchecked"))] @@ -731,7 +730,7 @@ impl Engine { self.eval_dot_index_chain_arguments( scope, global, caches, lib, this_ptr, rhs, *options, chain_type, idx_values, - size, level, + level, )?; if !_arg_values.is_empty() { @@ -809,7 +808,7 @@ impl Engine { caches: &mut Caches, lib: &[&Module], target: &'t mut Dynamic, - mut idx: Dynamic, + idx: &mut Dynamic, idx_pos: Position, _add_if_not_found: bool, use_indexers: bool, @@ -1018,7 +1017,7 @@ impl Engine { } _ if use_indexers => self - .call_indexer_get(global, caches, lib, target, &mut idx, level) + .call_indexer_get(global, caches, lib, target, idx, level) .map(Into::into), _ => Err(ERR::ErrorIndexingType( diff --git a/src/eval/expr.rs b/src/eval/expr.rs index cdbeb95e..c965ddda 100644 --- a/src/eval/expr.rs +++ b/src/eval/expr.rs @@ -561,14 +561,12 @@ impl Engine { } #[cfg(not(feature = "no_index"))] - Expr::Index(..) => { - self.eval_dot_index_chain(scope, global, caches, lib, this_ptr, expr, level, None) - } + Expr::Index(..) => self + .eval_dot_index_chain(scope, global, caches, lib, this_ptr, expr, level, &mut None), #[cfg(not(feature = "no_object"))] - Expr::Dot(..) => { - self.eval_dot_index_chain(scope, global, caches, lib, this_ptr, expr, level, None) - } + Expr::Dot(..) => self + .eval_dot_index_chain(scope, global, caches, lib, this_ptr, expr, level, &mut None), _ => unreachable!("expression cannot be evaluated: {:?}", expr), }; diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 58f7ce47..5fa46785 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -187,15 +187,6 @@ impl Engine { *target.write_lock::().unwrap() = new_val; } - /* - if let Some(mut guard) = target.write_lock::() { - if guard.is::() { - let s = std::mem::take(&mut *guard).cast::(); - *guard = self.get_interned_string(s).into(); - } - } - */ - target.propagate_changed_value(op_info.pos) } @@ -295,19 +286,25 @@ impl Engine { } else { let (op_info, BinaryExpr { lhs, rhs }) = &**x; - let rhs_result = self - .eval_expr(scope, global, caches, lib, this_ptr, rhs, level) - .map(Dynamic::flatten); + let rhs_result = self.eval_expr(scope, global, caches, lib, this_ptr, rhs, level); if let Ok(rhs_val) = rhs_result { - let rhs_val = if rhs_val.is::() { - self.get_interned_string(rhs_val.cast::()) - .into() + // Check if the result is a string. If so, intern it. + #[cfg(not(feature = "no_closure"))] + let is_string = !rhs_val.is_shared() && rhs_val.is::(); + #[cfg(feature = "no_closure")] + let is_string = rhs_val.is::(); + + let rhs_val = if is_string { + self.get_interned_string( + rhs_val.into_immutable_string().expect("`ImmutableString`"), + ) + .into() } else { - rhs_val + rhs_val.flatten() }; - let _new_val = Some((rhs_val, op_info)); + let _new_val = &mut Some((rhs_val, op_info)); // Must be either `var[index] op= val` or `var.prop op= val` match lhs { @@ -317,20 +314,17 @@ impl Engine { } // idx_lhs[idx_expr] op= rhs #[cfg(not(feature = "no_index"))] - Expr::Index(..) => self - .eval_dot_index_chain( - scope, global, caches, lib, this_ptr, lhs, level, _new_val, - ) - .map(|_| Dynamic::UNIT), + Expr::Index(..) => self.eval_dot_index_chain( + scope, global, caches, lib, this_ptr, lhs, level, _new_val, + ), // dot_lhs.dot_rhs op= rhs #[cfg(not(feature = "no_object"))] - Expr::Dot(..) => self - .eval_dot_index_chain( - scope, global, caches, lib, this_ptr, lhs, level, _new_val, - ) - .map(|_| Dynamic::UNIT), + Expr::Dot(..) => self.eval_dot_index_chain( + scope, global, caches, lib, this_ptr, lhs, level, _new_val, + ), _ => unreachable!("cannot assign to expression: {:?}", lhs), } + .map(|_| Dynamic::UNIT) } else { rhs_result }