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();