Skip to content

Commit ae59a0e

Browse files
menarulalamhgoldsteinvrn-snayoungbloodrbxAviral Goel
authored
Sync to upstream/release/691 (#1998)
# New Type Solver * Fixed #1983 by adding additional context to permit some expressions otherwise not allowed * We now skip issuing CheckedFunctionWarnings on use of unreduced type functions * Fix gcc compile error * Handle expressions `a == b` and `a ~= b` more efficiently * Subtyping now correctly handles generics over unions and intersections in cases such as ``` local function a<T>(arr: { T }) end a({ 'one', 'two' }) ``` * Rearrange unification cases to avoid free type generalization to never * Improve generic bounds mismatch error message * Fix Ancestry bug in visitor for incomplete repeat blocks such as ``` local t = {} function t:Foo() end repeat t:| ``` * Support autocomplete for attributes # Native Codegen * Unwind info has support on Android * Introduced a separate ctypeof function which does not constant-fold for vector arguments. * We now perform string concatenation at compile time if possible (there is a known issue with the optimization that we will address next week) * Make vector.lerp and math.lerp more efficient with FMA * Record STORE_SPLIT_TVALUE as a potential restore operation to reduce number of spills to stack * When native execution is disabled, we now mark the call frame as not executing natively, making resumption safer --- Co-authored-by: Andy Friesen <[email protected]> Co-authored-by: Annie Tang <[email protected]> Co-authored-by: Hunter Goldstein <[email protected]> Co-authored-by: Ilya Rezvov <[email protected]> Co-authored-by: Sora Kanosue <[email protected]> Co-authored-by: Varun Saini <[email protected]> Co-authored-by: Vighnesh Vijay <[email protected]> Co-authored-by: Vyacheslav Egorov <[email protected]> --------- Co-authored-by: Hunter Goldstein <[email protected]> Co-authored-by: Varun Saini <[email protected]> Co-authored-by: Alexander Youngblood <[email protected]> Co-authored-by: Aviral Goel <[email protected]> Co-authored-by: Vighnesh <[email protected]> Co-authored-by: Vyacheslav Egorov <[email protected]> Co-authored-by: Ariel Weiss <[email protected]> Co-authored-by: Andy Friesen <[email protected]>
1 parent 5059095 commit ae59a0e

File tree

101 files changed

+2133
-2387
lines changed

Some content is hidden

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

101 files changed

+2133
-2387
lines changed

Analysis/include/Luau/ConstraintSolver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ struct ConstraintSolver
178178
ConstraintSet constraintSet
179179
);
180180

181+
// TODO CLI-169086: Replace all uses of this constructor with the ConstraintSet constructor, above.
181182
explicit ConstraintSolver(
182183
NotNull<Normalizer> normalizer,
183184
NotNull<Simplifier> simplifier,

Analysis/include/Luau/Error.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ struct CannotExtendTable
8787
bool operator==(const CannotExtendTable& rhs) const;
8888
};
8989

