#borrowed data escapes outside of method

1 messages · Page 1 of 1 (latest)

rose ermine
#

code:

    fn _on_click(&self, func: Rc<RefCell<LuaFunction>>) {
        let gesture = gtk::GestureClick::new();
    
        gesture.connect_closure("clicked", false, closure_local!(move || {
            let a = func.borrow().clone();
            a.call::<_, ()>(LuaNil);
        }));
    
        self.add_controller(gesture)
    }```
The error comes from `closure_local!` (a macro from `gtkrs`)

Error:
```rs
borrowed data escapes outside of method
requirement occurs because of the type `RefCell<mlua::Function<'_>>`, which makes the generic argument `mlua::Function<'_>` invariant
the struct `RefCell<T>` is invariant over the parameter `T`
see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variancerustc

css.rs(76, 25): `func` is a reference that is only valid in the method body
css.rs(76, 25): has type `Rc<RefCell<mlua::Function<'1>>>```

what's the proper way of doing this? 🤔
main notch
#

I can't find such a crate: there's a gtk and a number of similar crates, but nothing with a closure_local macro. Do you have a link?

shadow kayak
#

you probably just need to move the clone outside of the closure

#

ah actually no, that's not it

shadow kayak
#

Wait, are you missing lifetimes?
maybe slap a #![deny(rust_2018_idiom)] in your crate root

main notch
#

It is a move closure, though, so it should be taking ownership ferrisHmm

main notch
blazing valley
#

the "doing lua in gui thread" problem is pretty common, but I still don't know how to manage that lol

main notch
blazing valley
#

oh you meant that as an answer to "are you missing lifetimes" and not to the lint being there

shadow kayak
#

I actually remember someone complaining about LuaFunction not being 'static

#

in which case this would be a fairly difficult problem to solve

rose ermine
blazing valley
#

no, because func has a lifetime parameter for 'lua

rose ermine
#

here's the code where the func variable is made:

            table.set(
                "on_click",
                lua.create_function(move |_lua, func: LuaFunction| {
                    tags3.borrow()[i].widget._on_click(Rc::new(RefCell::new(func)));
                    Ok(())
                })?,
            )?;```
blazing valley
#

which is in particular not 'static

rose ermine
#

i've tried some unsafe magic to make it static: ```rs
let func_static = unsafe { std::mem::transmute::<&'a LuaFunction, &'static LuaFunction>(func) };

thread 'main' panicked at src/test.rs:90:13:
assertion left == right failed: Expected 0 arguments but got 4
left: 4
right: 0
pointing at rs
gesture.connect_closure(
"pressed",
false,
closure_local!(|| {
a.call::<_, ()>(LuaNil).unwrap();
}),
);```
specifically, at the closure_local!

#

running with RUST_BACKTRACE=1, i get:

stack backtrace:
   0: rust_begin_unwind
             at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panicking.rs:645:5
   1: core::panicking::panic_fmt
             at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/panicking.rs:72:14
   2: core::panicking::assert_failed_inner
             at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/panicking.rs:337:23
   3: core::panicking::assert_failed
             at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/panicking.rs:297:5
   4: <gtk4::auto::label::Label as webx::b9::css::Styleable>::_on_click::{{closure}}
             at ./src/test.rs:90:13```, i suppose some sort of assertion failed for gtk::Label, meaning the closure is failing
rose ermine
blazing valley
#

normally I'd suggest lua having its own thread and communicating with it through channels or other means

#

because that'd make its lifetime local

#

but idk what the usual advice is, because that could be inconvenient

rose ermine
#

im just trying to call a function from Lua when a GTK widget is clicked, been stuck on it for 2 days xD

rose ermine
blazing valley
shadow kayak
#

@rose ermine As far as I know, you have basically two options:

  • Use OwnedFunction instead of Function<'_>
  • Leak your Lua instance to get a &'static Lua and derive stiff from that
#

please do not use transmute to extend your lifetimes, and please do not omit lifetimes from function signatures

rose ermine