From 2e5b3bb5eb5356d15b341b46d1a3e2ecaa19ad1c Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Fri, 2 May 2025 12:27:20 +0200 Subject: [PATCH] Fix panicking during require because of long lived require context borrow --- crates/lune-std/src/globals/require/mod.rs | 25 ++++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/crates/lune-std/src/globals/require/mod.rs b/crates/lune-std/src/globals/require/mod.rs index 487cbda..bef9ab6 100644 --- a/crates/lune-std/src/globals/require/mod.rs +++ b/crates/lune-std/src/globals/require/mod.rs @@ -35,7 +35,18 @@ pub fn create(lua: Lua) -> LuaResult { 3. The lua chunk we are require-ing from */ - let require_fn = lua.create_async_function(require)?; + let require_fn = lua.create_async_function(|lua, (source, path)| { + // NOTE: We need to make sure that the app data reference does not + // live through the entire require call, to prevent panicking from + // being unable to borrow other app data in the main body of scripts + let context = { + let context = lua + .app_data_ref::() + .expect("Failed to get RequireContext from app data"); + context.clone() + }; + require(lua, context, source, path) + })?; let get_source_fn = lua.create_function(move |lua, (): ()| match lua.inspect_stack(2) { None => Err(LuaError::runtime( "Failed to get stack info for require source", @@ -60,7 +71,12 @@ pub fn create(lua: Lua) -> LuaResult { .into_lua(&lua) } -async fn require(lua: Lua, (source, path): (LuaString, LuaString)) -> LuaResult { +async fn require( + lua: Lua, + context: RequireContext, + source: LuaString, + path: LuaString, +) -> LuaResult { let source = source .to_str() .into_lua_err() @@ -73,11 +89,6 @@ async fn require(lua: Lua, (source, path): (LuaString, LuaString)) -> LuaResult< .context("Failed to parse require path as string")? .to_string(); - let context = lua - .app_data_ref::() - .expect("Failed to get RequireContext from app data") - .clone(); - if let Some(builtin_name) = path.strip_prefix("@lune/").map(str::to_ascii_lowercase) { library::require(lua, &context, &builtin_name) } else if let Some(self_path) = path.strip_prefix("@self/") {