90+
struct CannotCompareUnrelatedTypes
91+
{
92+
TypeId left;
93+
TypeId right;
94+
AstExprBinary::Op op;
95+
96+
bool operator==(const CannotCompareUnrelatedTypes& rhs) const;
97+
};
98+
9099
struct OnlyTablesCanHaveMethods
91100
{
92101
TypeId tableType;
@@ -547,6 +556,7 @@ using TypeErrorData = Variant<
547556
UnknownProperty,
548557
NotATable,
549558
CannotExtendTable,
559+
CannotCompareUnrelatedTypes,
550560
OnlyTablesCanHaveMethods,
551561
DuplicateTypeDefinition,
552562
CountMismatch,

Analysis/include/Luau/IostreamHelpers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ std::ostream& operator<<(std::ostream& lhs, const UnknownSymbol& error);
2222
std::ostream& operator<<(std::ostream& lhs, const UnknownProperty& error);
2323
std::ostream& operator<<(std::ostream& lhs, const NotATable& error);
2424
std::ostream& operator<<(std::ostream& lhs, const CannotExtendTable& error);
25+
std::ostream& operator<<(std::ostream& lhs, const CannotCompareUnrelatedTypes& error);
2526
std::ostream& operator<<(std::ostream& lhs, const OnlyTablesCanHaveMethods& error);
2627
std::ostream& operator<<(std::ostream& lhs, const DuplicateTypeDefinition& error);
2728
std::ostream& operator<<(std::ostream& lhs, const CountMismatch& error);

Analysis/include/Luau/Normalize.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@ struct NormalizedType
281281
/// Returns true if this type contains the primitve top table type, `table`.
282282
bool hasTopTable() const;
283283

284+
/// Returns true if this type is `nil` or `nil | *error-type*`
285+
bool isNil() const;
286+
284287
// Helpers that improve readability of the above (they just say if the component is present)
285288
bool hasTops() const;
286289
bool hasBooleans() const;

Analysis/include/Luau/VisitType.h

Lines changed: 25 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
#include "Type.h"
1111

1212
LUAU_FASTINT(LuauVisitRecursionLimit)
13-
LUAU_FASTFLAG(LuauSolverV2)
14-
LUAU_FASTFLAG(LuauSolverAgnosticVisitType)
1513
LUAU_FASTFLAG(LuauReduceSetTypeStackPressure)
1614

1715
namespace Luau
@@ -261,37 +259,16 @@ struct GenericTypeVisitor
261259
}
262260
else if (auto ftv = get<FreeType>(ty))
263261
{
264-
if (FFlag::LuauSolverAgnosticVisitType)
262+
if (visit(ty, *ftv))
265263
{
266-
if (visit(ty, *ftv))
267-
{
268-
// Regardless of the choice of solver, all free types are guaranteed to have
269-
// lower and upper bounds
270-
LUAU_ASSERT(ftv->lowerBound);
271-
LUAU_ASSERT(ftv->upperBound);
264+
// Regardless of the choice of solver, all free types are guaranteed to have
265+
// lower and upper bounds
266+
LUAU_ASSERT(ftv->lowerBound);
267+
LUAU_ASSERT(ftv->upperBound);
272268

273-
traverse(ftv->lowerBound);
274-
traverse(ftv->upperBound);
275-
}
276-
}
277-
else if (FFlag::LuauSolverV2)
278-
{
279-
if (visit(ty, *ftv))
280-
{
281-
// TODO: Replace these if statements with assert()s when we
282-
// delete FFlag::LuauSolverV2.
283-
//
284-
// When the old solver is used, these pointers are always
285-
// unused. When the new solver is used, they are never null.
286-
if (ftv->lowerBound)
287-
traverse(ftv->lowerBound);
288-
289-
if (ftv->upperBound)
290-
traverse(ftv->upperBound);
291-
}
269+
traverse(ftv->lowerBound);
270+
traverse(ftv->upperBound);
292271
}
293-
else
294-
visit(ty, *ftv);
295272
}
296273
else if (auto gtv = get<GenericType>(ty))
297274
visit(ty, *gtv);
@@ -324,20 +301,15 @@ struct GenericTypeVisitor
324301
{
325302
for (auto& [_name, prop] : ttv->props)
326303
{
327-
if (FFlag::LuauSolverV2 || FFlag::LuauSolverAgnosticVisitType)
328-
{
329-
if (auto ty = prop.readTy)
330-
traverse(*ty);
331-
332-
// In the case that the readType and the writeType
333-
// are the same pointer, just traverse once.
334-
// Traversing each property twice has pretty
335-
// significant performance consequences.
336-
if (auto ty = prop.writeTy; ty && !prop.isShared())
337-
traverse(*ty);
338-
}
339-
else
340-
traverse(prop.type_DEPRECATED());
304+
if (auto ty = prop.readTy)
305+
traverse(*ty);
306+
307+
// In the case that the readType and the writeType
308+
// are the same pointer, just traverse once.
309+
// Traversing each property twice has pretty
310+
// significant performance consequences.
311+
if (auto ty = prop.writeTy; ty && !prop.isShared())
312+
traverse(*ty);
341313
}
342314

343315
if (ttv->indexer)
@@ -362,20 +334,15 @@ struct GenericTypeVisitor
362334
{
363335
for (const auto& [name, prop] : etv->props)
364336
{
365-
if (FFlag::LuauSolverV2 || FFlag::LuauSolverAgnosticVisitType)
366-
{
367-
if (auto ty = prop.readTy)
368-
traverse(*ty);
369-
370-
// In the case that the readType and the writeType are
371-
// the same pointer, just traverse once. Traversing each
372-
// property twice would have pretty significant
373-
// performance consequences.
374-
if (auto ty = prop.writeTy; ty && !prop.isShared())
375-
traverse(*ty);
376-
}
377-
else
378-
traverse(prop.type_DEPRECATED());
337+
if (auto ty = prop.readTy)
338+
traverse(*ty);
339+
340+
// In the case that the readType and the writeType are
341+
// the same pointer, just traverse once. Traversing each
342+
// property twice would have pretty significant
343+
// performance consequences.
344+
if (auto ty = prop.writeTy; ty && !prop.isShared())
345+
traverse(*ty);
379346
}
380347

381348
if (etv->parent)

Analysis/src/AstJsonEncoder.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include <math.h>
1010

11+
LUAU_FASTFLAG(LuauAutocompleteAttributes)
12+
1113
namespace Luau
1214
{
1315

@@ -1153,6 +1155,8 @@ struct AstJsonEncoder : public AstVisitor
11531155
return writeString("native");
11541156
case AstAttr::Type::Deprecated:
11551157
return writeString("deprecated");
1158+
case AstAttr::Type::Unknown:
1159+
return writeString("unknown");
11561160
}
11571161
}
11581162

@@ -1163,7 +1167,10 @@ struct AstJsonEncoder : public AstVisitor
11631167
"AstAttr",
11641168
[&]()
11651169
{
1166-
write("name", node->type);
1170+
if (FFlag::LuauAutocompleteAttributes)
1171+
write("name", node->name);
1172+
else
1173+
write("name", node->type);
11671174
}
11681175
);
11691176
}

