Fix crash with the index type function, where it would stack overflow due to not waiting for a pending-expansion (#1407)

Fix for https://github.com/luau-lang/luau/issues/1406

While it is good to let ``index`` wait for the pending-expansion. To
re-produce the issue you need more than just this code:
https://i.imgur.com/b3OmUGF.png

It needs this, else it won't crash.

```lua
local function ProblemCauser(key: Keys, value)
    PlayerData[key] = value
end
```

 

But regarding "pending things", I'd recommend **generalized functions**
for sanity checks like these, since there will be more cases of similar
issues I believe. But I am 100% sure that eventually this issue here can
maybe be prevented if looking at the Constraints. _(And optimization)_
Not sure if ``index`` needs the table fully completed, or if it is
preferred that the info is available based on **how much info is
available at the current position in the code**.

But if this gets done, I hope that they'll be connected to the Solver
Logger, because I actually refined mine with colors and more info _(yet
need to finish that)_ to understand the Luau Source Code more and to
debug issues.

---------

Co-authored-by: aaron <aweiss@hey.com>
This commit is contained in:
karl-police 2024-09-13 19:16:30 +02:00 committed by GitHub
parent 5cdea64b7a
commit f2488bdfa4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 0 deletions

View File

@ -2206,6 +2206,12 @@ TypeFunctionReductionResult<TypeId> indexFunctionImpl(
return {std::nullopt, true, {}, {}};
TypeId indexerTy = follow(typeParams.at(1));
if (isPending(indexerTy, ctx->solver))
{
return {std::nullopt, false, {indexerTy}, {}};
}
std::shared_ptr<const NormalizedType> indexerNormTy = ctx->normalizer->normalize(indexerTy);
// if the indexer failed to normalize, we can't reduce, but know nothing about inhabitance.

View File

@ -927,6 +927,32 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "index_type_function_works")
CHECK_EQ("string", toString(tpm->givenTp));
}
TEST_CASE_FIXTURE(BuiltinsFixture, "index_wait_for_pending_no_crash")
{
if (!FFlag::LuauSolverV2)
return;
CheckResult result = check(R"(
local PlayerData = {
Coins = 0,
Level = 1,
Exp = 0,
MaxExp = 100
}
type Keys = index<typeof(PlayerData), keyof<typeof(PlayerData)>>
-- This function makes it think that there's going to be a pending expansion
local function UpdateData(key: Keys, value)
PlayerData[key] = value
end
UpdateData("Coins", 2)
)");
// Should not crash!
}
TEST_CASE_FIXTURE(BuiltinsFixture, "index_type_function_works_w_array")
{
if (!FFlag::LuauSolverV2)