ThePhD / sol2

Sol3 (sol2 v3.0) - a C++ <-> Lua API wrapper with advanced features and top notch performance - is here, and it's great! Documentation:
http://sol2.rtfd.io/
MIT License
4.24k stars 520 forks source link

sol3 crash/recursion after adding custom type with non-explicit constructors #1618

Open RDaac opened 3 months ago

RDaac commented 3 months ago

I'm working with a library that has a variant class with non-explicit constructors for basic types like Variant(bool) and Variant(const char *). After adding sol3 sol_lua_get/push/check() functions for this type, sol operations on basic types, like lua["value"] = "cstring" or sol::stack::push<bool>(boolValue), will favor implicitly converting to the variant type and calling the custom sol_lua_push function over using the built-in operations for the basic types.

Is there a solution or fix for this? The equivalent sol2 implementation using struct pusher worked as expected.

This example recurses and segfaults (g++14, sol 3):

#include <sol.hpp>

struct MyStruct {
    MyStruct(bool val) { value = val; }   // not marked explicit
    bool value;
};

int sol_lua_push(lua_State *L, const MyStruct &v)
{
    // Recurses here instead of calling lua_pushboolean(L, v.value)
    sol::stack::push<bool>(L, v.value);
    return 1;
}

int main()
{
    sol::state lua;
    // Resolves to sol_lua_push(L, MyStruct(true)) instead of lua_pushboolean(L, true),
    lua["value"] = true;  
    return 0;
}
deadlocklogic commented 1 month ago

Using the exact type should work:

int sol_lua_push(sol::types<MyStruct>, lua_State *L, const MyStruct &v) {
    // Recurses here instead of calling lua_pushboolean(L, v.value)
    int amount = sol::stack::push<bool>(L, v.value);
    return amount;
}