Cannot move out a captured variable in an `FnMut` closure

⚓ Rust    📅 2025-07-12    👤 surdeus    👁️ 3      

surdeus

Look at this code:

use mlua::{Lua, Table};
fn init(xxx: SomeTypeWithoutCopy, lua: &Lua) {
	lua.globals().set(
		"base",
		lua.create_function_mut(move |luav, p: (String, u32, Table)| base(luav, p, xxx)).unwrap(),
	);
}
fn base(
	_: &Lua,
	(fn_name, args, argv): (String, u32, Table),
	xxx: SomeTypeWithoutCopy,
) -> Result<(), mlua::Error> {
	//Some other code
}

The compiler tells me that:

error[E0507]: cannot move out of `xxx`, a captured variable in an `FnMut` closure
lua.create_function_mut(move |luav, p: (String, u32, Table)| base(luav, p, xxx)).unwrap(),
                        ------------------------------------               ^^^ move occurs because `xxx` has type `Game`, which does not implement the `Copy` trait
                        |
                        captured by this `FnMut` closure

It works well if I change the code to that:

// ...
lua.create_function_mut(move |luav, p: (String, u32, Table)| base(luav, p, xxx.clone())).unwrap()
// ...

But Must clone be here? I think the variable should can move into the closure.

Edit:
Okay. Thank to alice and kpreid.
The function "base" will change some value in xxx. And I hope if call the closure, "base" can read those changed values.
I think that code can solve problem:

use mlua::{Lua, Table};
fn init(mut xxx: SomeTypeWithoutCopy, lua: &Lua) {
	lua.globals().set(
		"base",
		lua.create_function_mut(move |luav, p: (String, u32, Table)| base(luav, p, &mut xxx)).unwrap(),
	);
}
fn base(
	_: &Lua,
	(fn_name, args, argv): (String, u32, Table),
	xxx: &mut SomeTypeWithoutCopy,
) -> Result<(), mlua::Error> {
	//Some other code
}

But just for curious, What variable do move into the closure? The "xxx" or "&mut xxx"?

3 posts - 3 participants

Read full topic

🏷️ rust_feed