From f49ce33a8843c5938a1f499a8f8648ea3c074f41 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 21 Apr 2023 10:20:19 +0800 Subject: [PATCH] Use .take instead of mem::take(). --- CHANGELOG.md | 1 + src/api/register.rs | 2 +- src/ast/expr.rs | 6 ++++ src/ast/stmt.rs | 5 +++ src/eval/stmt.rs | 2 +- src/func/builtin.rs | 6 ++-- src/func/call.rs | 2 +- src/func/register.rs | 4 +-- src/func/script.rs | 2 +- src/module/mod.rs | 4 +-- src/optimizer.rs | 84 +++++++++++++++++++++----------------------- src/types/dynamic.rs | 5 +++ tests/call_fn.rs | 2 +- tests/closures.rs | 4 +-- 14 files changed, 72 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0941dd2..43b98e50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ New features * It is now possible to require a specific _type_ to the `this` pointer for a particular script-defined function so that it is called only when the `this` pointer contains the specified type. * `is_def_fn` is extended to support checking for typed methods, with syntax `is_def_fn(this_type, fn_name, arity)` +* `Dynamic::take` is added as a short-cut for `std::mem::take(&mut value)`. Enhancements ------------ diff --git a/src/api/register.rs b/src/api/register.rs index 285f959a..ab64ef37 100644 --- a/src/api/register.rs +++ b/src/api/register.rs @@ -124,7 +124,7 @@ impl Engine { /// /// To access a primary argument value (i.e. cloning is cheap), use: `args[n].as_xxx().unwrap()` /// - /// To access an argument value and avoid cloning, use `std::mem::take(args[n]).cast::()`. + /// To access an argument value and avoid cloning, use `args[n].take().cast::()`. /// Notice that this will _consume_ the argument, replacing it with `()`. /// /// To access the first mutable parameter, use `args.get_mut(0).unwrap()` diff --git a/src/ast/expr.rs b/src/ast/expr.rs index 52d7ccd1..e9ea368e 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -16,6 +16,7 @@ use std::{ fmt::Write, hash::Hash, iter::once, + mem, num::{NonZeroU8, NonZeroUsize}, }; @@ -833,6 +834,11 @@ impl Expr { Self::Property(..) => matches!(token, Token::LeftParen), } } + /// Return this [`Expr`], replacing it with [`Expr::Unit`]. + #[inline(always)] + pub fn take(&mut self) -> Self { + mem::take(self) + } /// Recursively walk this expression. /// Return `false` from the callback to terminate the walk. pub fn walk<'a>( diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index 79db87b2..75cdebff 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -1036,6 +1036,11 @@ impl Stmt { pub const fn is_control_flow_break(&self) -> bool { matches!(self, Self::Return(..) | Self::BreakLoop(..)) } + /// Return this [`Stmt`], replacing it with [`Stmt::Noop`]. + #[inline(always)] + pub fn take(&mut self) -> Self { + mem::take(self) + } /// Recursively walk this statement. /// Return `false` from the callback to terminate the walk. pub fn walk<'a>( diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 9c88f1cf..a58cbbc3 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -939,7 +939,7 @@ impl Engine { if !val.is_shared() { // Replace the variable with a shared value. - *val = std::mem::take(val).into_shared(); + *val = val.take().into_shared(); } } diff --git a/src/func/builtin.rs b/src/func/builtin.rs index 50f757f5..ca78d79a 100644 --- a/src/func/builtin.rs +++ b/src/func/builtin.rs @@ -748,7 +748,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt return match op { PlusAssign => Some(( |_ctx, args| { - let x = std::mem::take(args[1]).into_array().unwrap(); + let x = args[1].take().into_array().unwrap(); if x.is_empty() { return Ok(Dynamic::UNIT); @@ -783,7 +783,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt return match op { PlusAssign => Some(( |_ctx, args| { - let blob2 = std::mem::take(args[1]).into_blob().unwrap(); + let blob2 = args[1].take().into_blob().unwrap(); let blob1 = &mut *args[0].write_lock::().unwrap(); #[cfg(not(feature = "unchecked"))] @@ -931,7 +931,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt PlusAssign => Some(( |_ctx, args| { { - let x = std::mem::take(args[1]); + let x = args[1].take(); let array = &mut *args[0].write_lock::().unwrap(); push(array, x); } diff --git a/src/func/call.rs b/src/func/call.rs index 2cd36208..cfdaad14 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -831,7 +831,7 @@ impl Engine { } // FnPtr call on object - let fn_ptr = mem::take(&mut call_args[0]).cast::(); + let fn_ptr = call_args[0].take().cast::(); #[cfg(not(feature = "no_function"))] let (fn_name, is_anon, fn_curry, _environ, fn_def) = { diff --git a/src/func/register.rs b/src/func/register.rs index ea9ef6d5..5e410dd7 100644 --- a/src/func/register.rs +++ b/src/func/register.rs @@ -57,12 +57,12 @@ pub fn by_value(data: &mut Dynamic) -> T { } if TypeId::of::() == TypeId::of::() { // If T is `String`, data must be `ImmutableString`, so map directly to it - return reify! { mem::take(data).into_string().expect("`ImmutableString`") => T }; + return reify! { data.take().into_string().expect("`ImmutableString`") => T }; } // 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. - mem::take(data).cast::() + data.take().cast::() } /// Trait to register custom Rust functions. diff --git a/src/func/script.rs b/src/func/script.rs index 98551fe5..4040316f 100644 --- a/src/func/script.rs +++ b/src/func/script.rs @@ -67,7 +67,7 @@ impl Engine { // Put arguments into scope as variables scope.extend(fn_def.params.iter().cloned().zip(args.iter_mut().map(|v| { // Actually consume the arguments instead of cloning them - mem::take(*v) + v.take() }))); // Push a new call stack frame diff --git a/src/module/mod.rs b/src/module/mod.rs index 059028e2..d00cf0b2 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -1204,7 +1204,7 @@ impl Module { /// /// To access a primary argument value (i.e. cloning is cheap), use: `args[n].as_xxx().unwrap()` /// - /// To access an argument value and avoid cloning, use `std::mem::take(args[n]).cast::()`. + /// To access an argument value and avoid cloning, use `args[n].take().cast::()`. /// Notice that this will _consume_ the argument, replacing it with `()`. /// /// To access the first mutable argument, use `args.get_mut(0).unwrap()` @@ -1227,7 +1227,7 @@ impl Module { /// // 'args' is guaranteed to be the right length and of the correct types /// /// // Get the second parameter by 'consuming' it - /// let double = std::mem::take(args[1]).cast::(); + /// let double = args[1].take().cast::(); /// // Since it is a primary type, it can also be cheaply copied /// let double = args[1].clone_cast::(); /// // Get a mutable reference to the first argument. diff --git a/src/optimizer.rs b/src/optimizer.rs index 5300fd0c..b9546eb2 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -184,7 +184,7 @@ fn optimize_stmt_block( |s| matches!(s, Stmt::Block(block, ..) if !block.iter().any(Stmt::is_block_dependent)), ) { let (first, second) = statements.split_at_mut(n); - let stmt = mem::take(&mut second[0]); + let stmt = second[0].take(); let mut stmts = match stmt { Stmt::Block(block, ..) => block, stmt => unreachable!("Stmt::Block expected but gets {:?}", stmt), @@ -406,7 +406,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b Expr::FnCall(ref mut x2, pos) => { state.set_dirty(); x.0 = OpAssignment::new_op_assignment_from_base(&x2.name, pos); - x.1.rhs = mem::take(&mut x2.args[1]); + x.1.rhs = x2.args[1].take(); } ref expr => unreachable!("Expr::FnCall expected but gets {:?}", expr), } @@ -426,7 +426,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b state.set_dirty(); let pos = condition.start_position(); - let mut expr = mem::take(condition); + let mut expr = condition.take(); optimize_expr(&mut expr, state, false); *stmt = if preserve_result { @@ -456,7 +456,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b // if false { if_block } else { else_block } -> else_block Stmt::If(x, ..) if matches!(x.expr, Expr::BoolConstant(false, ..)) => { state.set_dirty(); - let body = mem::take(&mut *x.branch); + let body = x.branch.take_statements(); *stmt = match optimize_stmt_block(body, state, preserve_result, true, false) { statements if statements.is_empty() => Stmt::Noop(x.branch.position()), statements => (statements, x.branch.span()).into(), @@ -465,7 +465,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b // if true { if_block } else { else_block } -> if_block Stmt::If(x, ..) if matches!(x.expr, Expr::BoolConstant(true, ..)) => { state.set_dirty(); - let body = mem::take(&mut *x.body); + let body = x.body.take_statements(); *stmt = match optimize_stmt_block(body, state, preserve_result, true, false) { statements if statements.is_empty() => Stmt::Noop(x.body.position()), statements => (statements, x.body.span()).into(), @@ -475,9 +475,9 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b Stmt::If(x, ..) => { let FlowControl { expr, body, branch } = &mut **x; optimize_expr(expr, state, false); - let statements = mem::take(&mut **body); + let statements = body.take_statements(); **body = optimize_stmt_block(statements, state, preserve_result, true, false); - let statements = mem::take(&mut **branch); + let statements = branch.take_statements(); **branch = optimize_stmt_block(statements, state, preserve_result, true, false); } @@ -508,7 +508,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b if b.is_always_true() { // Promote the matched case - let mut statements = Stmt::Expr(mem::take(&mut b.expr).into()); + let mut statements = Stmt::Expr(b.expr.take().into()); optimize_stmt(&mut statements, state, true); *stmt = statements; } else { @@ -518,14 +518,14 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b let branch = match def_case { Some(index) => { let mut def_stmt = - Stmt::Expr(mem::take(&mut expressions[*index].expr).into()); + Stmt::Expr(expressions[*index].expr.take().into()); optimize_stmt(&mut def_stmt, state, true); def_stmt.into() } _ => StmtBlock::NONE, }; - let body = Stmt::Expr(mem::take(&mut b.expr).into()).into(); - let expr = mem::take(&mut b.condition); + let body = Stmt::Expr(b.expr.take().into()).into(); + let expr = b.condition.take(); *stmt = Stmt::If( FlowControl { expr, body, branch }.into(), @@ -542,7 +542,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b if b.is_always_true() { // Promote the matched case - let mut statements = Stmt::Expr(mem::take(&mut b.expr).into()); + let mut statements = Stmt::Expr(b.expr.take().into()); optimize_stmt(&mut statements, state, true); *stmt = statements; state.set_dirty(); @@ -567,11 +567,11 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b if range_block.is_always_true() { // Promote the matched case let block = &mut expressions[r.index()]; - let mut statements = Stmt::Expr(mem::take(&mut block.expr).into()); + let mut statements = Stmt::Expr(block.expr.take().into()); optimize_stmt(&mut statements, state, true); *stmt = statements; } else { - let mut expr = mem::take(&mut range_block.condition); + let mut expr = range_block.condition.take(); // switch const { range if condition => stmt, _ => def } => if condition { stmt } else { def } optimize_expr(&mut expr, state, false); @@ -579,16 +579,14 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b let branch = match def_case { Some(index) => { let mut def_stmt = - Stmt::Expr(mem::take(&mut expressions[*index].expr).into()); + Stmt::Expr(expressions[*index].expr.take().into()); optimize_stmt(&mut def_stmt, state, true); def_stmt.into() } _ => StmtBlock::NONE, }; - let body = - Stmt::Expr(mem::take(&mut expressions[r.index()].expr).into()) - .into(); + let body = Stmt::Expr(expressions[r.index()].expr.take().into()).into(); *stmt = Stmt::If( FlowControl { expr, body, branch }.into(), @@ -628,7 +626,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b match def_case { Some(index) => { - let mut def_stmt = Stmt::Expr(mem::take(&mut expressions[*index].expr).into()); + let mut def_stmt = Stmt::Expr(expressions[*index].expr.take().into()); optimize_stmt(&mut def_stmt, state, true); *stmt = def_stmt; } @@ -738,17 +736,17 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b if let Expr::BoolConstant(true, pos) = expr { *expr = Expr::Unit(*pos); } - **body = optimize_stmt_block(mem::take(&mut **body), state, false, true, false); + **body = optimize_stmt_block(body.take_statements(), state, false, true, false); } // do { block } while|until expr Stmt::Do(x, ..) => { optimize_expr(&mut x.expr, state, false); - *x.body = optimize_stmt_block(mem::take(&mut *x.body), state, false, true, false); + *x.body = optimize_stmt_block(x.body.take_statements(), state, false, true, false); } // for id in expr { block } Stmt::For(x, ..) => { optimize_expr(&mut x.2.expr, state, false); - *x.2.body = optimize_stmt_block(mem::take(&mut *x.2.body), state, false, true, false); + *x.2.body = optimize_stmt_block(x.2.body.take_statements(), state, false, true, false); } // let id = expr; Stmt::Var(x, options, ..) if !options.contains(ASTFlags::CONSTANT) => { @@ -771,7 +769,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b // Only one statement which is not block-dependent - promote [s] if !s.is_block_dependent() => { state.set_dirty(); - *stmt = mem::take(s); + *stmt = s.take(); } _ => *stmt = (block, span).into(), } @@ -781,15 +779,15 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b // If try block is pure, there will never be any exceptions state.set_dirty(); *stmt = ( - optimize_stmt_block(mem::take(&mut *x.body), state, false, true, false), + optimize_stmt_block(x.body.take_statements(), state, false, true, false), x.body.span(), ) .into(); } // try { try_block } catch ( var ) { catch_block } Stmt::TryCatch(x, ..) => { - *x.body = optimize_stmt_block(mem::take(&mut *x.body), state, false, true, false); - *x.branch = optimize_stmt_block(mem::take(&mut *x.branch), state, false, true, false); + *x.body = optimize_stmt_block(x.body.take_statements(), state, false, true, false); + *x.branch = optimize_stmt_block(x.branch.take_statements(), state, false, true, false); } // expr(stmt) @@ -799,7 +797,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b Expr::Stmt(block) if !block.is_empty() => { let mut stmt_block = *mem::take(block); *stmt_block = - optimize_stmt_block(mem::take(&mut *stmt_block), state, true, true, false); + optimize_stmt_block(stmt_block.take_statements(), state, true, true, false); *stmt = stmt_block.into(); } Expr::Stmt(..) => *stmt = Stmt::Noop(expr.position()), @@ -810,7 +808,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b // expr(func()) Stmt::Expr(expr) if matches!(**expr, Expr::FnCall(..)) => { state.set_dirty(); - match mem::take(expr.as_mut()) { + match expr.take() { Expr::FnCall(x, pos) => *stmt = Stmt::FnCall(x, pos), _ => unreachable!(), } @@ -820,7 +818,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b // func(...) Stmt::FnCall(..) => { - if let Stmt::FnCall(x, pos) = mem::take(stmt) { + if let Stmt::FnCall(x, pos) = stmt.take() { let mut expr = Expr::FnCall(x, pos); optimize_expr(&mut expr, state, false); *stmt = match expr { @@ -883,16 +881,16 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { } // { stmt; ... } - do not count promotion as dirty because it gets turned back into an array Expr::Stmt(x) => { - ***x = optimize_stmt_block(mem::take(&mut **x), state, true, true, false); + ***x = optimize_stmt_block(x.take_statements(), state, true, true, false); // { Stmt(Expr) } - promote - if let [ Stmt::Expr(e) ] = &mut ****x { state.set_dirty(); *expr = mem::take(e); } + if let [ Stmt::Expr(e) ] = &mut ****x { state.set_dirty(); *expr = e.take(); } } // ()?.rhs #[cfg(not(feature = "no_object"))] Expr::Dot(x, options, ..) if options.contains(ASTFlags::NEGATED) && matches!(x.lhs, Expr::Unit(..)) => { state.set_dirty(); - *expr = mem::take(&mut x.lhs); + *expr = x.lhs.take(); } // lhs.rhs #[cfg(not(feature = "no_object"))] @@ -935,7 +933,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { #[cfg(not(feature = "no_index"))] Expr::Index(x, options, ..) if options.contains(ASTFlags::NEGATED) && matches!(x.lhs, Expr::Unit(..)) => { state.set_dirty(); - *expr = mem::take(&mut x.lhs); + *expr = x.lhs.take(); } // lhs[rhs] #[cfg(not(feature = "no_index"))] @@ -946,7 +944,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { // Array literal where everything is pure - promote the indexed item. // All other items can be thrown away. state.set_dirty(); - let mut result = mem::take(&mut a[*i as usize]); + let mut result = a[*i as usize].take(); result.set_position(*pos); *expr = result; } @@ -956,7 +954,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { // All other items can be thrown away. state.set_dirty(); let index = a.len() - i.unsigned_abs() as usize; - let mut result = mem::take(&mut a[index]); + let mut result = a[index].take(); result.set_position(*pos); *expr = result; } @@ -1018,7 +1016,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { // Merge consecutive strings while n < x.len() - 1 { - match (mem::take(&mut x[n]), mem::take(&mut x[n+1])) { + match (x[n].take(),x[n+1].take()) { (Expr::StringConstant(mut s1, pos), Expr::StringConstant(s2, ..)) => { s1 += s2; x[n] = Expr::StringConstant(s1, pos); x.remove(n+1); state.set_dirty(); } (expr1, Expr::Unit(..)) => { x[n] = expr1; x.remove(n+1); state.set_dirty(); } (Expr::Unit(..), expr2) => { x[n+1] = expr2; x.remove(n); state.set_dirty(); } @@ -1051,34 +1049,34 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) { // lhs && rhs Expr::And(x, ..) => match (&mut x.lhs, &mut x.rhs) { // true && rhs -> rhs - (Expr::BoolConstant(true, ..), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = mem::take(rhs); } + (Expr::BoolConstant(true, ..), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = rhs.take(); } // false && rhs -> false (Expr::BoolConstant(false, pos), ..) => { state.set_dirty(); *expr = Expr::BoolConstant(false, *pos); } // lhs && true -> lhs - (lhs, Expr::BoolConstant(true, ..)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = mem::take(lhs); } + (lhs, Expr::BoolConstant(true, ..)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = lhs.take(); } // lhs && rhs (lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, false); } }, // lhs || rhs Expr::Or(ref mut x, ..) => match (&mut x.lhs, &mut x.rhs) { // false || rhs -> rhs - (Expr::BoolConstant(false, ..), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = mem::take(rhs); } + (Expr::BoolConstant(false, ..), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = rhs.take(); } // true || rhs -> true (Expr::BoolConstant(true, pos), ..) => { state.set_dirty(); *expr = Expr::BoolConstant(true, *pos); } // lhs || false - (lhs, Expr::BoolConstant(false, ..)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = mem::take(lhs); } + (lhs, Expr::BoolConstant(false, ..)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = lhs.take(); } // lhs || rhs (lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, false); } }, // () ?? rhs -> rhs Expr::Coalesce(x, ..) if matches!(x.lhs, Expr::Unit(..)) => { state.set_dirty(); - *expr = mem::take(&mut x.rhs); + *expr = x.rhs.take(); }, // lhs:constant ?? rhs -> lhs Expr::Coalesce(x, ..) if x.lhs.is_constant() => { state.set_dirty(); - *expr = mem::take(&mut x.lhs); + *expr = x.lhs.take(); }, // !true or !false @@ -1383,7 +1381,7 @@ impl Engine { functions.into_iter().for_each(|fn_def| { let mut fn_def = crate::func::shared_take_or_clone(fn_def); // Optimize the function body - let body = mem::take(&mut *fn_def.body); + let body = fn_def.body.take_statements(); *fn_def.body = self.optimize_top_level(body, scope, lib2, optimization_level); diff --git a/src/types/dynamic.rs b/src/types/dynamic.rs index acc691a0..f1bf1d2b 100644 --- a/src/types/dynamic.rs +++ b/src/types/dynamic.rs @@ -1146,6 +1146,11 @@ impl Dynamic { )), } } + /// Return this [`Dynamic`], replacing it with [`Dynamic::UNIT`]. + #[inline(always)] + pub fn take(&mut self) -> Self { + mem::take(self) + } /// Convert the [`Dynamic`] value into specific type. /// /// Casting to a [`Dynamic`] just returns as is, but if it contains a shared value, diff --git a/tests/call_fn.rs b/tests/call_fn.rs index 5d4338d9..1547363d 100644 --- a/tests/call_fn.rs +++ b/tests/call_fn.rs @@ -175,7 +175,7 @@ fn test_fn_ptr_raw() -> Result<(), Box> { TypeId::of::(), ], move |context, args| { - let fp = std::mem::take(args[1]).cast::(); + let fp = args[1].take().cast::(); let value = args[2].clone(); let this_ptr = args.get_mut(0).unwrap(); diff --git a/tests/closures.rs b/tests/closures.rs index a0511456..f596c75e 100644 --- a/tests/closures.rs +++ b/tests/closures.rs @@ -16,8 +16,8 @@ fn test_fn_ptr_curry_call() -> Result<(), Box> { "call_with_arg", [TypeId::of::(), TypeId::of::()], |context, args| { - let fn_ptr = std::mem::take(args[0]).cast::(); - fn_ptr.call_raw(&context, None, [std::mem::take(args[1])]) + let fn_ptr = args[0].take().cast::(); + fn_ptr.call_raw(&context, None, [args[1].take()]) }, );