Skip to content

Commit c517432

Browse files
andyfriesenaatxehgoldsteinskanosueTalha Pathan
authored
Sync to upstream/release/671 (#1787)
# General * Internally rename `ClassType` to `ExternType`. In definition files, the syntax to define these types has changed to `declare extern type Foo with prop: type end` * Add `luarequire_registermodule` to Luau.Require * Support yieldable Luau C functions calling other functions * Store return types as `AstTypePack*` on Ast nodes ## New Solver * Improve the logic that determines constraint dispatch ordering * Fix a crash in the type solver that arose when using multi-return functions with `string.format` * Fix #1736 * Initial steps toward rethinking function generalization: * Instead of generalizing every type in a function all at once, we will instead generalize individual type variables once their bounds have been fully resolved. This will make it possible to properly interleave type function reduction and generalization. * Magic functions are no longer considered magical in cases where they are not explicitly called by the code. * The most prominent example of this is in `for..in` loops where the function call is part of the desugaring process. * Almost all magic functions work by directly inspecting the AST, so they can't work without an AST fragment anyway. * Further, none of the magic functions we have are usefully used in this way. Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Ariel Weiss <aaronweiss@roblox.com> Co-authored-by: Hunter Goldstein <hgoldstein@roblox.com> Co-authored-by: Sora Kanosue <skanosue@roblox.com> Co-authored-by: Talha Pathan <tpathan@roblox.com> Co-authored-by: Varun Saini <vsaini@roblox.com> Co-authored-by: Vighnesh Vijay <vvijay@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
1 parent a2303a6 commit c517432

File tree

127 files changed

+4030
-1577
lines changed

Some content is hidden

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

127 files changed

+4030
-1577
lines changed

Analysis/include/Luau/AutocompleteTypes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct AutocompleteEntry
5757
// Set if this suggestion matches the type expected in the context
5858
TypeCorrectKind typeCorrect = TypeCorrectKind::None;
5959

60-
std::optional<const ClassType*> containingClass = std::nullopt;
60+
std::optional<const ExternType*> containingExternType = std::nullopt;
6161
std::optional<const Property*> prop = std::nullopt;
6262
std::optional<std::string> documentationSymbol = std::nullopt;
6363
Tags tags;
@@ -85,7 +85,7 @@ struct AutocompleteResult
8585
};
8686

8787
using StringCompletionCallback =
88-
std::function<std::optional<AutocompleteEntryMap>(std::string tag, std::optional<const ClassType*> ctx, std::optional<std::string> contents)>;
88+
std::function<std::optional<AutocompleteEntryMap>(std::string tag, std::optional<const ExternType*> ctx, std::optional<std::string> contents)>;
8989

9090
constexpr char kGeneratedAnonymousFunctionEntryName[] = "function (anonymous autofilled)";
9191

Analysis/include/Luau/ConstraintGenerator.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "Luau/Ast.h"
55
#include "Luau/Constraint.h"
6+
#include "Luau/ConstraintSet.h"
67
#include "Luau/ControlFlow.h"
78
#include "Luau/DataFlowGraph.h"
89
#include "Luau/EqSatSimplification.h"
@@ -91,9 +92,8 @@ struct ConstraintGenerator
9192
// Constraints that go straight to the solver.
9293
std::vector<ConstraintPtr> constraints;
9394

94-
// Constraints that do not go to the solver right away. Other constraints
95-
// will enqueue them during solving.
96-
std::vector<ConstraintPtr> unqueuedConstraints;
95+
// The set of all free types introduced during constraint generation.
96+
DenseHashSet<TypeId> freeTypes{nullptr};
9797

9898
// Map a function's signature scope back to its signature type.
9999
DenseHashMap<Scope*, TypeId> scopeToFunction{nullptr};
@@ -151,6 +151,9 @@ struct ConstraintGenerator
151151
std::vector<RequireCycle> requireCycles
152152
);
153153