Analysis/src/AstQuery.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <algorithm>
1313

1414
LUAU_FASTFLAG(LuauSolverV2)
15+
LUAU_FASTFLAGVARIABLE(LuauUnfinishedRepeatAncestryFix)
1516

1617
namespace Luau
1718
{
@@ -31,10 +32,22 @@ struct AutocompleteNodeFinder : public AstVisitor
3132

3233
bool visit(AstExpr* expr) override
3334
{
34-
if (expr->location.begin <= pos && pos <= expr->location.end)
35+
if (FFlag::LuauUnfinishedRepeatAncestryFix)
3536
{
36-
ancestry.push_back(expr);
37-
return true;
37+
// If the expression size is 0 (begin == end), we don't want to include it in the ancestry
38+
if (expr->location.begin <= pos && pos <= expr->location.end && expr->location.begin != expr->location.end)
39+
{
40+
ancestry.push_back(expr);
41+
return true;
42+
}
43+
}
44+
else
45+
{
46+
if (expr->location.begin <= pos && pos <= expr->location.end)
47+
{
48+
ancestry.push_back(expr);
49+
return true;
50+
}
3851
}
3952
return false;
4053
}

Analysis/src/AutocompleteCore.cpp

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,17 @@ LUAU_FASTFLAG(LuauSolverV2)
2727
LUAU_FASTINT(LuauTypeInferIterationLimit)
2828
LUAU_FASTINT(LuauTypeInferRecursionLimit)
2929
LUAU_FASTFLAGVARIABLE(DebugLuauMagicVariableNames)
30-
LUAU_FASTFLAG(LuauImplicitTableIndexerKeys3)
3130
LUAU_FASTFLAGVARIABLE(LuauIncludeBreakContinueStatements)
3231
LUAU_FASTFLAGVARIABLE(LuauSuggestHotComments)
32+
LUAU_FASTFLAG(LuauAutocompleteAttributes)
3333

3434
static constexpr std::array<std::string_view, 12> kStatementStartingKeywords =
3535
{"while", "if", "local", "repeat", "function", "do", "for", "return", "break", "continue", "type", "export"};
3636

3737
static constexpr std::array<std::string_view, 6> kHotComments = {"nolint", "nocheck", "nonstrict", "strict", "optimize", "native"};
3838

39+
static const std::string kKnownAttributes[] = {"checked", "deprecated", "native"};
40+
3941
namespace Luau
4042
{
4143

@@ -582,39 +584,21 @@ static void autocompleteStringSingleton(TypeId ty, bool addQuotes, AstNode* node
582584

583585
ty = follow(ty);
584586

585-
if (FFlag::LuauImplicitTableIndexerKeys3)
587+
if (auto ss = get<StringSingleton>(get<SingletonType>(ty)))
586588
{
587-
if (auto ss = get<StringSingleton>(get<SingletonType>(ty)))
588-
{
589-
// This is purposefully `try_emplace` as we don't want to override any existing entries.
590-
result.try_emplace(formatKey(ss->value), AutocompleteEntry{AutocompleteEntryKind::String, ty, false, false, TypeCorrectKind::Correct});
591-
}
592-
else if (auto uty = get<UnionType>(ty))
593-
{
594-
for (auto el : uty)
595-
{
596-
if (auto ss = get<StringSingleton>(get<SingletonType>(el)))
597-
{
598-
// This is purposefully `try_emplace` as we don't want to override any existing entries.
599-
result.try_emplace(
600-
formatKey(ss->value), AutocompleteEntry{AutocompleteEntryKind::String, ty, false, false, TypeCorrectKind::Correct}
601-
);
602-
}
603-
}
604-
}
589+
// This is purposefully `try_emplace` as we don't want to override any existing entries.
590+
result.try_emplace(formatKey(ss->value), AutocompleteEntry{AutocompleteEntryKind::String, ty, false, false, TypeCorrectKind::Correct});
605591
}
606-
else
592+
else if (auto uty = get<UnionType>(ty))
607593
{
608-
if (auto ss = get<StringSingleton>(get<SingletonType>(ty)))
594+
for (auto el : uty)
609595
{
610-
result[formatKey(ss->value)] = AutocompleteEntry{AutocompleteEntryKind::String, ty, false, false, TypeCorrectKind::Correct};
611-
}
612-
else if (auto uty = get<UnionType>(ty))
613-
{
614-
for (auto el : uty)
596+
if (auto ss = get<StringSingleton>(get<SingletonType>(el)))
615597
{
616-
if (auto ss = get<StringSingleton>(get<SingletonType>(el)))
617-
result[formatKey(ss->value)] = AutocompleteEntry{AutocompleteEntryKind::String, ty, false, false, TypeCorrectKind::Correct};
598+
// This is purposefully `try_emplace` as we don't want to override any existing entries.
599+
result.try_emplace(
600+
formatKey(ss->value), AutocompleteEntry{AutocompleteEntryKind::String, ty, false, false, TypeCorrectKind::Correct}
601+
);
618602
}
619603
}
620604
}
@@ -2105,12 +2089,6 @@ AutocompleteResult autocomplete_(
21052089
{
21062090
AutocompleteEntryMap result;
21072091

2108-
if (!FFlag::LuauImplicitTableIndexerKeys3)
2109-
{
2110-
if (auto it = module->astExpectedTypes.find(node->asExpr()))
2111-
autocompleteStringSingleton(*it, false, node, position, result);
2112-
}
2113-
21142092
if (ancestry.size() >= 2)
21152093
{
21162094
if (auto idxExpr = ancestry.at(ancestry.size() - 2)->as<AstExprIndexExpr>())
@@ -2128,11 +2106,8 @@ AutocompleteResult autocomplete_(
21282106
}
21292107
}
21302108

2131-
if (FFlag::LuauImplicitTableIndexerKeys3)
2132-
{
2133-
if (auto it = module->astExpectedTypes.find(node->asExpr()))
2134-
autocompleteStringSingleton(*it, false, node, position, result);
2135-
}
2109+
if (auto it = module->astExpectedTypes.find(node->asExpr()))
2110+
autocompleteStringSingleton(*it, false, node, position, result);
21362111

21372112
return {std::move(result), ancestry, AutocompleteContext::String};
21382113
}
@@ -2143,6 +2118,22 @@ AutocompleteResult autocomplete_(
21432118
AutocompleteEntryMap map;
21442119
return {std::move(map), ancestry, AutocompleteContext::String};
21452120
}
2121+
else if (AstExprFunction* func = node->as<AstExprFunction>())
2122+
{
2123+
if (FFlag::LuauAutocompleteAttributes)
2124+
{
2125+
for (AstAttr* attr : func->attributes)
2126+
{
2127+
if (attr->location.begin <= position && position <= attr->location.end && attr->type == AstAttr::Type::Unknown)
2128+
{
2129+
AutocompleteEntryMap ret;
2130+
for (const auto& attr : kKnownAttributes)
2131+
ret[attr.c_str()] = {AutocompleteEntryKind::Keyword};
2132+
return {std::move(ret), std::move(ancestry), AutocompleteContext::Keyword};
2133+
}
2134+
}
2135+
}
2136+
}
21462137

21472138
if (node->is<AstExprConstantNumber>())
21482139
return {};

Analysis/src/BuiltinDefinitions.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
*/
3333

3434
LUAU_FASTFLAG(LuauSolverV2)
35-
LUAU_FASTFLAG(LuauEagerGeneralization4)
3635
LUAU_FASTFLAGVARIABLE(LuauTableCloneClonesType3)
3736
LUAU_FASTFLAG(LuauUseWorkspacePropToChooseSolver)
3837
LUAU_FASTFLAG(LuauEmplaceNotPushBack)
@@ -367,9 +366,7 @@ void registerBuiltinGlobals(Frontend& frontend, GlobalTypes& globals, bool typeC
367366

368367
TypeArena& arena = globals.globalTypes;
369368
NotNull<BuiltinTypes> builtinTypes = globals.builtinTypes;
370-
Scope* globalScope = nullptr; // NotNull<Scope> when removing FFlag::LuauEagerGeneralization4
371-
if (FFlag::LuauEagerGeneralization4)
372-
globalScope = globals.globalScope.get();
369+
NotNull<Scope> globalScope{globals.globalScope.get()};
373370

374371
if (frontend.getLuauSolverMode() == SolverMode::New)
375372
builtinTypeFunctions().addToScope(NotNull{&arena}, NotNull{globals.globalScope.get()});
@@ -513,12 +510,10 @@ void registerBuiltinGlobals(Frontend& frontend, GlobalTypes& globals, bool typeC
513510
TypePackId thePack = arena.addTypePack({genericTy});
514511
TypeId idTyWithMagic = arena.addType(FunctionType{{genericTy}, {}, thePack, thePack});
515512
ttv->props["freeze"] = makeProperty(idTyWithMagic, "@luau/global/table.freeze");
516-
if (globalScope)
517-
inferGenericPolarities(NotNull{&globals.globalTypes}, NotNull{globalScope}, idTyWithMagic);
513+
inferGenericPolarities(NotNull{&globals.globalTypes}, NotNull{globalScope}, idTyWithMagic);
518514

519515
TypeId idTy = arena.addType(FunctionType{{genericTy}, {}, thePack, thePack});
520-
if (globalScope)
521-
inferGenericPolarities(NotNull{&globals.globalTypes}, NotNull{globalScope}, idTy);
516+
inferGenericPolarities(NotNull{&globals.globalTypes}, NotNull{globalScope}, idTy);
522517
ttv->props["clone"] = makeProperty(idTy, "@luau/global/table.clone");
523518
}
524519
else

0 commit comments

Comments
 (0)