Callbacks should be 'static again, fix #33

Every time I do lifetime transmutation, I get it wrong.
This commit is contained in:
kyren 2017-08-01 12:03:05 -04:00
parent 8ba3886c96
commit 721ffc462d
2 changed files with 53 additions and 43 deletions

View file

@ -968,7 +968,7 @@ impl<'lua, T: UserData> UserDataMethods<'lua, T> {
/// back to the user-provided metamethod if no regular method was found.
pub fn add_method<M>(&mut self, name: &str, method: M)
where
M: 'lua + for<'a> FnMut(&'lua Lua, &'a T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
M: 'static + for<'a> FnMut(&'lua Lua, &'a T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
{
self.methods.insert(
name.to_owned(),
@ -983,7 +983,7 @@ impl<'lua, T: UserData> UserDataMethods<'lua, T> {
/// [`add_method`]: #method.add_method
pub fn add_method_mut<M>(&mut self, name: &str, method: M)
where
M: 'lua + for<'a> FnMut(&'lua Lua, &'a mut T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
M: 'static + for<'a> FnMut(&'lua Lua, &'a mut T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
{
self.methods.insert(
name.to_owned(),
@ -1000,7 +1000,7 @@ impl<'lua, T: UserData> UserDataMethods<'lua, T> {
/// [`add_method_mut`]: #method.add_method_mut
pub fn add_function<F>(&mut self, name: &str, function: F)
where
F: 'lua + FnMut(&'lua Lua, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
F: 'static + FnMut(&'lua Lua, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
{
self.methods.insert(name.to_owned(), Box::new(function));
}
@ -1015,7 +1015,7 @@ impl<'lua, T: UserData> UserDataMethods<'lua, T> {
/// [`add_meta_function`]: #method.add_meta_function
pub fn add_meta_method<M>(&mut self, meta: MetaMethod, method: M)
where
M: 'lua + for<'a> FnMut(&'lua Lua, &'a T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
M: 'static + for<'a> FnMut(&'lua Lua, &'a T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
{
self.meta_methods.insert(meta, Self::box_method(method));
}
@ -1030,7 +1030,7 @@ impl<'lua, T: UserData> UserDataMethods<'lua, T> {
/// [`add_meta_function`]: #method.add_meta_function
pub fn add_meta_method_mut<M>(&mut self, meta: MetaMethod, method: M)
where
M: 'lua + for<'a> FnMut(&'lua Lua, &'a mut T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
M: 'static + for<'a> FnMut(&'lua Lua, &'a mut T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
{
self.meta_methods.insert(meta, Self::box_method_mut(method));
}
@ -1042,14 +1042,14 @@ impl<'lua, T: UserData> UserDataMethods<'lua, T> {
/// userdata of type `T`.
pub fn add_meta_function<F>(&mut self, meta: MetaMethod, function: F)
where
F: 'lua + FnMut(&'lua Lua, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
F: 'static + FnMut(&'lua Lua, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
{
self.meta_methods.insert(meta, Box::new(function));
}
fn box_method<M>(mut method: M) -> Callback<'lua>
where
M: 'lua + for<'a> FnMut(&'lua Lua, &'a T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
M: 'static + for<'a> FnMut(&'lua Lua, &'a T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
{
Box::new(move |lua, mut args| if let Some(front) = args.pop_front() {
let userdata = AnyUserData::from_lua(front, lua)?;
@ -1065,7 +1065,7 @@ impl<'lua, T: UserData> UserDataMethods<'lua, T> {
fn box_method_mut<M>(mut method: M) -> Callback<'lua>
where
M: 'lua + for<'a> FnMut(&'lua Lua, &'a mut T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
M: 'static + for<'a> FnMut(&'lua Lua, &'a mut T, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
{
Box::new(move |lua, mut args| if let Some(front) = args.pop_front() {
let userdata = AnyUserData::from_lua(front, lua)?;
@ -1514,7 +1514,7 @@ impl Lua {
/// ```
pub fn create_function<'lua, F>(&'lua self, func: F) -> Function<'lua>
where
F: 'lua + FnMut(&'lua Lua, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
F: 'static + FnMut(&'lua Lua, MultiValue<'lua>) -> Result<MultiValue<'lua>>,
{
self.create_callback_function(Box::new(func))
}

View file

@ -208,32 +208,27 @@ fn test_bind() {
#[test]
fn test_rust_function() {
let mut captured_var = 2;
{
let lua = Lua::new();
let globals = lua.globals();
lua.exec::<()>(
r#"
function lua_function()
return rust_function()
end
let lua = Lua::new();
let globals = lua.globals();
lua.exec::<()>(
r#"
function lua_function()
return rust_function()
end
-- Test to make sure chunk return is ignored
return 1
"#,
None,
).unwrap();
-- Test to make sure chunk return is ignored
return 1
"#,
None,
).unwrap();
let lua_function = globals.get::<_, Function>("lua_function").unwrap();
let rust_function = lua.create_function(|lua, _| {
captured_var = 42;
lua.pack("hello")
});
let lua_function = globals.get::<_, Function>("lua_function").unwrap();
let rust_function = lua.create_function(|lua, _| {
lua.pack("hello")
});
globals.set("rust_function", rust_function).unwrap();
assert_eq!(lua_function.call::<_, String>(()).unwrap(), "hello");
}
assert_eq!(captured_var, 42);
globals.set("rust_function", rust_function).unwrap();
assert_eq!(lua_function.call::<_, String>(()).unwrap(), "hello");
}
#[test]
@ -368,17 +363,6 @@ fn test_scope() {
assert_eq!(tin.get::<_, i64>(1).unwrap(), 1);
assert_eq!(tin.get::<_, i64>(2).unwrap(), 2);
assert_eq!(tin.get::<_, i64>(3).unwrap(), 3);
// Should not compile, don't know how to test that
// struct UserData;
// impl UserData for UserData {};
// let userdata_ref;
// {
// let touter = globals.get::<_, Table>("touter").unwrap();
// touter.set("userdata", lua.create_userdata(UserData).unwrap()).unwrap();
// let userdata = touter.get::<_, AnyUserData>("userdata").unwrap();
// userdata_ref = userdata.borrow::<UserData>();
// }
}
#[test]
@ -907,3 +891,29 @@ fn coroutine_panic() {
let thrd: Thread = lua.create_thread(thrd_main);
thrd.resume::<_, ()>(()).unwrap();
}
// Need to use compiletest-rs or similar to make sure these don't compile.
/*
#[test]
fn should_not_compile() {
let lua = Lua::new();
let globals = lua.globals();
// Should not allow userdata borrow to outlive lifetime of AnyUserData handle
struct MyUserData;
impl UserData for MyUserData {};
let userdata_ref;
{
let touter = globals.get::<_, Table>("touter").unwrap();
touter.set("userdata", lua.create_userdata(MyUserData)).unwrap();
let userdata = touter.get::<_, AnyUserData>("userdata").unwrap();
userdata_ref = userdata.borrow::<MyUserData>();
}
// Should not allow self borrow of lua, it can change addresses
globals.set("boom", lua.create_function(|_, _| {
lua.pack(lua.eval::<i32>("1 + 1", None)?)
})).unwrap();
}
*/