TERRIBLE HACK FIX I DO NOT UNDERSTAND

Okay, so this is the fix for the previously mentioned lifetime problem.  I
mimicked the API for `crossbeam::scope` extremely closely for `Lua::scope`, and
for some reason things that would not compile with `crossbeam::scope` WOULD
compile with `Lua::scope`, and I could not figure it out.

So I took the crossbeam source and made tiny edits until I determined the
crossover point where invalid borrows would compile, and it was.. not what I
expected it to be.  Simply replacing a RefCell<Option<DtorChain<'a>>> with a
PhantomData<&'a ()> would suddenly cause this to compile with crossbeam:

```
struct Test {
    field: i32,
}
crossbeam::scope(|scope| {
    let mut t = Test {
        field: 0,
    };

    scope.spawn(|| t.field = 42);

    drop(t);

    // ...anything
})

```

which is precisely the same problem as `rlua`.

To say I am unsatisfied by this fix is a drastic understatement.  SURELY this
must be a compiler bug?
This commit is contained in:
kyren 2018-02-08 05:00:11 -05:00
parent f05716deb8
commit 7701aeef85
1 changed files with 2 additions and 0 deletions

View File

@ -33,6 +33,7 @@ pub struct Lua {
pub struct Scope<'scope> { pub struct Scope<'scope> {
lua: &'scope Lua, lua: &'scope Lua,
destructors: RefCell<Vec<Box<FnMut(*mut ffi::lua_State) -> Box<Any>>>>, destructors: RefCell<Vec<Box<FnMut(*mut ffi::lua_State) -> Box<Any>>>>,
_phantom: PhantomData<RefCell<&'scope ()>>,
} }
// Data associated with the main lua_State via lua_getextraspace. // Data associated with the main lua_State via lua_getextraspace.
@ -326,6 +327,7 @@ impl Lua {
let mut scope = Scope { let mut scope = Scope {
lua: self, lua: self,
destructors: RefCell::new(Vec::new()), destructors: RefCell::new(Vec::new()),
_phantom: PhantomData,
}; };
let r = f(&mut scope); let r = f(&mut scope);
drop(scope); drop(scope);