From 53b7b5b70bbb640609e23f3cfb91d62739f3c806 Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Sun, 27 Aug 2023 23:01:37 +0100 Subject: [PATCH] Fix setting userdata (static) fields when it has __index metamethod/function. Closes #312 --- src/lua.rs | 1 + tests/userdata.rs | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/lua.rs b/src/lua.rs index 57fb304..11765ce 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -2667,6 +2667,7 @@ impl Lua { rawset_field(state, metatable_index, "__index")?; } _ => { + ffi::lua_pop(state, 1); // Propagate fields to the field getters for (k, f) in registry.fields { registry.field_getters.push((k, f)) diff --git a/tests/userdata.rs b/tests/userdata.rs index 98431bd..da6c40d 100644 --- a/tests/userdata.rs +++ b/tests/userdata.rs @@ -506,6 +506,9 @@ fn test_functions() -> Result<()> { #[test] fn test_fields() -> Result<()> { + let lua = Lua::new(); + let globals = lua.globals(); + #[derive(Copy, Clone)] struct MyUserData(i64); @@ -533,8 +536,6 @@ fn test_fields() -> Result<()> { } } - let lua = Lua::new(); - let globals = lua.globals(); globals.set("ud", MyUserData(7))?; lua.load( r#" @@ -555,6 +556,33 @@ fn test_fields() -> Result<()> { ) .exec()?; + // Case: fields + __index metamethod (function) + struct MyUserData2(i64); + + impl UserData for MyUserData2 { + fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) { + fields.add_field("z", 0); + fields.add_field_method_get("x", |_, data| Ok(data.0)); + } + + fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { + methods.add_meta_method(MetaMethod::Index, |_, _, name: StdString| match &*name { + "y" => Ok(Some(-1)), + _ => Ok(None), + }); + } + } + + globals.set("ud", MyUserData2(1))?; + lua.load( + r#" + assert(ud.x == 1) + assert(ud.y == -1) + assert(ud.z == 0) + "#, + ) + .exec()?; + Ok(()) }