Skip to content

Commit 16fbfe9

Browse files
aatxezeuxvegorov-rbxandyfriesenAmaranthineCodices
authored
Sync to upstream/release/596 (luau-lang#1050)
- Cleaned up `FFlag::FixFindBindingAtFunctionName`, `FFlag::LuauNormalizeBlockedTypes`, `FFlag::LuauPCallDebuggerFix` - Added support for break and continue into control flow analysis - The old type unification engine will now report a more fine-grained error at times, indicating that type normalization in particular failed # New Type Solver - Refactor of Unifier2, the new unification implementation for Luau - Completed MVP of new unification implementation - Dramatically simplified overload selection logic - Type family reduction can now apply sooner to free types that have been solved - Subtyping now supports table indexers - Generalization now replaces bad generics with unknown # Native Code Generation - Reduce stack spills caused by FINDUPVAL and STORE_TAG - Improve Generate SHL/SHR/SAR/rotates with immediate operands in X64 - Removed redundant case re-check in table lookup fallback --------- Co-authored-by: Arseny Kapoulkine <[email protected]> Co-authored-by: Vyacheslav Egorov <[email protected]> Co-authored-by: Andy Friesen <[email protected]> Co-authored-by: Lily Brown <[email protected]>
1 parent d00e93c commit 16fbfe9

Some content is hidden

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

50 files changed

+1327
-666
lines changed

Analysis/include/Luau/ConstraintSolver.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,9 @@ struct ConstraintSolver
203203
* the result.
204204
* @param subType the sub-type to unify.
205205
* @param superType the super-type to unify.
206+
* @returns optionally a unification too complex error if unification failed
206207
*/
207-
ErrorVec unify(NotNull<Scope> scope, Location location, TypeId subType, TypeId superType);
208+
std::optional<TypeError> unify(NotNull<Scope> scope, Location location, TypeId subType, TypeId superType);
208209

209210
/**
210211
* Creates a new Unifier and performs a single unification operation. Commits
@@ -233,6 +234,15 @@ struct ConstraintSolver
233234
void reportError(TypeErrorData&& data, const Location& location);
234235
void reportError(TypeError e);
235236

237+
/**
238+
* Checks the existing set of constraints to see if there exist any that contain
239+
* the provided free type, indicating that it is not yet ready to be replaced by
240+
* one of its bounds.
241+
* @param ty the free type that to check for related constraints
242+
* @returns whether or not it is unsafe to replace the free type by one of its bounds
243+
*/
244+
bool hasUnresolvedConstraints(TypeId ty);
245+
236246
private:
237247

238248
/** Helper used by tryDispatch(SubtypeConstraint) and

Analysis/include/Luau/Subtyping.h

+2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ struct Subtyping
124124
SubtypingResult isCovariantWith(const PrimitiveType* subPrim, const TableType* superTable);
125125
SubtypingResult isCovariantWith(const SingletonType* subSingleton, const TableType* superTable);
126126

127+
SubtypingResult isCovariantWith(const TableIndexer& subIndexer, const TableIndexer& superIndexer);
128+
127129
SubtypingResult isCovariantWith(const NormalizedType* subNorm, const NormalizedType* superNorm);
128130
SubtypingResult isCovariantWith(const NormalizedClassType& subClass, const NormalizedClassType& superClass);
129131
SubtypingResult isCovariantWith(const NormalizedClassType& subClass, const TypeIds& superTables);

Analysis/include/Luau/Type.h

-2
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ struct BlockedType
141141
{
142142
BlockedType();
143143
int index;
144-
145-
static int DEPRECATED_nextIndex;
146144
};
147145

148146
struct PrimitiveType

Analysis/include/Luau/TypeFamily.h

+42-10
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct TypeFamily
5454

5555
/// The reducer function for the type family.
5656
std::function<TypeFamilyReductionResult<TypeId>(std::vector<TypeId>, std::vector<TypePackId>, NotNull<TypeArena>, NotNull<BuiltinTypes>,
57-
NotNull<TxnLog>, NotNull<Scope>, NotNull<Normalizer>)>
57+
NotNull<TxnLog>, NotNull<Scope>, NotNull<Normalizer>, ConstraintSolver*)>
5858
reducer;
5959
};
6060

@@ -68,7 +68,7 @@ struct TypePackFamily
6868

6969
/// The reducer function for the type pack family.
7070
std::function<TypeFamilyReductionResult<TypePackId>(std::vector<TypeId>, std::vector<TypePackId>, NotNull<TypeArena>, NotNull<BuiltinTypes>,
71-
NotNull<TxnLog>, NotNull<Scope>, NotNull<Normalizer>)>
71+
NotNull<TxnLog>, NotNull<Scope>, NotNull<Normalizer>, ConstraintSolver*)>
7272
reducer;
7373
};
7474

@@ -81,37 +81,69 @@ struct FamilyGraphReductionResult
8181
DenseHashSet<TypePackId> reducedPacks{nullptr};
8282
};
8383

84+
/**
85+
* Attempt to reduce all instances of any type or type pack family in the type
86+
* graph provided.
87+
*
88+
* @param entrypoint the entry point to the type graph.
89+
* @param location the location the reduction is occurring at; used to populate
90+
* type errors.
91+
* @param arena an arena to allocate types into.
92+
* @param builtins the built-in types.
93+
* @param normalizer the normalizer to use when normalizing types
94+
* @param log a TxnLog to use. If one is provided, substitution will take place
95+
* against the TxnLog, otherwise substitutions will directly mutate the type
96+
* graph. Do not provide the empty TxnLog, as a result.
97+
*/
98+
FamilyGraphReductionResult reduceFamilies(TypeId entrypoint, Location location, NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtins,
99+
NotNull<Scope> scope, NotNull<Normalizer> normalizer, TxnLog* log = nullptr, bool force = false);
100+
101+
/**
102+
* Attempt to reduce all instances of any type or type pack family in the type
103+
* graph provided.
104+
*
105+
* @param entrypoint the entry point to the type graph.
106+
* @param location the location the reduction is occurring at; used to populate
107+
* type errors.
108+
* @param arena an arena to allocate types into.
109+
* @param builtins the built-in types.
110+
* @param normalizer the normalizer to use when normalizing types
111+
* @param log a TxnLog to use. If one is provided, substitution will take place
112+
* against the TxnLog, otherwise substitutions will directly mutate the type
113+
* graph. Do not provide the empty TxnLog, as a result.
114+
*/
115+
FamilyGraphReductionResult reduceFamilies(TypePackId entrypoint, Location location, NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtins,
116+
NotNull<Scope> scope, NotNull<Normalizer> normalizer, TxnLog* log = nullptr, bool force = false);
117+
84118
/**
85119
* Attempt to reduce all instances of any type or type pack family in the type
86120
* graph provided.
87121
*
122+
* @param solver the constraint solver this reduction is being performed in.
88123
* @param entrypoint the entry point to the type graph.
89124
* @param location the location the reduction is occurring at; used to populate
90125
* type errors.
91-
* @param arena an arena to allocate types into.
92-
* @param builtins the built-in types.
93126
* @param log a TxnLog to use. If one is provided, substitution will take place
94127
* against the TxnLog, otherwise substitutions will directly mutate the type
95128
* graph. Do not provide the empty TxnLog, as a result.
96129
*/
97-
FamilyGraphReductionResult reduceFamilies(TypeId entrypoint, Location location, NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtins,
98-
NotNull<Scope> scope, NotNull<Normalizer> normalizer, TxnLog* log = nullptr, bool force = false);
130+
FamilyGraphReductionResult reduceFamilies(
131+
NotNull<ConstraintSolver> solver, TypeId entrypoint, Location location, NotNull<Scope> scope, TxnLog* log = nullptr, bool force = false);
99132

100133
/**
101134
* Attempt to reduce all instances of any type or type pack family in the type
102135
* graph provided.
103136
*
137+
* @param solver the constraint solver this reduction is being performed in.
104138
* @param entrypoint the entry point to the type graph.
105139
* @param location the location the reduction is occurring at; used to populate
106140
* type errors.
107-
* @param arena an arena to allocate types into.
108-
* @param builtins the built-in types.
109141
* @param log a TxnLog to use. If one is provided, substitution will take place
110142
* against the TxnLog, otherwise substitutions will directly mutate the type
111143
* graph. Do not provide the empty TxnLog, as a result.
112144
*/
113-
FamilyGraphReductionResult reduceFamilies(TypePackId entrypoint, Location location, NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtins,
114-
NotNull<Scope> scope, NotNull<Normalizer> normalizer, TxnLog* log = nullptr, bool force = false);
145+
FamilyGraphReductionResult reduceFamilies(
146+
NotNull<ConstraintSolver> solver, TypePackId entrypoint, Location location, NotNull<Scope> scope, TxnLog* log = nullptr, bool force = false);
115147

116148
struct BuiltinTypeFamilies
117149
{

Analysis/include/Luau/Unifier2.h

+40-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
#include "Luau/DenseHash.h"
66
#include "Luau/NotNull.h"
7+
#include "Type.h"
8+
#include "TypeCheckLimits.h"
9+
#include "TypeChecker2.h"
710

811
#include <optional>
912
#include <vector>
@@ -26,16 +29,44 @@ enum class OccursCheckResult
2629
Fail
2730
};
2831

32+
struct TypePairHash
33+
{
34+
size_t hashOne(Luau::TypeId key) const
35+
{
36+
return (uintptr_t(key) >> 4) ^ (uintptr_t(key) >> 9);
37+
}
38+
39+
size_t hashOne(Luau::TypePackId key) const
40+
{
41+
return (uintptr_t(key) >> 4) ^ (uintptr_t(key) >> 9);
42+
}
43+
44+
size_t operator()(const std::pair<Luau::TypeId, Luau::TypeId>& x) const
45+
{
46+
return hashOne(x.first) ^ (hashOne(x.second) << 1);
47+
}
48+
49+
size_t operator()(const std::pair<Luau::TypePackId, Luau::TypePackId>& x) const
50+
{
51+
return hashOne(x.first) ^ (hashOne(x.second) << 1);
52+
}
53+
};
54+
2955
struct Unifier2
3056
{
3157
NotNull<TypeArena> arena;
3258
NotNull<BuiltinTypes> builtinTypes;
59+
NotNull<Scope> scope;
3360
NotNull<InternalErrorReporter> ice;
61+
TypeCheckLimits limits;
62+
63+
DenseHashSet<std::pair<TypeId, TypeId>, TypePairHash> seenTypePairings{{nullptr, nullptr}};
64+
DenseHashSet<std::pair<TypePackId, TypePackId>, TypePairHash> seenTypePackPairings{{nullptr, nullptr}};
3465

3566
int recursionCount = 0;
3667
int recursionLimit = 0;
3768

38-
Unifier2(NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtinTypes, NotNull<InternalErrorReporter> ice);
69+
Unifier2(NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtinTypes, NotNull<Scope> scope, NotNull<InternalErrorReporter> ice);
3970

4071
/** Attempt to commit the subtype relation subTy <: superTy to the type
4172
* graph.
@@ -50,11 +81,18 @@ struct Unifier2
5081
* free TypePack to another and encounter an occurs check violation.
5182
*/
5283
bool unify(TypeId subTy, TypeId superTy);
84+
bool unify(TypeId subTy, const FunctionType* superFn);
85+
bool unify(const UnionType* subUnion, TypeId superTy);
86+
bool unify(TypeId subTy, const UnionType* superUnion);
87+
bool unify(const IntersectionType* subIntersection, TypeId superTy);
88+
bool unify(TypeId subTy, const IntersectionType* superIntersection);
89+
bool unify(const TableType* subTable, const TableType* superTable);
90+
bool unify(const MetatableType* subMetatable, const MetatableType* superMetatable);
5391

5492
// TODO think about this one carefully. We don't do unions or intersections of type packs
5593
bool unify(TypePackId subTp, TypePackId superTp);
5694

57-
std::optional<TypeId> generalize(NotNull<Scope> scope, TypeId ty);
95+
std::optional<TypeId> generalize(TypeId ty);
5896

5997
private:
6098
/**

Analysis/include/Luau/VisitType.h

+10-5
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,16 @@ struct GenericTypeVisitor
226226
{
227227
if (visit(ty, *ftv))
228228
{
229-
LUAU_ASSERT(ftv->lowerBound);
230-
traverse(ftv->lowerBound);
231-
232-
LUAU_ASSERT(ftv->upperBound);
233-
traverse(ftv->upperBound);
229+
// TODO: Replace these if statements with assert()s when we
230+
// delete FFlag::DebugLuauDeferredConstraintResolution.
231+
//
232+
// When the old solver is used, these pointers are always
233+
// unused. When the new solver is used, they are never null.
234+
if (ftv->lowerBound)
235+
traverse(ftv->lowerBound);
236+
237+
if (ftv->upperBound)
238+
traverse(ftv->upperBound);
234239
}
235240
}
236241
else

Analysis/src/AstQuery.cpp

+12-27
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include <algorithm>
1313

1414
LUAU_FASTFLAG(DebugLuauReadWriteProperties)
15-
LUAU_FASTFLAGVARIABLE(FixFindBindingAtFunctionName, false);
1615

1716
namespace Luau
1817
{
@@ -151,19 +150,12 @@ struct FindNode : public AstVisitor
151150

152151
bool visit(AstStatFunction* node) override
153152
{
154-
if (FFlag::FixFindBindingAtFunctionName)
155-
{
156-
visit(static_cast<AstNode*>(node));
157-
if (node->name->location.contains(pos))
158-
node->name->visit(this);
159-
else if (node->func->location.contains(pos))
160-
node->func->visit(this);
161-
return false;
162-
}
163-
else
164-
{
165-
return AstVisitor::visit(node);
166-
}
153+
visit(static_cast<AstNode*>(node));
154+
if (node->name->location.contains(pos))
155+
node->name->visit(this);
156+
else if (node->func->location.contains(pos))
157+
node->func->visit(this);
158+
return false;
167159
}
168160

169161
bool visit(AstStatBlock* block) override
@@ -208,19 +200,12 @@ struct FindFullAncestry final : public AstVisitor
208200

209201
bool visit(AstStatFunction* node) override
210202
{
211-
if (FFlag::FixFindBindingAtFunctionName)
212-
{
213-
visit(static_cast<AstNode*>(node));
214-
if (node->name->location.contains(pos))
215-
node->name->visit(this);
216-
else if (node->func->location.contains(pos))
217-
node->func->visit(this);
218-
return false;
219-
}
220-
else
221-
{
222-
return AstVisitor::visit(node);
223-
}
203+
visit(static_cast<AstNode*>(node));
204+
if (node->name->location.contains(pos))
205+
node->name->visit(this);
206+
else if (node->func->location.contains(pos))
207+
node->func->visit(this);
208+
return false;
224209
}
225210

226211
bool visit(AstNode* node) override

0 commit comments

Comments
 (0)