Skip to content

Commit 9457397

Browse files
vrn-snandyfriesenannieetangaatxehgoldstein
authored
Sync to origin/release/692 (#2012)
Another week, another release! ## Analysis/Autocomplete - Improve recursive type lookups by using scoped tracking of processed types. - Enforce recursion limits in subtyping on type packs, not just on types. - Simplify type checking for intersections between tables and discriminants containing read-only table properties. - Allow fields provided by `__index` to satisfy subtyping relationships. - Improve the ability for the type checker to do proper generic substitution in `for ... in` loops. - Fix a fragment autocomplete bug that caused fragments to be selected incorrectly in `for ... in` loops. - Fix a crash caused by `typeof` containing an unterminated function definition: `typeof(function())`. - Fix a flagging issue that may have been causing stack overflows in the previous release. ## Runtime - Support constant folding for interpolated strings. - Fix a bug caused by the empty string being the result of constant folding. - Add helper macros in Bytecode.h to help access data in Luau auxiliary instruction bits. - Add support for branchless `==`/`~=` comparisons in CodeGen (in certain cases). --- Co-authored-by: Andy Friesen <[email protected]> Co-authored-by: Annie Tang <[email protected]> Co-authored-by: Ariel Weiss <[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: Vighnesh Vijay <[email protected]> Co-authored-by: Vyacheslav Egorov <[email protected]>
1 parent ae59a0e commit 9457397

Some content is hidden

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

67 files changed

+2753
-628
lines changed

Analysis/include/Luau/AstUtils.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,15 @@ namespace Luau
1313
// uniquely held references. Append these types to 'uniqueTypes'.
1414
void findUniqueTypes(NotNull<DenseHashSet<TypeId>> uniqueTypes, AstExpr* expr, NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes);
1515

16-
void findUniqueTypes(NotNull<DenseHashSet<TypeId>> uniqueTypes, AstArray<AstExpr*> exprs, NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes);
17-
void findUniqueTypes(NotNull<DenseHashSet<TypeId>> uniqueTypes, const std::vector<AstExpr*>& exprs, NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes);
16+
void findUniqueTypes(
17+
NotNull<DenseHashSet<TypeId>> uniqueTypes,
18+
AstArray<AstExpr*> exprs,
19+
NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes
20+
);
21+
void findUniqueTypes(
22+
NotNull<DenseHashSet<TypeId>> uniqueTypes,
23+
const std::vector<AstExpr*>& exprs,
24+
NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes
25+
);
1826

19-
}
27+
} // namespace Luau

Analysis/include/Luau/ConstraintSolver.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ struct ConstraintSolver
300300
ValueContext context,
301301
bool inConditional,
302302
bool suppressSimplification,
303-
DenseHashSet<TypeId>& seen
303+
Set<TypeId>& seen
304304
);
305305

306306
/**

Analysis/include/Luau/Subtyping.h

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ inline const SubtypingReasoning kEmptyReasoning = SubtypingReasoning{TypePath::k
5959
* isn't strictly lexical (see test nested_generic_argument_type_packs), and that nested generic packs can shadow existing ones
6060
* such as with the type <A...>(<A...>(A...) -> (), <A...>(A...) -> ()) -> (), which should result in three independent bindings for A... .
6161
* To handle this, we maintain a stack of frames, each of which contains a mapping for the generic packs bound in that scope, as well as a pointers to
62-
* its parent and child scopes. Inside each frame, we map the generic pack to an optional type pack, which is nullopt if we have not yet encountered a mapping
63-
* for that generic pack in this scope.
62+
* its parent and child scopes. Inside each frame, we map the generic pack to an optional type pack, which is nullopt if we have not yet encountered a
63+
* mapping for that generic pack in this scope.
6464
*/
6565

6666
struct MappedGenericEnvironment
@@ -282,7 +282,6 @@ struct Subtyping
282282
SubtypingResult cache(SubtypingEnvironment& env, SubtypingResult res, TypeId subTy, TypeId superTy);
283283

284284
SubtypingResult isCovariantWith(SubtypingEnvironment& env, TypeId subTy, TypeId superTy, NotNull<Scope> scope);
285-
SubtypingResult isCovariantWith(SubtypingEnvironment& env, TypePackId subTp, TypePackId superTp, NotNull<Scope> scope);
286285

