diff options
author | kyren <kerriganw@gmail.com> | 2018-02-08 04:55:26 -0500 |
---|---|---|
committer | kyren <kerriganw@gmail.com> | 2018-02-08 05:12:11 -0500 |
commit | f05716deb85e8e458f2a43478c5fae4cb156099b (patch) | |
tree | 55a8203a8da61a7add9bc0ee47f5aab58e431616 | |
parent | 7a0c0665937c36feaa5deff93f2a70e9a4d4a508 (diff) | |
download | mlua-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.rs | 16 | ||||
-rw-r--r-- | src/tests.rs | 21 |
2 files changed, 27 insertions, 10 deletions
@@ -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(); + }); } */ |