A reference to a boxed object inside the same struct

I'm trying to create a struct that will use mlua crate to generate some data.
Mlua interface is pretty simple - basically I need to make a central mlua::Lua struct that provides all the services.

So basically my struct could look like this:

pub struct DataGenerator {
    lua: Lua,
}

impl DataGenerator {
   pub fn give_me_some_data(&self) -> Vec<u64> {
      let function: Function = lua.globals().get("my_function").unwrap();  // lookup the code to run
      let result = function.call(...);  // now run the code
      // ... process the results
   }
}

However, that's not very efficient, because I'm looking up the function each time (and yes, I profiled that and it adds non-negligible amount of time). It would be nice to cache the returned Function object.

The problem is, Function is tied to the lifetime of Lua, so actually it has a signature Function<'lua>.
And that's a bummer, a naive way of doing it doesn't work:

pub struct DataGenerator {
    lua: Pin<Box<Lua>>,
    main_f: Function<'static>
}

impl DataGenerator {

    pub fn new() -> DataGenerator {
        let lua = Pin::new(Box::new(Lua::new()));
        lua.load("some lua code ...").exec().unwrap();
        let main_f = lua.globals().get("my_function").unwrap();       
        DataGenerator { lua, main_f }  // error: borrowed value does not live long enough
    }

I think it should be doable, because the object under Pin should never move, and it definitely lives as long as the DataGenerator. What is the idiomatic way to do it?

You misunderstand the purpose of Pin. It does not let you write self-referential structs safely.

Did you consider having the Lua object be stored outside of DataGenerator and giving all of your lua-related structs a 'lua lifetime for references to the Lua object?

3 Likes

Yes, I considered that, but that makes the API a bit more complex. I thought it would be possible to hide function caching as an implementation detail.

You can't write self-referential structs in safe Rust.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.