Skip to content

Commit b968ef7

Browse files
Vighnesh-Vhgoldsteinvrn-snayoungbloodrbxmenarulalam
authored
Sync to upstream/release/709 (luau-lang#2253)
We skipped the release last week, but we're back today with some new additions to the VM and Native Code Generation (and as always, improvements to typechecking). ## Analysis - Fixed some instances of "unreduced table types" like { x: number } | { x: number }, especially for data-like arrays (extremely large tables that have the same element of a given type). ```luau -- Prior, hovering would claim `t: {{number} | {number}}`, and now -- we will claim it is a `{{number}}` local t = { {1, 2, 3}, {4, 5, 6} } ``` - Fixed a bug where user defined type function could crash if passed too many arguments. - Enables autocomplete to use type information for function arguments to suggest results when those types are variadic. For example: ```luau local function foo(...: "Val1") end foo(@1) ``` will now suggest "Val1" - Partially annotated local statements with type packs on the right-hand-side (see example) are now correctly inferred. Prior, we mishandled this case in a way that caused subsequent assignments to assume the first element of the type pack corresponded to the first unannotated element: ```luau local function foo(): (number, boolean, string) return 1, true "three" end -- Prior to this fix, we inferred that `y: number` for this statement ... local x: number, y, z: string = foo() -- ... similarly, this would have inferred `z: number` ... local x: number, y: boolean, z = foo() -- ... and this would have inferred `y: number` and `z: boolean` local x: number, y, z = foo() ``` ## VM - Fix a use-after-free in `table.find`. ## Native Code Generation - Fix a bug in NCG caused by using an incorrect operand in a buffer length check. - NCG now unmaps executable pages when functions are garbage-collected. - Provide a native implementation for `math.isnan` --- Co-authored-by: Hunter Goldstein <hgoldstein@roblox.com> Co-authored-by: Ilya Rezvov <irezvov@roblox.com> Co-authored-by: Sora Kanosue <skanosue@roblox.com> Co-authored-by: Varun Saini <vsaini@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com> --------- Co-authored-by: Hunter Goldstein <hgoldstein@roblox.com> Co-authored-by: Varun Saini <61795485+vrn-sn@users.noreply.github.com> Co-authored-by: Alexander Youngblood <ayoungblood@roblox.com> Co-authored-by: Menarul Alam <malam@roblox.com> Co-authored-by: Aviral Goel <agoel@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com> Co-authored-by: Ariel Weiss <aaronweiss@roblox.com> Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Ilya Rezvov <irezvov@roblox.com> Co-authored-by: Ariel Weiss <arielweiss@roblox.com> Co-authored-by: Sora Kanosue <skanosue@roblox.com> Co-authored-by: Varun Saini <vsaini@roblox.com>
1 parent 54a2ea0 commit b968ef7

53 files changed

Lines changed: 1833 additions & 749 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Analysis/src/AutocompleteCore.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
LUAU_FASTINT(LuauTypeInferIterationLimit)
2727
LUAU_FASTINT(LuauTypeInferRecursionLimit)
2828
LUAU_FASTFLAGVARIABLE(DebugLuauMagicVariableNames)
29-
LUAU_FASTFLAGVARIABLE(LuauAutocompleteSingletonsInIndexer)
29+
LUAU_FASTFLAGVARIABLE(LuauAutocompleteFunctionCallArgTails)
3030

3131
static constexpr std::array<std::string_view, 12> kStatementStartingKeywords =
3232
{"while", "if", "local", "repeat", "function", "do", "for", "return", "break", "continue", "type", "export"};
@@ -141,6 +141,8 @@ static std::optional<TypeId> findExpectedTypeAt(const Module& module, AstNode* n
141141

142142
if (index < head.size())
143143
return head[index];
144+
else if (FFlag::LuauAutocompleteFunctionCallArgTails && index == head.size() && tail.has_value() && isVariadic(*tail))
145+
return first(*tail);
144146

145147
return std::nullopt;
146148
}
@@ -423,7 +425,7 @@ static void autocompleteProps(
423425
else if (auto tbl = get<TableType>(ty))
424426
{
425427
fillProps(tbl->props);
426-
if (FFlag::LuauAutocompleteSingletonsInIndexer && tbl->indexer && indexType == PropIndexType::Point)
428+
if (tbl->indexer && indexType == PropIndexType::Point)
427429
{
428430
auto indexerTy = follow(tbl->indexer->indexType);
429431
if (auto utv = get<UnionType>(indexerTy))

Analysis/src/BuiltinTypeFunctions.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ LUAU_DYNAMIC_FASTINTVARIABLE(LuauStepRefineRecursionLimit, 64)
2222

2323
LUAU_FASTFLAG(LuauInstantiationUsesGenericPolarity2)
2424
LUAU_FASTFLAGVARIABLE(LuauBuiltinTypeFunctionsUseNewOverloadResolution)
25-
LUAU_FASTFLAGVARIABLE(LuauSetmetatableWaitForPendingTypes)
2625
LUAU_FASTFLAGVARIABLE(LuauTypeFunctionsUseSolveFunctionCall)
2726

2827
namespace Luau
@@ -2431,11 +2430,8 @@ TypeFunctionReductionResult<TypeId> setmetatableTypeFunction(
24312430
TypeId targetTy = follow(typeParams.at(0));
24322431
TypeId metatableTy = follow(typeParams.at(1));
24332432

2434-
if (FFlag::LuauSetmetatableWaitForPendingTypes)
2435-
{
2436-
if (isPending(targetTy, ctx->solver))
2437-
return {std::nullopt, Reduction::MaybeOk, {targetTy}, {}};
2438-
}
2433+
if (isPending(targetTy, ctx->solver))
2434+
return {std::nullopt, Reduction::MaybeOk, {targetTy}, {}};
24392435

24402436
std::shared_ptr<const NormalizedType> targetNorm = ctx->normalizer->normalize(targetTy);
24412437

@@ -2453,11 +2449,8 @@ TypeFunctionReductionResult<TypeId> setmetatableTypeFunction(
24532449
targetNorm->hasExternTypes())
24542450
return {std::nullopt, Reduction::Erroneous, {}, {}};
24552451

2456-
if (FFlag::LuauSetmetatableWaitForPendingTypes)
2457-
{
2458-
if (isPending(metatableTy, ctx->solver))
2459-
return {std::nullopt, Reduction::MaybeOk, {metatableTy}, {}};
2460-
}
2452+
if (isPending(metatableTy, ctx->solver))
2453+
return {std::nullopt, Reduction::MaybeOk, {metatableTy}, {}};
24612454

24622455
// if the supposed metatable is not a table, we will fail to reduce.
24632456
if (!get<TableType>(metatableTy) && !get<MetatableType>(metatableTy))

Analysis/src/ConstraintGenerator.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ LUAU_FASTINTVARIABLE(LuauPrimitiveInferenceInTableLimit, 500)
4141
LUAU_FASTFLAG(LuauExplicitTypeInstantiationSyntax)
4242
LUAU_FASTFLAG(LuauExplicitTypeInstantiationSupport)
4343
LUAU_FASTFLAG(LuauPushTypeConstraintLambdas3)
44-
LUAU_FASTFLAGVARIABLE(LuauAvoidMintingMultipleBlockedTypesForGlobals)
4544
LUAU_FASTFLAGVARIABLE(LuauPropagateTypeAnnotationsInForInLoops)
4645
LUAU_FASTFLAGVARIABLE(LuauStorePolarityInline)
4746
LUAU_FASTFLAGVARIABLE(LuauDontIncludeVarargWithAnnotation)
4847
LUAU_FASTFLAGVARIABLE(LuauUdtfIndirectAliases)
4948
LUAU_FASTFLAGVARIABLE(LuauDisallowRedefiningBuiltinTypes)
49+
LUAU_FASTFLAGVARIABLE(LuauUnpackRespectsAnnotations)
5050

5151
namespace Luau
5252
{
@@ -1152,6 +1152,8 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatLocal* stat
11521152
std::vector<TypeId> deferredTypes;
11531153
auto [head, tail] = flatten(rvaluePack);
11541154

1155+
DenseHashSet<BlockedType*> freshBlockedTypes{nullptr};
1156+
11551157
for (size_t i = 0; i < statLocal->vars.size; ++i)
11561158
{
11571159
LUAU_ASSERT(get<BlockedType>(assignees[i]));
@@ -1161,6 +1163,8 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatLocal* stat
11611163
if (statLocal->vars.data[i]->annotation)
11621164
{
11631165
localDomain->insert(annotatedTypes[i]);
1166+
if (FFlag::LuauUnpackRespectsAnnotations && i >= head.size() && tail)
1167+
deferredTypes.emplace_back(annotatedTypes[i]);
11641168
}
11651169
else
11661170
{
@@ -1172,6 +1176,8 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatLocal* stat
11721176
{
11731177
deferredTypes.push_back(arena->addType(BlockedType{}));
11741178
localDomain->insert(deferredTypes.back());
1179+
if (FFlag::LuauUnpackRespectsAnnotations)
1180+
freshBlockedTypes.insert(getMutable<BlockedType>(deferredTypes.back()));
11751181
}
11761182
else
11771183
{
@@ -1201,8 +1207,19 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatLocal* stat
12011207
}
12021208
);
12031209

1204-
for (TypeId t : deferredTypes)
1205-
getMutable<BlockedType>(t)->setOwner(uc);
1210+
if (FFlag::LuauUnpackRespectsAnnotations)
1211+
{
1212+
// This is a separate set from `deferredTypes` to
1213+
// distinguish between blocked types we just minted
1214+
// and blocked types that correspond to annotations.
1215+
for (BlockedType* bt : freshBlockedTypes)
1216+
bt->setOwner(uc);
1217+
}
1218+
else
1219+
{
1220+
for (TypeId t : deferredTypes)
1221+
getMutable<BlockedType>(t)->setOwner(uc);
1222+
}
12061223
}
12071224

12081225
if (statLocal->vars.size == 1 && statLocal->values.size == 1 && firstValueType && scope.get() == rootScope && !hasAnnotation)
@@ -4507,7 +4524,7 @@ struct GlobalPrepopulator : AstVisitor
45074524
if (!globalScope->lookup(g->name))
45084525
globalScope->globalsToWarn.insert(g->name.value);
45094526

4510-
if (!FFlag::LuauAvoidMintingMultipleBlockedTypesForGlobals || globalScope->bindings.find(g->name) == globalScope->bindings.end())
4527+
if (globalScope->bindings.find(g->name) == globalScope->bindings.end())
45114528
{
45124529
TypeId bt = arena->addType(BlockedType{});
45134530
globalScope->bindings[g->name] = Binding{bt, g->location};

Analysis/src/ConstraintSolver.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ LUAU_FASTFLAGVARIABLE(LuauUseFastSubtypeForIndexerWithName)
5050
LUAU_FASTFLAGVARIABLE(LuauUnifyWithSubtyping2)
5151
LUAU_FASTFLAGVARIABLE(LuauDoNotUseApplyTypeFunctionToClone)
5252
LUAU_FASTFLAGVARIABLE(LuauReworkInfiniteTypeFinder)
53+
LUAU_FASTFLAG(LuauRelateHandlesCoincidentTables)
54+
LUAU_FASTFLAG(LuauUnpackRespectsAnnotations)
5355

5456
namespace Luau
5557
{
@@ -1016,6 +1018,9 @@ bool ConstraintSolver::tryDispatch(const GeneralizationConstraint& c, NotNull<co
10161018
}
10171019
else if (get<TableType>(ty))
10181020
sealTable(constraint->scope, ty);
1021+
1022+
if (FFlag::LuauRelateHandlesCoincidentTables)
1023+
unblock(ty, constraint->location);
10191024
}
10201025
}
10211026

@@ -2574,11 +2579,16 @@ bool ConstraintSolver::tryDispatch(const UnpackConstraint& c, NotNull<const Cons
25742579
TypeId srcTy = follow(srcPack.head[i]);
25752580
TypeId resultTy = follow(*resultIter);
25762581

2577-
LUAU_ASSERT(get<BlockedType>(resultTy));
2578-
LUAU_ASSERT(canMutate(resultTy, constraint));
2582+
if (!FFlag::LuauUnpackRespectsAnnotations)
2583+
{
2584+
LUAU_ASSERT(get<BlockedType>(resultTy));
2585+
LUAU_ASSERT(canMutate(resultTy, constraint));
2586+
}
25792587

25802588
if (get<BlockedType>(resultTy))
25812589
{
2590+
if (FFlag::LuauUnpackRespectsAnnotations)
2591+
LUAU_ASSERT(canMutate(resultTy, constraint));
25822592
if (follow(srcTy) == resultTy)
25832593
{
25842594
// It is sometimes the case that we find that a blocked type
@@ -2765,6 +2775,15 @@ struct FindAllUnionMembers : TypeOnceVisitor
27652775
{
27662776
return true;
27672777
}
2778+
2779+
bool visit(TypeId ty, const TableType& tbl) override
2780+
{
2781+
if (FFlag::LuauRelateHandlesCoincidentTables && tbl.state != TableState::Sealed)
2782+
blockedTys.insert(ty);
2783+
else
2784+
recordedTys.insert(ty);
2785+
return false;
2786+
}
27682787
};
27692788

27702789
bool ConstraintSolver::tryDispatch(const SimplifyConstraint& c, NotNull<const Constraint> constraint, bool force)

Analysis/src/EmbeddedBuiltinDefinitions.cpp

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
22
#include "Luau/BuiltinDefinitions.h"
33

4-
LUAU_FASTFLAGVARIABLE(LuauUseTopTableForTableClearAndIsFrozen)
54
LUAU_FASTFLAGVARIABLE(LuauTypeCheckerUdtfRenameClassToExtern)
65
LUAU_FASTFLAGVARIABLE(LuauMorePermissiveNewtableType)
76

@@ -184,31 +183,6 @@ declare coroutine: {
184183
close: @checked (co: thread) -> (boolean, any)
185184
}
186185
187-
)BUILTIN_SRC";
188-
static constexpr const char* kBuiltinDefinitionTableSrc_DEPRECATED = R"BUILTIN_SRC(
189-
190-
declare table: {
191-
concat: <V>(t: {V}, sep: string?, i: number?, j: number?) -> string,
192-
insert: (<V>(t: {V}, value: V) -> ()) & (<V>(t: {V}, pos: number, value: V) -> ()),
193-
maxn: <V>(t: {V}) -> number,
194-
remove: <V>(t: {V}, number?) -> V?,
195-
sort: <V>(t: {V}, comp: ((V, V) -> boolean)?) -> (),
196-
create: <V>(count: number, value: V?) -> {V},
197-
find: <V>(haystack: {V}, needle: V, init: number?) -> number?,
198-
199-
unpack: <V>(list: {V}, i: number?, j: number?) -> ...V,
200-
pack: <V>(...V) -> { n: number, [number]: V },
201-
202-
getn: <V>(t: {V}) -> number,
203-
foreach: <K, V>(t: {[K]: V}, f: (K, V) -> ()) -> (),
204-
foreachi: <V>({V}, (number, V) -> ()) -> (),
205-
206-
move: <V>(src: {V}, a: number, b: number, t: number, dst: {V}?) -> {V},
207-
clear: <K, V>(table: {[K]: V}) -> (),
208-
209-
isfrozen: <K, V>(t: {[K]: V}) -> boolean,
210-
}
211-
212186
)BUILTIN_SRC";
213187

214188
static constexpr const char* kBuiltinDefinitionTableSrc = R"BUILTIN_SRC(
@@ -331,14 +305,7 @@ std::string getBuiltinDefinitionSource()
331305
result += kBuiltinDefinitionMathSrc;
332306
result += kBuiltinDefinitionOsSrc;
333307
result += kBuiltinDefinitionCoroutineSrc;
334-
if (FFlag::LuauUseTopTableForTableClearAndIsFrozen)
335-
{
336-
result += kBuiltinDefinitionTableSrc;
337-
}
338-
else
339-
{
340-
result += kBuiltinDefinitionTableSrc_DEPRECATED;
341-
}
308+
result += kBuiltinDefinitionTableSrc;
342309
result += kBuiltinDefinitionDebugSrc;
343310
result += kBuiltinDefinitionUtf8Src;
344311
result += kBuiltinDefinitionBufferSrc;

0 commit comments

Comments
 (0)