Skip to content

Commit d0250a8

Browse files
authored
Sync Luau to 663 release. (luau-lang#100)
This sync is the last one that will be painful since we are now able to use a totally unmodified upstream Luau after the 663 release exposed `parseExpr`. It should be possible to `git subrepo pull extern/luau` in the future without issue.
1 parent 9d955d9 commit d0250a8

Some content is hidden

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

66 files changed

+944
-1099
lines changed

extern/luau/.gitrepo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[subrepo]
77
remote = [email protected]:luau-lang/luau.git
88
branch = master
9-
commit = c1e2f650dbd8c1080a3c5614d02adc5b75254c4e
10-
parent = 4045f931959bfa871429a6c0878599c745229b48
9+
commit = 640ebbc0a51bef0daa7c9b8c943d522dacb6a9a8
10+
parent = df1e96a1741709ff2795a1dd27b997aff7af56e7
1111
method = merge
1212
cmdver = 0.4.9

extern/luau/Analysis/include/Luau/ConstraintGenerator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ struct ConstraintGenerator
9696
// will enqueue them during solving.
9797
std::vector<ConstraintPtr> unqueuedConstraints;
9898

99+
// Map a function's signature scope back to its signature type.
100+
DenseHashMap<Scope*, TypeId> scopeToFunction{nullptr};
101+
99102
// The private scope of type aliases for which the type parameters belong to.
100103
DenseHashMap<const AstStatTypeAlias*, ScopePtr> astTypeAliasDefiningScopes{nullptr};
101104

extern/luau/Analysis/include/Luau/ConstraintSolver.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct ConstraintSolver
8888
NotNull<TypeFunctionRuntime> typeFunctionRuntime;
8989
// The entire set of constraints that the solver is trying to resolve.
9090
std::vector<NotNull<Constraint>> constraints;
91+
NotNull<DenseHashMap<Scope*, TypeId>> scopeToFunction;
9192
NotNull<Scope> rootScope;
9293
ModuleName currentModuleName;
9394

@@ -119,6 +120,7 @@ struct ConstraintSolver
119120
DenseHashMap<TypeId, size_t> unresolvedConstraints{{}};
120121

121122
std::unordered_map<NotNull<const Constraint>, DenseHashSet<TypeId>> maybeMutatedFreeTypes;
123+
std::unordered_map<TypeId, DenseHashSet<const Constraint*>> mutatedFreeTypeToConstraint;
122124

123125
// Irreducible/uninhabited type functions or type pack functions.
124126
DenseHashSet<const void*> uninhabitedTypeFunctions{{}};
@@ -144,6 +146,7 @@ struct ConstraintSolver
144146
NotNull<TypeFunctionRuntime> typeFunctionRuntime,
145147
NotNull<Scope> rootScope,
146148
std::vector<NotNull<Constraint>> constraints,
149+
NotNull<DenseHashMap<Scope*, TypeId>> scopeToFunction,
147150
ModuleName moduleName,
148151
NotNull<ModuleResolver> moduleResolver,
149152
std::vector<RequireCycle> requireCycles,
@@ -171,6 +174,8 @@ struct ConstraintSolver
171174
bool isDone() const;
172175

173176
private:
177+
void generalizeOneType(TypeId ty);
178+
174179
/**
175180
* Bind a type variable to another type.
176181
*

extern/luau/Analysis/include/Luau/FragmentAutocomplete.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,65 @@ FragmentAutocompleteResult fragmentAutocomplete(
8282
std::optional<Position> fragmentEndPosition = std::nullopt
8383
);
8484

85+
enum class FragmentAutocompleteStatus
86+
{
87+
Success,
88+
FragmentTypeCheckFail,
89+
InternalIce
90+
};
91+
92+
struct FragmentAutocompleteStatusResult
93+
{
94+
FragmentAutocompleteStatus status;
95+
std::optional<FragmentAutocompleteResult> result;
96+
};
97+
98+
struct FragmentContext
99+
{
100+
std::string_view newSrc;
101+
const ParseResult& newAstRoot;
102+
std::optional<FrontendOptions> opts;
103+
std::optional<Position> DEPRECATED_fragmentEndPosition;
104+
};
105+
106+
/**
107+
* @brief Attempts to compute autocomplete suggestions from the fragment context.
108+
*
109+
* This function computes autocomplete suggestions using outdated frontend typechecking data
110+
* by patching the fragment context of the new script source content.
111+
*
112+
* @param frontend The Luau Frontend data structure, which may contain outdated typechecking data.
113+
*
114+
* @param moduleName The name of the target module, specifying which script the caller wants to request autocomplete for.
115+
*
116+
* @param cursorPosition The position in the script where the caller wants to trigger autocomplete.
117+
*
118+
* @param context The fragment context that this API will use to patch the outdated typechecking data.
119+
*
120+
* @param stringCompletionCB A callback function that provides autocomplete suggestions for string contexts.
121+
*
122+
* @return
123+
* The status indicating whether `fragmentAutocomplete` ran successfully or failed, along with the reason for failure.
124+
* Also includes autocomplete suggestions if the status is successful.
125+
*
126+
* @usage
127+
* FragmentAutocompleteStatusResult acStatusResult;
128+
* if (shouldFragmentAC)
129+
* acStatusResult = Luau::tryFragmentAutocomplete(...);
130+
*
131+
* if (acStatusResult.status != Successful)
132+
* {
133+
* frontend.check(moduleName, options);
134+
* acStatusResult.acResult = Luau::autocomplete(...);
135+
* }
136+
* return convertResultWithContext(acStatusResult.acResult);
137+
*/
138+
FragmentAutocompleteStatusResult tryFragmentAutocomplete(
139+
Frontend& frontend,
140+
const ModuleName& moduleName,
141+
Position cursorPosition,
142+
FragmentContext context,
143+
StringCompletionCallback stringCompletionCB
144+
);
85145

86146
} // namespace Luau

