summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkyren <kerriganw@gmail.com>2018-02-08 04:55:26 -0500
committerkyren <kerriganw@gmail.com>2018-02-08 05:12:11 -0500
commitf05716deb85e8e458f2a43478c5fae4cb156099b (patch)
tree55a8203a8da61a7add9bc0ee47f5aab58e431616
parent7a0c0665937c36feaa5deff93f2a70e9a4d4a508 (diff)
downloadmlua-f05716deb85e8e458f2a43478c5fae4cb156099b.zip
This SHOULD fix the lifetime problem with scope... but it doesn't!
The following code should not compile: ``` struct Test { field: i32, } let lua = Lua::new(); lua.scope(|scope| { let mut test = Test { field: 0 }; let f = scope .create_function(|_, ()| { test.field = 42; Ok(()) }) .unwrap(); lua.globals().set("bad!", f).unwrap(); }); ``` yet it does with this commit. However, I have a fix for this, which I do not in any way understand.
-rw-r--r--src/lua.rs16
-rw-r--r--src/tests.rs21
2 files changed, 27 insertions, 10 deletions
diff --git a/src/lua.rs b/src/lua.rs
index a0320e6..a7bf385 100644
--- a/src/lua.rs
+++ b/src/lua.rs
@@ -30,8 +30,8 @@ pub struct Lua {
/// Constructed by the `Lua::scope` method, allows temporarily passing to Lua userdata that is
/// !Send, and callbacks that are !Send and not 'static.
-pub struct Scope<'lua> {
- lua: &'lua Lua,
+pub struct Scope<'scope> {
+ lua: &'scope Lua,
destructors: RefCell<Vec<Box<FnMut(*mut ffi::lua_State) -> Box<Any>>>>,
}
@@ -319,9 +319,9 @@ impl Lua {
/// lifetime of values created through `Scope`, and we know that `Lua` cannot be sent to another
/// thread while `Scope` is live, it is safe to allow !Send datatypes and functions whose
/// lifetimes only outlive the scope lifetime.
- pub fn scope<'lua, F, R>(&'lua self, f: F) -> R
+ pub fn scope<'scope, F, R>(&'scope self, f: F) -> R
where
- F: FnOnce(&mut Scope<'lua>) -> R,
+ F: FnOnce(&mut Scope<'scope>) -> R,
{
let mut scope = Scope {
lua: self,
@@ -1036,8 +1036,8 @@ impl Lua {
}
}
-impl<'lua> Scope<'lua> {
- pub fn create_function<'scope, A, R, F>(&'scope self, mut func: F) -> Result<Function<'scope>>
+impl<'scope> Scope<'scope> {
+ pub fn create_function<A, R, F>(&self, mut func: F) -> Result<Function<'scope>>
where
A: FromLuaMulti<'scope>,
R: ToLuaMulti<'scope>,
@@ -1071,7 +1071,7 @@ impl<'lua> Scope<'lua> {
}
}
- pub fn create_userdata<T>(&self, data: T) -> Result<AnyUserData>
+ pub fn create_userdata<T>(&self, data: T) -> Result<AnyUserData<'scope>>
where
T: UserData,
{
@@ -1094,7 +1094,7 @@ impl<'lua> Scope<'lua> {
}
}
-impl<'lua> Drop for Scope<'lua> {
+impl<'scope> Drop for Scope<'scope> {
fn drop(&mut self) {
// We separate the action of invalidating the userdata in Lua and actually dropping the
// userdata type into two phases. This is so that, in the event a userdata drop panics, we
diff --git a/src/tests.rs b/src/tests.rs
index bb721d8..f8ce37a 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -695,7 +695,24 @@ fn should_not_compile() {
let lua = Lua::new();
let mut r = None;
lua.scope(|scope| {
- r = Some(scope.create_userdata(MyUserdata(Rc::new(()))).unwrap());
- });
+ r = Some(scope.create_userdata(MyUserdata(Rc::new(()))).unwrap());
+ });
+
+ struct Test {
+ field: i32,
+ }
+
+ let lua = Lua::new();
+ lua.scope(|scope| {
+ let mut test = Test { field: 0 };
+
+ let f = scope
+ .create_function(|_, ()| {
+ test.field = 42;
+ Ok(())
+ })
+ .unwrap();
+ lua.globals().set("bad!", f).unwrap();
+ });
}
*/