154+
ConstraintSet run(AstStatBlock* block);
155+
ConstraintSet runOnFragment(const ScopePtr& resumeScope, AstStatBlock* block);
156+
154157
/**
155158
* The entry point to the ConstraintGenerator. This will construct a set
156159
* of scopes, constraints, and free types that can be solved later.
@@ -269,7 +272,7 @@ struct ConstraintGenerator
269272
ControlFlow visit(const ScopePtr& scope, AstStatTypeAlias* alias);
270273
ControlFlow visit(const ScopePtr& scope, AstStatTypeFunction* function);
271274
ControlFlow visit(const ScopePtr& scope, AstStatDeclareGlobal* declareGlobal);
272-
ControlFlow visit(const ScopePtr& scope, AstStatDeclareClass* declareClass);
275+
ControlFlow visit(const ScopePtr& scope, AstStatDeclareExternType* declareExternType);
273276
ControlFlow visit(const ScopePtr& scope, AstStatDeclareFunction* declareFunction);
274277
ControlFlow visit(const ScopePtr& scope, AstStatError* error);
275278

@@ -481,9 +484,4 @@ struct ConstraintGenerator
481484
TypeId simplifyUnion(const ScopePtr& scope, Location location, TypeId left, TypeId right);
482485
};
483486

484-
/** Borrow a vector of pointers from a vector of owning pointers to constraints.
485-
*/
486-
std::vector<NotNull<Constraint>> borrowConstraints(const std::vector<ConstraintPtr>& constraints);
487-
488-
489487
} // namespace Luau

Analysis/include/Luau/ConstraintSet.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2+
3+
#pragma once
4+
5+
#include "Luau/Constraint.h"
6+
#include "Luau/DenseHash.h"
7+
#include "Luau/Error.h"
8+
9+
#include <vector>
10+
11+
namespace Luau
12+
{
13+
14+
struct ConstraintSet
15+
{
16+
NotNull<Scope> rootScope;
17+
18+
std::vector<ConstraintPtr> constraints;
19+
20+
// The set of all free types created during constraint generation
21+
DenseHashSet<TypeId> freeTypes{nullptr};
22+
23+
// Map a function's signature scope back to its signature type. Once we've
24+
// dispatched all of the constraints pertaining to a particular free type,
25+
// we use this mapping to generalize that free type.
26+
DenseHashMap<Scope*, TypeId> scopeToFunction{nullptr};
27+
28+
// It is pretty uncommon for constraint generation to itself produce errors, but it can happen.
29+
std::vector<TypeError> errors;
30+
};
31+
32+
}

Analysis/include/Luau/ConstraintSolver.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#pragma once
44

55
#include "Luau/Constraint.h"
6+
#include "Luau/ConstraintSet.h"
67
#include "Luau/DataFlowGraph.h"
78
#include "Luau/DenseHash.h"
89
#include "Luau/EqSatSimplification.h"
@@ -87,6 +88,7 @@ struct ConstraintSolver
8788
NotNull<Simplifier> simplifier;
8889
NotNull<TypeFunctionRuntime> typeFunctionRuntime;
8990
// The entire set of constraints that the solver is trying to resolve.
91+
ConstraintSet constraintSet;
9092
std::vector<NotNull<Constraint>> constraints;
9193
NotNull<DenseHashMap<Scope*, TypeId>> scopeToFunction;
9294
NotNull<Scope> rootScope;
@@ -140,6 +142,19 @@ struct ConstraintSolver
140142

141143
DenseHashMap<TypeId, const Constraint*> typeFunctionsToFinalize{nullptr};
142144

