Skip to content

Commit

Permalink
Analysis: Make typeof on a type userdata return "type" (#1568)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nothing1649 authored Feb 17, 2025
1 parent bd4fe54 commit 9c19841
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Analysis/src/TypeFunctionRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <vector>

LUAU_DYNAMIC_FASTINT(LuauTypeFunctionSerdeIterationLimit)
LUAU_FASTFLAGVARIABLE(LuauUserTypeFunTypeofReturnsType)

namespace Luau
{
Expand Down Expand Up @@ -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");
Expand Down
19 changes: 19 additions & 0 deletions tests/TypeFunction.user.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ using namespace Luau;

LUAU_FASTFLAG(LuauSolverV2)
LUAU_FASTFLAG(DebugLuauEqSatSimplification)
LUAU_FASTFLAG(LuauUserTypeFunTypeofReturnsType)

TEST_SUITE_BEGIN("UserDefinedTypeFunctionTests");

Expand Down Expand Up @@ -1866,4 +1867,22 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "udtf_eqsat_opaque")
CHECK_EQ("t0<number & string>", 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<number>
)");

LUAU_REQUIRE_ERROR_COUNT(1, result);
CHECK(toString(result.errors[0]) == R"(type)");
}

TEST_SUITE_END();

0 comments on commit 9c19841

Please sign in to comment.