287286
template<typename SubTy, typename SuperTy>
288287
SubtypingResult isContravariantWith(SubtypingEnvironment& env, SubTy&& subTy, SuperTy&& superTy, NotNull<Scope> scope);
@@ -321,7 +320,13 @@ struct Subtyping
321320
NotNull<Scope> scope
322321
);
323322
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const TableType* subTable, const TableType* superTable, NotNull<Scope> scope);
324-
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const TableType* subTable, const TableType* superTable, bool forceCovariantTest, NotNull<Scope> scope);
323+
SubtypingResult isCovariantWith(
324+
SubtypingEnvironment& env,
325+
const TableType* subTable,
326+
const TableType* superTable,
327+
bool forceCovariantTest,
328+
NotNull<Scope> scope
329+
);
325330
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const MetatableType* subMt, const MetatableType* superMt, NotNull<Scope> scope);
326331
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const MetatableType* subMt, const TableType* superTable, NotNull<Scope> scope);
327332
SubtypingResult isCovariantWith(
@@ -420,6 +425,31 @@ struct Subtyping
420425
NotNull<Scope> scope
421426
);
422427

428+
// Pack subtyping
429+
SubtypingResult isCovariantWith(SubtypingEnvironment& env, TypePackId subTp, TypePackId superTp, NotNull<Scope> scope);
430+
std::optional<SubtypingResult> isSubTailCovariantWith(
431+
SubtypingEnvironment& env,
432+
std::vector<SubtypingResult>& outputResults,
433+
TypePackId subTp,
434+
TypePackId subTail,
435+
TypePackId superTp,
436+
size_t superHeadStartIndex,
437+
const std::vector<TypeId>& superHead,
438+
std::optional<TypePackId> superTail,
439+
NotNull<Scope> scope
440+
);
441+
std::optional<SubtypingResult> isCovariantWithSuperTail(
442+
SubtypingEnvironment& env,
443+
std::vector<SubtypingResult>& outputResults,
444+
TypePackId subTp,
445+
size_t subHeadStartIndex,
446+
const std::vector<TypeId>& subHead,
447+
std::optional<TypePackId> subTail,
448+
TypePackId superTp,
449+
TypePackId superTail,
450+
NotNull<Scope> scope
451+
);
452+
423453
bool bindGeneric(SubtypingEnvironment& env, TypeId subTp, TypeId superTp);
424454
// Clip with LuauSubtypingGenericPacksDoesntUseVariance
425455
bool bindGeneric_DEPRECATED(SubtypingEnvironment& env, TypePackId subTp, TypePackId superTp) const;

Analysis/include/Luau/TypeChecker2.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,12 @@ struct TypeChecker2
200200