145+
explicit ConstraintSolver(
146+
NotNull<Normalizer> normalizer,
147+
NotNull<Simplifier> simplifier,
148+
NotNull<TypeFunctionRuntime> typeFunctionRuntime,
149+
ModuleName moduleName,
150+
NotNull<ModuleResolver> moduleResolver,
151+
std::vector<RequireCycle> requireCycles,
152+
DcrLogger* logger,
153+
NotNull<const DataFlowGraph> dfg,
154+
TypeCheckLimits limits,
155+
ConstraintSet constraintSet
156+
);
157+
143158
explicit ConstraintSolver(
144159
NotNull<Normalizer> normalizer,
145160
NotNull<Simplifier> simplifier,
@@ -174,6 +189,9 @@ struct ConstraintSolver
174189
bool isDone() const;
175190

176191
private:
192+
/// A helper that does most of the setup work that is shared between the two constructors.
193+
void initFreeTypeTracking();
194+
177195
void generalizeOneType(TypeId ty);
178196

179197
/**
@@ -432,6 +450,10 @@ struct ConstraintSolver
432450
void fillInDiscriminantTypes(NotNull<const Constraint> constraint, const std::vector<std::optional<TypeId>>& discriminantTypes);
433451
};
434452

453+
/** Borrow a vector of pointers from a vector of owning pointers to constraints.
454+
*/
455+
std::vector<NotNull<Constraint>> borrowConstraints(const std::vector<ConstraintPtr>& constraints);
456+
435457
void dump(NotNull<Scope> rootScope, struct ToStringOptions& opts);
436458

437459
} // namespace Luau

Analysis/include/Luau/DataFlowGraph.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ struct DataFlowGraphBuilder
173173
ControlFlow visit(AstStatTypeFunction* f);
174174
ControlFlow visit(AstStatDeclareGlobal* d);
175175
ControlFlow visit(AstStatDeclareFunction* d);
176-
ControlFlow visit(AstStatDeclareClass* d);
176+
ControlFlow visit(AstStatDeclareExternType* d);
177177
ControlFlow visit(AstStatError* error);
178178

179179
DataFlowResult visitExpr(AstExpr* e);

Analysis/include/Luau/Error.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,11 +332,11 @@ struct TypePackMismatch
332332
bool operator==(const TypePackMismatch& rhs) const;
333333
};
334334

335-
struct DynamicPropertyLookupOnClassesUnsafe
335+
struct DynamicPropertyLookupOnExternTypesUnsafe
336336
{
337337
TypeId ty;
338338

339-
bool operator==(const DynamicPropertyLookupOnClassesUnsafe& rhs) const;
339+
bool operator==(const DynamicPropertyLookupOnExternTypesUnsafe& rhs) const;
340340
};
341341

342342
struct UninhabitedTypeFunction
@@ -499,7 +499,7 @@ using TypeErrorData = Variant<
499499
TypesAreUnrelated,
500500
NormalizationTooComplex,
501501
TypePackMismatch,
502-
DynamicPropertyLookupOnClassesUnsafe,
502+
DynamicPropertyLookupOnExternTypesUnsafe,
503503
UninhabitedTypeFunction,
504504
UninhabitedTypePackFunction,
505505
WhereClauseNeeded,

Analysis/include/Luau/FileResolver.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ struct FileResolver
117117
return std::nullopt;
118118
}
119119

120-
// Make non-virtual when removing FFlagLuauImproveRequireByStringAutocomplete.
121-
virtual std::optional<RequireSuggestions> getRequireSuggestions(const ModuleName& requirer, const std::optional<std::string>& pathString) const;
120+
std::optional<RequireSuggestions> getRequireSuggestions(const ModuleName& requirer, const std::optional<std::string>& pathString) const;
122121

123122
std::shared_ptr<RequireSuggester> requireSuggester;
124123
};

Analysis/include/Luau/Instantiation.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ struct GenericTypeFinder : TypeOnceVisitor
133133
return false;
134134
}
135135

136-
bool visit(TypeId ty, const Luau::ClassType&) override
136+
bool visit(TypeId ty, const Luau::ExternType&) override
137137
{
138-
// During function instantiation, classes are not traversed even if they have generics
138+
// During function instantiation, extern types are not traversed even if they have generics
139139
return false;
140140
}
141141
};

