Skip to content

Commit

Permalink
keyof - fix LUAU_ASSERT when there's only one key entry (#1388)
Browse files Browse the repository at this point in the history
Fixes #1387

Was suggested by @alexmccord 

I changed ``singletons[0]`` to ``singletons.front()``, unsure if that
makes a huge difference, and then I added the rest of the things needed
for the return type.

Maybe it's also the ideal location since doing it before looping through
``keys`` won't add the string into the type arena.

I put comments next to it based on how I thought it would make sense.

 

``LUAU_ASSERT`` seems to trigger when there's only one entry being put
inside a UnionType. It's as if it was put there for quality.

Allow edits by maintainers is enabled.


I tested this with a quick Unit Test something like

```lua
local test: keyof<typeof({a="test"})>
```
  • Loading branch information
karl-police authored Sep 9, 2024
1 parent d9536ce commit a8047b2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Analysis/src/TypeFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2041,6 +2041,12 @@ TypeFunctionReductionResult<TypeId> keyofFunctionImpl(
for (std::string key : keys)
singletons.push_back(ctx->arena->addType(SingletonType{StringSingleton{key}}));

// If there's only one entry, we don't need a UnionType.
// We can take straight take it from the first entry
// because it was added into the type arena already.
if (singletons.size() == 1)
return {singletons.front(), false, {}, {}};

return {ctx->arena->addType(UnionType{singletons}), false, {}, {}};
}

Expand Down
19 changes: 19 additions & 0 deletions tests/TypeFunction.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,25 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "keyof_type_function_works_with_metatables")
CHECK_EQ("\"w\" | \"x\" | \"y\" | \"z\"", toString(tpm->givenTp));
}

TEST_CASE_FIXTURE(BuiltinsFixture, "keyof_single_entry_no_uniontype")
{
if (!FFlag::LuauSolverV2)
return;

CheckResult result = check(R"(
local tbl_A = { abc = "value" }
local tbl_B = { a1 = nil, ["a2"] = nil }
type keyof_A = keyof<typeof(tbl_A)>
type keyof_B = keyof<typeof(tbl_B)>
)");

LUAU_REQUIRE_NO_ERRORS(result);

CHECK(toString(requireTypeAlias("keyof_A")) == "\"abc\"");
CHECK(toString(requireTypeAlias("keyof_B")) == "\"a1\" | \"a2\"");
}

TEST_CASE_FIXTURE(BuiltinsFixture, "keyof_type_function_errors_if_it_has_nontable_part")
{
if (!FFlag::LuauSolverV2)
Expand Down

0 comments on commit a8047b2

Please sign in to comment.