From 9c198413ece76474da64e6718696521a0b6cb200 Mon Sep 17 00:00:00 2001 From: nothing <65153224+nothing1649@users.noreply.github.com> Date: Tue, 18 Feb 2025 04:36:52 +1100 Subject: [PATCH] Analysis: Make typeof on a type userdata return "type" (#1568) This change introduces a flag (`LuauUserTypeFunTypeofReturnsType`) that, when enabled, sets `__type` on the type userdata's metatable to "type". This behaviour was described in the user-defined type function RFC (https://rfcs.luau.org/user-defined-type-functions.html), but seems to have been missed; this change implements that behaviour. Currently this does not change `typeof(t) == 'type'` emitting an unknown type warning as I don't trust myself to implement it due to my general lack of C++ knowledge; this can be worked on later. --- Analysis/src/TypeFunctionRuntime.cpp | 7 +++++++ tests/TypeFunction.user.test.cpp | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Analysis/src/TypeFunctionRuntime.cpp b/Analysis/src/TypeFunctionRuntime.cpp index 14f13d5e..79c4f6a1 100644 --- a/Analysis/src/TypeFunctionRuntime.cpp +++ b/Analysis/src/TypeFunctionRuntime.cpp @@ -14,6 +14,7 @@ #include LUAU_DYNAMIC_FASTINT(LuauTypeFunctionSerdeIterationLimit) +LUAU_FASTFLAGVARIABLE(LuauUserTypeFunTypeofReturnsType) namespace Luau { @@ -1564,6 +1565,12 @@ void registerTypeUserData(lua_State* L) // Create and register metatable for type userdata luaL_newmetatable(L, "type"); + + if (FFlag::LuauUserTypeFunTypeofReturnsType) + { + lua_pushstring(L, "type"); + lua_setfield(L, -2, "__type"); + } // Protect metatable from being changed lua_pushstring(L, "The metatable is locked"); diff --git a/tests/TypeFunction.user.test.cpp b/tests/TypeFunction.user.test.cpp index 8f48961d..2cd586c9 100644 --- a/tests/TypeFunction.user.test.cpp +++ b/tests/TypeFunction.user.test.cpp @@ -9,6 +9,7 @@ using namespace Luau; LUAU_FASTFLAG(LuauSolverV2) LUAU_FASTFLAG(DebugLuauEqSatSimplification) +LUAU_FASTFLAG(LuauUserTypeFunTypeofReturnsType) TEST_SUITE_BEGIN("UserDefinedTypeFunctionTests"); @@ -1866,4 +1867,22 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "udtf_eqsat_opaque") CHECK_EQ("t0", toString(simplified->result)); // NOLINT(bugprone-unchecked-optional-access) } +TEST_CASE_FIXTURE(BuiltinsFixture, "typeof_type_userdata_returns_type") +{ + ScopedFastFlag solverV2{FFlag::LuauSolverV2, true}; + ScopedFastFlag luauUserTypeFunTypeofReturnsType{FFlag::LuauUserTypeFunTypeofReturnsType, true}; + + CheckResult result = check(R"( +type function test(t) + print(typeof(t)) + return t +end + +local _:test + )"); + + LUAU_REQUIRE_ERROR_COUNT(1, result); + CHECK(toString(result.errors[0]) == R"(type)"); +} + TEST_SUITE_END();