Analysis/include/Luau/Normalize.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ struct NormalizedStringType
181181

182182
bool isSubtype(const NormalizedStringType& subStr, const NormalizedStringType& superStr);
183183

184-
struct NormalizedClassType
184+
struct NormalizedExternType
185185
{
186186
/** Has the following structure:
187187
*
@@ -192,7 +192,7 @@ struct NormalizedClassType
192192
*
193193
* Each TypeId is a class type.
194194
*/
195-
std::unordered_map<TypeId, TypeIds> classes;
195+
std::unordered_map<TypeId, TypeIds> externTypes;
196196

197197
/**
198198
* In order to maintain a consistent insertion order, we use this vector to
@@ -245,7 +245,7 @@ enum class NormalizationResult
245245
};
246246

247247
// A normalized type is either any, unknown, or one of the form P | T | F | G where
248-
// * P is a union of primitive types (including singletons, classes and the error type)
248+
// * P is a union of primitive types (including singletons, extern types and the error type)
249249
// * T is a union of table types
250250
// * F is a union of an intersection of function types
251251
// * G is a union of generic/free/blocked types, intersected with a normalized type
@@ -260,7 +260,7 @@ struct NormalizedType
260260
// This type is either never, boolean type, or a boolean singleton.
261261
TypeId booleans;
262262

263-
NormalizedClassType classes;
263+
NormalizedExternType externTypes;
264264

265265
// The error part of the type.
266266
// This type is either never or the error type.
@@ -333,7 +333,7 @@ struct NormalizedType
333333
// Helpers that improve readability of the above (they just say if the component is present)
334334
bool hasTops() const;
335335
bool hasBooleans() const;
336-
bool hasClasses() const;
336+
bool hasExternTypes() const;
337337
bool hasErrors() const;
338338
bool hasNils() const;
339339
bool hasNumbers() const;
@@ -391,10 +391,10 @@ class Normalizer
391391
void unionTysWithTy(TypeIds& here, TypeId there);
392392
TypeId unionOfTops(TypeId here, TypeId there);
393393
TypeId unionOfBools(TypeId here, TypeId there);
394-
void unionClassesWithClass(TypeIds& heres, TypeId there);
395-
void unionClasses(TypeIds& heres, const TypeIds& theres);
396-
void unionClassesWithClass(NormalizedClassType& heres, TypeId there);
397-
void unionClasses(NormalizedClassType& heres, const NormalizedClassType& theres);
394+
void unionExternTypesWithExternType(TypeIds& heres, TypeId there);
395+
void unionExternTypes(TypeIds& heres, const TypeIds& theres);
396+
void unionExternTypesWithExternType(NormalizedExternType& heres, TypeId there);
397+
void unionExternTypes(NormalizedExternType& heres, const NormalizedExternType& theres);
398398
void unionStrings(NormalizedStringType& here, const NormalizedStringType& there);
399399
std::optional<TypePackId> unionOfTypePacks(TypePackId here, TypePackId there);
400400
std::optional<TypeId> unionOfFunctions(TypeId here, TypeId there);
@@ -423,8 +423,8 @@ class Normalizer
423423
// ------- Normalizing intersections
424424
TypeId intersectionOfTops(TypeId here, TypeId there);
425425
TypeId intersectionOfBools(TypeId here, TypeId there);
426-
void intersectClasses(NormalizedClassType& heres, const NormalizedClassType& theres);
427-
void intersectClassesWithClass(NormalizedClassType& heres, TypeId there);
426+
void intersectExternTypes(NormalizedExternType& heres, const NormalizedExternType& theres);
427+
void intersectExternTypesWithExternType(NormalizedExternType& heres, TypeId there);
428428
void intersectStrings(NormalizedStringType& here, const NormalizedStringType& there);
429429
std::optional<TypePackId> intersectionOfTypePacks(TypePackId here, TypePackId there);
430430
std::optional<TypeId> intersectionOfTables(TypeId here, TypeId there, SeenTablePropPairs& seenTablePropPairs, Set<TypeId>& seenSet);

Analysis/include/Luau/Quantify.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ struct Scope;
1616

1717
void quantify(TypeId ty, TypeLevel level);
1818

19-
// TODO: This is eerily similar to the pattern that NormalizedClassType
19+
// TODO: This is eerily similar to the pattern that NormalizedExternType
2020
// implements. We could, and perhaps should, merge them together.
2121
template<typename K, typename V>
2222
struct OrderedMap

Analysis/include/Luau/Subtyping.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct InternalErrorReporter;
2222

2323
class TypeIds;
2424
class Normalizer;
25-
struct NormalizedClassType;
25+
struct NormalizedExternType;
2626
struct NormalizedFunctionType;
2727
struct NormalizedStringType;
2828
struct NormalizedType;
@@ -121,7 +121,7 @@ struct SubtypingEnvironment
121121
DenseHashMap<TypePackId, TypePackId> mappedGenericPacks{nullptr};
122122

123123
/*
124-
* See the test cyclic_tables_are_assumed_to_be_compatible_with_classes for
124+
* See the test cyclic_tables_are_assumed_to_be_compatible_with_extern_types for
125125
* details.
126126
*
127127
* An empty value is equivalent to a nonexistent key.
@@ -229,9 +229,8 @@ struct Subtyping
229229
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const TableType* subTable, const TableType* superTable, NotNull<Scope> scope);
230230
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const MetatableType* subMt, const MetatableType* superMt, NotNull<Scope> scope);
231231
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const MetatableType* subMt, const TableType* superTable, NotNull<Scope> scope);
232-
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const ClassType* subClass, const ClassType* superClass, NotNull<Scope> scope);
233-
SubtypingResult
234-
isCovariantWith(SubtypingEnvironment& env, TypeId subTy, const ClassType* subClass, TypeId superTy, const TableType* superTable, NotNull<Scope>);
232+
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const ExternType* subExternType, const ExternType* superExternType, NotNull<Scope> scope);
233+
SubtypingResult isCovariantWith(SubtypingEnvironment& env, TypeId subTy, const ExternType* subExternType, TypeId superTy, const TableType* superTable, NotNull<Scope>);
235234
SubtypingResult isCovariantWith(
236235
SubtypingEnvironment& env,
237236
const FunctionType* subFunction,
@@ -259,11 +258,11 @@ struct Subtyping
259258
);
260259
SubtypingResult isCovariantWith(
261260
SubtypingEnvironment& env,
262-
const NormalizedClassType& subClass,
263-
const NormalizedClassType& superClass,
261+
const NormalizedExternType& subExternType,
262+
const NormalizedExternType& superExternType,
264263
NotNull<Scope> scope
265264
);
266-
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const NormalizedClassType& subClass, const TypeIds& superTables, NotNull<Scope> scope);
265+
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const NormalizedExternType& subExternType, const TypeIds& superTables, NotNull<Scope> scope);
267266
SubtypingResult isCovariantWith(
268267
SubtypingEnvironment& env,
269268
const NormalizedStringType& subString,

Analysis/include/Luau/ToString.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct ToStringOptions
4444
bool hideTableKind = false; // If true, all tables will be surrounded with plain '{}'
4545
bool hideNamedFunctionTypeParameters = false; // If true, type parameters of functions will be hidden at top-level.
4646
bool hideFunctionSelfArgument = false; // If true, `self: X` will be omitted from the function signature if the function has self
47+
bool hideTableAliasExpansions = false; // If true, all table aliases will not be expanded
4748
bool useQuestionMarks = true; // If true, use a postfix ? for options, else write them out as unions that include nil.
4849
size_t maxTableLength = size_t(FInt::LuauTableTypeMaximumStringifierLength); // Only applied to TableTypes
4950
size_t maxTypeLength = size_t(FInt::LuauTypeMaximumStringifierLength);

0 commit comments

Comments
 (0)