summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lua.rs16
-rw-r--r--tests/compile_fail/static_callback_args.rs32
-rw-r--r--tests/compile_fail/static_callback_args.stderr35
3 files changed, 80 insertions, 3 deletions
diff --git a/src/lua.rs b/src/lua.rs
index 12feca9..f9b23d7 100644
--- a/src/lua.rs
+++ b/src/lua.rs
@@ -190,6 +190,7 @@ impl Lua {
#[doc(hidden)]
pub fn entrypoint1<'lua, 'callback, R, F>(&'lua self, func: F) -> Result<c_int>
where
+ 'lua: 'callback,
R: ToLua<'callback>,
F: 'static + Fn(&'callback Lua) -> Result<R>,
{
@@ -446,6 +447,7 @@ impl Lua {
/// [`ToLuaMulti`]: trait.ToLuaMulti.html
pub fn create_function<'lua, 'callback, A, R, F>(&'lua self, func: F) -> Result<Function<'lua>>
where
+ 'lua: 'callback,
A: FromLuaMulti<'callback>,
R: ToLuaMulti<'callback>,
F: 'static + Fn(&'callback Lua, A) -> Result<R>,
@@ -466,6 +468,7 @@ impl Lua {
func: F,
) -> Result<Function<'lua>>
where
+ 'lua: 'callback,
A: FromLuaMulti<'callback>,
R: ToLuaMulti<'callback>,
F: 'static + FnMut(&'callback Lua, A) -> Result<R>,
@@ -522,6 +525,7 @@ impl Lua {
func: F,
) -> Result<Function<'lua>>
where
+ 'lua: 'callback,
A: FromLuaMulti<'callback>,
R: ToLuaMulti<'callback>,
F: 'static + Fn(&'callback Lua, A) -> FR,
@@ -736,7 +740,7 @@ impl Lua {
/// Equivalent to calling [`set_named_registry_value`] with a value of Nil.
///
/// [`set_named_registry_value`]: #method.set_named_registry_value
- pub fn unset_named_registry_value<'lua, S>(&'lua self, name: &S) -> Result<()>
+ pub fn unset_named_registry_value<S>(&self, name: &S) -> Result<()>
where
S: ?Sized + AsRef<[u8]>,
{
@@ -1079,7 +1083,10 @@ impl Lua {
pub(crate) fn create_callback<'lua, 'callback>(
&'lua self,
func: Callback<'callback, 'static>,
- ) -> Result<Function<'lua>> {
+ ) -> Result<Function<'lua>>
+ where
+ 'lua: 'callback,
+ {
unsafe extern "C" fn call_callback(state: *mut ffi::lua_State) -> c_int {
callback_error(state, |nargs| {
let func =
@@ -1133,7 +1140,10 @@ impl Lua {
pub(crate) fn create_async_callback<'lua, 'callback>(
&'lua self,
func: AsyncCallback<'callback, 'static>,
- ) -> Result<Function<'lua>> {
+ ) -> Result<Function<'lua>>
+ where
+ 'lua: 'callback,
+ {
#[cfg(any(feature = "lua53", feature = "lua52"))]
self.load_from_std_lib(StdLib::COROUTINE)?;
diff --git a/tests/compile_fail/static_callback_args.rs b/tests/compile_fail/static_callback_args.rs
new file mode 100644
index 0000000..66dbf8b
--- /dev/null
+++ b/tests/compile_fail/static_callback_args.rs
@@ -0,0 +1,32 @@
+use std::cell::RefCell;
+
+use mlua::{Lua, Result, Table};
+
+fn main() -> Result<()> {
+ thread_local! {
+ static BAD_TIME: RefCell<Option<Table<'static>>> = RefCell::new(None);
+ }
+
+ let lua = Lua::new();
+
+ lua.create_function(|_, table: Table| {
+ BAD_TIME.with(|bt| {
+ *bt.borrow_mut() = Some(table);
+ });
+ Ok(())
+ })?
+ .call::<_, ()>(lua.create_table()?)?;
+
+ // In debug, this will panic with a reference leak before getting to the next part but
+ // it segfaults anyway.
+ drop(lua);
+
+ BAD_TIME.with(|bt| {
+ println!(
+ "you're gonna have a bad time: {}",
+ bt.borrow().as_ref().unwrap().len().unwrap()
+ );
+ });
+
+ Ok(())
+}
diff --git a/tests/compile_fail/static_callback_args.stderr b/tests/compile_fail/static_callback_args.stderr
new file mode 100644
index 0000000..561bcbe
--- /dev/null
+++ b/tests/compile_fail/static_callback_args.stderr
@@ -0,0 +1,35 @@
+error[E0597]: `lua` does not live long enough
+ --> $DIR/static_callback_args.rs:12:5
+ |
+12 | lua.create_function(|_, table: Table| {
+ | -^^
+ | |
+ | _____borrowed value does not live long enough
+ | |
+13 | | BAD_TIME.with(|bt| {
+14 | | *bt.borrow_mut() = Some(table);
+15 | | });
+16 | | Ok(())
+17 | | })?
+ | |______- argument requires that `lua` is borrowed for `'static`
+...
+32 | }
+ | - `lua` dropped here while still borrowed
+
+error[E0505]: cannot move out of `lua` because it is borrowed
+ --> $DIR/static_callback_args.rs:22:10
+ |
+12 | lua.create_function(|_, table: Table| {
+ | ---
+ | |
+ | _____borrow of `lua` occurs here
+ | |
+13 | | BAD_TIME.with(|bt| {
+14 | | *bt.borrow_mut() = Some(table);
+15 | | });
+16 | | Ok(())
+17 | | })?
+ | |______- argument requires that `lua` is borrowed for `'static`
+...
+22 | drop(lua);
+ | ^^^ move out of `lua` occurs here