extern/luau/Analysis/include/Luau/TableLiteralInference.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "Luau/NotNull.h"
77
#include "Luau/TypeFwd.h"
88

9+
#include <vector>
10+
911
namespace Luau
1012
{
1113

extern/luau/Analysis/include/Luau/TxnLog.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,10 @@ T* getMutable(PendingTypePack* pending)
6565
// Log of what TypeIds we are rebinding, to be committed later.
6666
struct TxnLog
6767
{
68-
explicit TxnLog(bool useScopes = false)
68+
explicit TxnLog()
6969
: typeVarChanges(nullptr)
7070
, typePackChanges(nullptr)
7171
, ownedSeen()
72-
, useScopes(useScopes)
7372
, sharedSeen(&ownedSeen)
7473
{
7574
}

extern/luau/Analysis/include/Luau/TypeFunctionRuntime.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,11 @@ struct TypeFunctionClassType
216216

217217
std::optional<TypeFunctionTypeId> metatable; // metaclass?
218218

219-
std::optional<TypeFunctionTypeId> parent;
219+
// this was mistaken, and we should actually be keeping separate read/write types here.
220+
std::optional<TypeFunctionTypeId> parent_DEPRECATED;
221+
222+
std::optional<TypeFunctionTypeId> readParent;
223+
std::optional<TypeFunctionTypeId> writeParent;
220224

221225
TypeId classTy;
222226

extern/luau/Analysis/include/Luau/Unifier.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,6 @@ struct Unifier
9393

9494
Unifier(NotNull<Normalizer> normalizer, NotNull<Scope> scope, const Location& location, Variance variance, TxnLog* parentLog = nullptr);
9595

96-
// Configure the Unifier to test for scope subsumption via embedded Scope
97-
// pointers rather than TypeLevels.
98-
void enableNewSolver();
99-
10096
// Test whether the two type vars unify. Never commits the result.
10197
ErrorVec canUnify(TypeId subTy, TypeId superTy);
10298
ErrorVec canUnify(TypePackId subTy, TypePackId superTy, bool isFunctionCall = false);
@@ -169,7 +165,6 @@ struct Unifier
169165

170166
std::optional<TypeId> findTablePropertyRespectingMeta(TypeId lhsType, Name name);
171167

172-
TxnLog combineLogsIntoIntersection(std::vector<TxnLog> logs);
173168
TxnLog combineLogsIntoUnion(std::vector<TxnLog> logs);
174169

175170
public:
@@ -195,11 +190,6 @@ struct Unifier
195190

196191
// Available after regular type pack unification errors
197192
std::optional<int> firstPackErrorPos;
198-
199-
// If true, we do a bunch of small things differently to work better with
200-
// the new type inference engine. Most notably, we use the Scope hierarchy
201-
// directly rather than using TypeLevels.
202-
bool useNewSolver = false;
203193
};
204194

205195
void promoteTypeLevels(TxnLog& log, const TypeArena* arena, TypeLevel minLevel, Scope* outerScope, bool useScope, TypePackId tp);

extern/luau/Analysis/src/Autocomplete.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "Luau/Autocomplete.h"
33

44
#include "Luau/AstQuery.h"
5+
#include "Luau/TimeTrace.h"
56
#include "Luau/TypeArena.h"
67
#include "Luau/Module.h"
78
#include "Luau/Frontend.h"
@@ -15,6 +16,9 @@ namespace Luau
1516

1617
AutocompleteResult autocomplete(Frontend& frontend, const ModuleName& moduleName, Position position, StringCompletionCallback callback)
1718
{
19+
LUAU_TIMETRACE_SCOPE("Luau::autocomplete", "Autocomplete");
20+
LUAU_TIMETRACE_ARGUMENT("name", moduleName.c_str());
21+
1822
const SourceModule* sourceModule = frontend.getSourceModule(moduleName);
1923
if (!sourceModule)
2024
return {};

extern/luau/Analysis/src/AutocompleteCore.cpp

Lines changed: 75 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "Luau/Common.h"
1111
#include "Luau/FileResolver.h"
1212
#include "Luau/Frontend.h"
13+
#include "Luau/TimeTrace.h"
1314
#include "Luau/ToString.h"
1415
#include "Luau/Subtyping.h"
1516
#include "Luau/TypeInfer.h"
@@ -24,7 +25,8 @@ LUAU_FASTINT(LuauTypeInferIterationLimit)
2425
LUAU_FASTINT(LuauTypeInferRecursionLimit)
2526

2627
LUAU_FASTFLAGVARIABLE(LuauAutocompleteRefactorsForIncrementalAutocomplete)
27-
LUAU_FASTFLAGVARIABLE(LuauAutocompleteUseLimits)
28+
29+
LUAU_FASTFLAGVARIABLE(LuauAutocompleteUsesModuleForTypeCompatibility)
2830

2931
static const std::unordered_set<std::string> kStatementStartingKeywords =
3032
{"while", "if", "local", "repeat", "function", "do", "for", "return", "break", "continue", "type", "export"};
@@ -146,44 +148,91 @@ static std::optional<TypeId> findExpectedTypeAt(const Module& module, AstNode* n
146148
return *it;
147149
}
148150

149-
static bool checkTypeMatch(TypeId subTy, TypeId superTy, NotNull<Scope> scope, TypeArena* typeArena, NotNull<BuiltinTypes> builtinTypes)
151+
static bool checkTypeMatch(
152+
const Module& module,
153+
TypeId subTy,
154+
TypeId superTy,
155+
NotNull<Scope> scope,
156+
TypeArena* typeArena,
157+
NotNull<BuiltinTypes> builtinTypes
158+
)
150159
{
151160
InternalErrorReporter iceReporter;
152161
UnifierSharedState unifierState(&iceReporter);
153162
SimplifierPtr simplifier = newSimplifier(NotNull{typeArena}, builtinTypes);
154163
Normalizer normalizer{typeArena, builtinTypes, NotNull{&unifierState}};
155-
156-
if (FFlag::LuauSolverV2)
164+
if (FFlag::LuauAutocompleteUsesModuleForTypeCompatibility)
157165
{
158-
TypeCheckLimits limits;
159-
TypeFunctionRuntime typeFunctionRuntime{
160-
NotNull{&iceReporter}, NotNull{&limits}
161-
}; // TODO: maybe subtyping checks should not invoke user-defined type function runtime
166+
if (module.checkedInNewSolver)
167+
{
168+
TypeCheckLimits limits;
169+
TypeFunctionRuntime typeFunctionRuntime{
170+
NotNull{&iceReporter}, NotNull{&limits}
171+
}; // TODO: maybe subtyping checks should not invoke user-defined type function runtime
172+
173+
unifierState.counters.recursionLimit = FInt::LuauTypeInferRecursionLimit;
174+
unifierState.counters.iterationLimit = FInt::LuauTypeInferIterationLimit;
162175

163-
unifierState.counters.recursionLimit = FInt::LuauTypeInferRecursionLimit;
164-
unifierState.counters.iterationLimit = FInt::LuauTypeInferIterationLimit;
176+
Subtyping subtyping{
177+
builtinTypes,
178+
NotNull{typeArena},
179+
NotNull{simplifier.get()},
180+
NotNull{&normalizer},
181+
NotNull{&typeFunctionRuntime},
182+
NotNull{&iceReporter}
183+
};
165184

166-
Subtyping subtyping{
167-
builtinTypes, NotNull{typeArena}, NotNull{simplifier.get()}, NotNull{&normalizer}, NotNull{&typeFunctionRuntime}, NotNull{&iceReporter}
168-
};
185+
return subtyping.isSubtype(subTy, superTy, scope).isSubtype;
186+
}
187+
else
188+
{
189+
Unifier unifier(NotNull<Normalizer>{&normalizer}, scope, Location(), Variance::Covariant);
190+
191+
// Cost of normalization can be too high for autocomplete response time requirements
192+
unifier.normalize = false;
193+
unifier.checkInhabited = false;
169194

170-
return subtyping.isSubtype(subTy, superTy, scope).isSubtype;
195+
unifierState.counters.recursionLimit = FInt::LuauTypeInferRecursionLimit;
196+
unifierState.counters.iterationLimit = FInt::LuauTypeInferIterationLimit;
197+
198+
return unifier.canUnify(subTy, superTy).empty();
199+
}
171200
}
172201
else
173202
{
174-
Unifier unifier(NotNull<Normalizer>{&normalizer}, scope, Location(), Variance::Covariant);
203+
if (FFlag::LuauSolverV2)
204+
{
205+
TypeCheckLimits limits;
206+
TypeFunctionRuntime typeFunctionRuntime{
207+
NotNull{&iceReporter}, NotNull{&limits}
208+
}; // TODO: maybe subtyping checks should not invoke user-defined type function runtime
175209

176-
// Cost of normalization can be too high for autocomplete response time requirements
177-
unifier.normalize = false;
178-
unifier.checkInhabited = false;
210+
unifierState.counters.recursionLimit = FInt::LuauTypeInferRecursionLimit;
211+
unifierState.counters.iterationLimit = FInt::LuauTypeInferIterationLimit;
179212

180-
if (FFlag::LuauAutocompleteUseLimits)
213+
Subtyping subtyping{
214+
builtinTypes,
215+
NotNull{typeArena},
216+
NotNull{simplifier.get()},
217+
NotNull{&normalizer},
218+
NotNull{&typeFunctionRuntime},
219+
NotNull{&iceReporter}
220+
};
221+
222+
return subtyping.isSubtype(subTy, superTy, scope).isSubtype;
223+
}
224+
else
181225
{
226+
Unifier unifier(NotNull<Normalizer>{&normalizer}, scope, Location(), Variance::Covariant);
227+
228+
// Cost of normalization can be too high for autocomplete response time requirements
229+
unifier.normalize = false;
230+
unifier.checkInhabited = false;
182231
unifierState.counters.recursionLimit = FInt::LuauTypeInferRecursionLimit;
183232
unifierState.counters.iterationLimit = FInt::LuauTypeInferIterationLimit;
184-
}
185233

186-
return unifier.canUnify(subTy, superTy).empty();
234+
return unifier.canUnify(subTy, superTy).empty();
235+
}
187236
}
188237
}
189238

@@ -209,10 +258,10 @@ static TypeCorrectKind checkTypeCorrectKind(
209258

210259
TypeId expectedType = follow(*typeAtPosition);
211260

212-
auto checkFunctionType = [typeArena, builtinTypes, moduleScope, &expectedType](const FunctionType* ftv)
261+
auto checkFunctionType = [typeArena, builtinTypes, moduleScope, &expectedType, &module](const FunctionType* ftv)
213262
{
214263
if (std::optional<TypeId> firstRetTy = first(ftv->retTypes))
215-
return checkTypeMatch(*firstRetTy, expectedType, moduleScope, typeArena, builtinTypes);
264+
return checkTypeMatch(module, *firstRetTy, expectedType, moduleScope, typeArena, builtinTypes);
216265

217266
return false;
218267
};
@@ -235,7 +284,7 @@ static TypeCorrectKind checkTypeCorrectKind(
235284
}
236285
}
237286

238-
return checkTypeMatch(ty, expectedType, moduleScope, typeArena, builtinTypes) ? TypeCorrectKind::Correct : TypeCorrectKind::None;
287+
return checkTypeMatch(module, ty, expectedType, moduleScope, typeArena, builtinTypes) ? TypeCorrectKind::Correct : TypeCorrectKind::None;
239288
}
240289

241290
enum class PropIndexType
@@ -286,7 +335,7 @@ static void autocompleteProps(
286335
// When called with '.', but declared with 'self', it is considered invalid if first argument is compatible
287336
if (std::optional<TypeId> firstArgTy = first(ftv->argTypes))
288337
{
289-
if (checkTypeMatch(rootTy, *firstArgTy, NotNull{module.getModuleScope().get()}, typeArena, builtinTypes))
338+
if (checkTypeMatch(module, rootTy, *firstArgTy, NotNull{module.getModuleScope().get()}, typeArena, builtinTypes))
290339
return calledWithSelf;
291340
}
292341

@@ -1714,6 +1763,7 @@ AutocompleteResult autocomplete_(
17141763
StringCompletionCallback callback
17151764
)
17161765
{
1766+
LUAU_TIMETRACE_SCOPE("Luau::autocomplete_", "AutocompleteCore");
17171767
AstNode* node = ancestry.back();
17181768

17191769
AstExprConstantNil dummy{Location{}};

0 commit comments

Comments
 (0)