201201
bool testIsSubtype(TypeId subTy, TypeId superTy, Location location);
202202
bool testIsSubtype(TypePackId subTy, TypePackId superTy, Location location);
203+
204+
void maybeReportSubtypingError(TypeId subTy, TypeId superTy, const Location& location);
205+
// Tests whether subTy is a subtype of superTy in the context of a function iterator for a for-in statement.
206+
// Includes some extra logic to help locate errors to the values and variables of the for-in statement.
207+
void testIsSubtypeForInStat(TypeId iterFunc, TypeId prospectiveFunc, const AstStatForIn& forInStat);
208+
203209
void reportError(TypeError e);
204210
void reportErrors(ErrorVec errors);
205211
PropertyTypes lookupProp(

Analysis/include/Luau/TypePack.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ LUAU_NOINLINE Unifiable::Bound<TypePackId>* emplaceTypePack<BoundTypePack>(TypeP
267267
TypePackId sliceTypePack(
268268
size_t sliceIndex,
269269
TypePackId toBeSliced,
270-
std::vector<TypeId>& head,
270+
const std::vector<TypeId>& head,
271271
std::optional<TypePackId> tail,
272272
NotNull<BuiltinTypes> builtinTypes,
273273
NotNull<TypeArena> arena

Analysis/include/Luau/TypePath.h

Lines changed: 8 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -242,18 +242,13 @@ std::string toString(const TypePath::Path& path, bool prefixDot = false);
242242
std::string toStringHuman(const TypePath::Path& path);
243243

244244
// To keep my head straight when clipping:
245-
// LuauReturnMappedGenericPacksFromSubtyping2 expects mappedGenericPacks AND arena
245+
// LuauReturnMappedGenericPacksFromSubtyping3 expects mappedGenericPacks AND arena
246246
// LuauSubtypingGenericPacksDoesntUseVariance expects just arena. this is the final state
247247

248-
// TODO: clip below two along with `LuauReturnMappedGenericPacksFromSubtyping2`
248+
// TODO: clip below two along with `LuauReturnMappedGenericPacksFromSubtyping3`
249249
std::optional<TypeOrPack> traverse_DEPRECATED(TypeId root, const Path& path, NotNull<BuiltinTypes> builtinTypes);
250250
std::optional<TypeOrPack> traverse_DEPRECATED(TypePackId root, const Path& path, NotNull<BuiltinTypes> builtinTypes);
251-
std::optional<TypeOrPack> traverse(
252-
TypePackId root,
253-
const Path& path,
254-
NotNull<BuiltinTypes> builtinTypes,
255-
NotNull<TypeArena> arena
256-
);
251+
std::optional<TypeOrPack> traverse(TypePackId root, const Path& path, NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena);
257252
// TODO: Clip with LuauSubtypingGenericPacksDoesntUseVariance
258253
std::optional<TypeOrPack> traverse_DEPRECATED(
259254
TypePackId root,
@@ -262,12 +257,7 @@ std::optional<TypeOrPack> traverse_DEPRECATED(
262257
NotNull<const DenseHashMap<TypePackId, TypePackId>> mappedGenericPacks,
263258
NotNull<TypeArena> arena
264259
);
265-
std::optional<TypeOrPack> traverse(
266-
TypeId root,
267-
const Path& path,
268-
NotNull<BuiltinTypes> builtinTypes,
269-
NotNull<TypeArena> arena
270-
);
260+
std::optional<TypeOrPack> traverse(TypeId root, const Path& path, NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena);
271261
// TODO: Clip with LuauSubtypingGenericPacksDoesntUseVariance
272262
std::optional<TypeOrPack> traverse_DEPRECATED(
273263
TypeId root,
@@ -306,12 +296,7 @@ std::optional<TypeId> traverseForType_DEPRECATED(
306296
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
307297
/// @param arena a TypeArena, required if path has a PackSlice component
308298
/// @returns the TypeId at the end of the path, or nullopt if the traversal failed.
309-
std::optional<TypeId> traverseForType(
310-
TypeId root,
311-
const Path& path,
312-
NotNull<BuiltinTypes> builtinTypes,
313-
NotNull<TypeArena> arena
314-
);
299+
std::optional<TypeId> traverseForType(TypeId root, const Path& path, NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena);
315300

316301
/// Traverses a path from a type pack to its end point, which must be a type.
317302
/// @param root the entry point of the traversal
@@ -341,12 +326,7 @@ std::optional<TypeId> traverseForType_DEPRECATED(
341326
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
342327
/// @param arena a TypeArena, required if path has a PackSlice component
343328
/// @returns the TypeId at the end of the path, or nullopt if the traversal failed.
344-
std::optional<TypeId> traverseForType(
345-
TypePackId root,
346-
const Path& path,
347-
NotNull<BuiltinTypes> builtinTypes,
348-
NotNull<TypeArena> arena
349-
);
329+
std::optional<TypeId> traverseForType(TypePackId root, const Path& path, NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena);
350330

351331
/// Traverses a path from a type to its end point, which must be a type pack. This overload will fail if the path contains a PackSlice component or a
352332
/// mapped generic pack.
@@ -377,12 +357,7 @@ std::optional<TypePackId> traverseForPack_DEPRECATED(
377357
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
378358
/// @param arena a TypeArena, required if path has a PackSlice component
379359
/// @returns the TypePackId at the end of the path, or nullopt if the traversal failed.
380-
std::optional<TypePackId> traverseForPack(
381-
TypeId root,
382-
const Path& path,
383-
NotNull<BuiltinTypes> builtinTypes,
384-
NotNull<TypeArena> arena
385-
);
360+
std::optional<TypePackId> traverseForPack(TypeId root, const Path& path, NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena);
386361

387362
/// Traverses a path from a type pack to its end point, which must be a type pack.
388363
/// @param root the entry point of the traversal
@@ -412,12 +387,7 @@ std::optional<TypePackId> traverseForPack_DEPRECATED(
412387
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
413388
/// @param arena a TypeArena, required if path has a PackSlice component
414389
/// @returns the TypePackId at the end of the path, or nullopt if the traversal failed.
415-
std::optional<TypePackId> traverseForPack(
416-
TypePackId root,
417-
const Path& path,
418-
NotNull<BuiltinTypes> builtinTypes,
419-
NotNull<TypeArena> arena
420-
);
390+
std::optional<TypePackId> traverseForPack(TypePackId root, const Path& path, NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena);
421391

422392
/// Traverses a path of Index and PackSlices to compute the index of the type the path points to
423393
/// Returns std::nullopt if the path isn't n PackSlice components followed by an Index component

Analysis/include/Luau/VisitType.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ struct GenericTypeVisitor
336336
{
337337
if (auto ty = prop.readTy)
338338
traverse(*ty);
339-
339+
340340
// In the case that the readType and the writeType are
341341
// the same pointer, just traverse once. Traversing each
342342
// property twice would have pretty significant

Analysis/src/AstUtils.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ struct AstExprTableFinder : AstVisitor
1414
explicit AstExprTableFinder(NotNull<DenseHashSet<TypeId>> result, NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes)
1515
: result(result)
1616
, astTypes(astTypes)
17-
{}
17+
{
18+
}
1819

1920
bool visit(AstExpr* expr) override
2021
{
@@ -38,8 +39,13 @@ void findUniqueTypes(NotNull<DenseHashSet<TypeId>> uniqueTypes, AstExpr* expr, N
3839
expr->visit(&finder);
3940
}
4041

41-
template <typename Iter>
42-
void findUniqueTypes(NotNull<DenseHashSet<TypeId>> uniqueTypes, Iter startIt, Iter endIt, NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes)
42+
template<typename Iter>
43+
void findUniqueTypes(
44+
NotNull<DenseHashSet<TypeId>> uniqueTypes,
45+
Iter startIt,
46+
Iter endIt,
47+
NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes
48+
)
4349
{
4450
while (startIt != endIt)
4551
{
@@ -51,14 +57,22 @@ void findUniqueTypes(NotNull<DenseHashSet<TypeId>> uniqueTypes, Iter startIt, It
5157
}
5258

5359

54-
void findUniqueTypes(NotNull<DenseHashSet<TypeId>> uniqueTypes, AstArray<AstExpr*> exprs, NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes)
60+
void findUniqueTypes(
61+
NotNull<DenseHashSet<TypeId>> uniqueTypes,
62+
AstArray<AstExpr*> exprs,
63+
NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes
64+
)
5565
{
5666
findUniqueTypes(uniqueTypes, exprs.begin(), exprs.end(), astTypes);
5767
}
5868

59-
void findUniqueTypes(NotNull<DenseHashSet<TypeId>> uniqueTypes, const std::vector<AstExpr*>& exprs, NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes)
69+
void findUniqueTypes(
70+
NotNull<DenseHashSet<TypeId>> uniqueTypes,
71+
const std::vector<AstExpr*>& exprs,
72+
NotNull<const DenseHashMap<const AstExpr*, TypeId>> astTypes
73+
)
6074
{
6175
findUniqueTypes(uniqueTypes, exprs.begin(), exprs.end(), astTypes);
6276
}
6377

64-
}
78+
} // namespace Luau

Analysis/src/Constraint.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "Luau/VisitType.h"
66

77
LUAU_FASTFLAGVARIABLE(LuauExplicitSkipBoundTypes)
8+
LUAU_FASTFLAG(LuauNoOrderingTypeFunctions)
89

910
namespace Luau
1011
{
@@ -87,7 +88,8 @@ TypeIds Constraint::getMaybeMutatedFreeTypes() const
8788
if (auto ec = get<EqualityConstraint>(*this))
8889
{
8990
rci.traverse(ec->resultType);
90-
// `EqualityConstraints` should not mutate `assignmentType`.
91+
if (FFlag::LuauNoOrderingTypeFunctions)
92+
rci.traverse(ec->assignmentType);
9193
}
9294
else if (auto sc = get<SubtypeConstraint>(*this))
9395
{

0 commit comments

Comments
 (0)