From 747c0345f2ccff00a41bbcea3488b2689f11941d Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sun, 2 Aug 2020 13:51:07 +0800 Subject: [PATCH] Do not convert a function call into a method call if the object is shared. --- src/any.rs | 2 +- src/fn_call.rs | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/any.rs b/src/any.rs index e0281efe..08ebdeab 100644 --- a/src/any.rs +++ b/src/any.rs @@ -258,7 +258,7 @@ impl Dynamic { } /// Does this `Dynamic` hold a shared data type - /// instead of one of the support system primitive types? + /// instead of one of the supported system primitive types? pub fn is_shared(&self) -> bool { match self.0 { #[cfg(not(feature = "no_shared"))] diff --git a/src/fn_call.rs b/src/fn_call.rs index 2b4ffb65..6980caca 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -906,11 +906,11 @@ impl Engine { // No arguments args = Default::default(); } else { - // See if the first argument is a variable, if so, convert to method-call style + // If the first argument is a variable, and there is no curried arguments, convert to method-call style // in order to leverage potential &mut first argument and avoid cloning the value match args_expr.get(0).unwrap() { // func(x, ...) -> x.func(...) - lhs @ Expr::Variable(_) => { + lhs @ Expr::Variable(_) if curry.is_empty() => { arg_values = args_expr .iter() .skip(1) @@ -922,12 +922,14 @@ impl Engine { self.inc_operations(state) .map_err(|err| err.new_position(pos))?; - args = once(target) - .chain(curry.iter_mut()) - .chain(arg_values.iter_mut()) - .collect(); - - is_ref = true; + // Turn it into a method call only if the object is not shared + args = if target.is_shared() { + arg_values.insert(0, target.clone_inner_data().unwrap()); + arg_values.iter_mut().collect() + } else { + is_ref = true; + once(target).chain(arg_values.iter_mut()).collect() + }; } // func(..., ...) _ => {