Skip to content

Commit 282ddfa

Browse files
SPYandyfriesenannieetangaatxehgoldstein
authored
Sync to upstream/release/700 (#2090)
We have reached release 700! # Analysis * `table.isfrozen` and `table.clear` use `{}` instead of generic table type to make it work with union of table types. * Relax typing definitions for `types.newtable` to make it easier to specify read-only table properties * Do not drop explicit generic type packs. Hopefully fixes #2075 * Added protection against stack overflows to more spots in `Unifier2` * Improved bidirectionally inferring lambdas. When performing inference on a lambda, check _right_ before we attempt to emplace a free type whether there's a generic. * Reworked overload resolution interface. `OverloadResolver::resolveOverload` was introduced to abstract and unify existing resolving machinery. * `instantiation2` selects more useful bounds. - If we have positive or negative polarity, blindly use the upper/lower bounds respectively. - Otherwise, attempt to find a reasonable bound by first avoiding picking `never` or `unknown`, then doing a subtype test to try to pick a tight bound. * Added protection against stack overflows to the non-strict type checker * Luau-syntax configuration extraction can now be timed out during analysis. See `CLI/src/Analyze.cpp` for an example. # Require * Support chained aliases with built-in cycle detection: luau-lang/rfcs#145. * Resolve JohnnyMorganz/luau-lsp#1246. # Autocomplete * Do not recommend generic types for anonymous functions being passed as arguments --- 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: Varun Saini <[email protected]>
1 parent 994b641 commit 282ddfa

File tree

78 files changed

+2669
-477
lines changed

Some content is hidden

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

78 files changed

+2669
-477
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2+
#pragma once
3+
4+
#include "Luau/Config.h"
5+
#include "Luau/TypeCheckLimits.h"
6+
7+
namespace Luau
8+
{
9+
10+
struct Config;
11+
12+
struct ConfigResolver
13+
{
14+
virtual ~ConfigResolver() {}
15+
16+
virtual const Config& getConfig(const ModuleName& name, const TypeCheckLimits& limits) const = 0;
17+
};
18+
19+
struct NullConfigResolver : ConfigResolver
20+
{
21+
Config defaultConfig;
22+
23+
virtual const Config& getConfig(const ModuleName& name, const TypeCheckLimits& limits) const override
24+
{
25+
return defaultConfig;
26+
}
27+
};
28+
29+
} // namespace Luau

Analysis/include/Luau/FileResolver.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
22
#pragma once
33

4+
#include "Luau/TypeCheckLimits.h"
5+
46
#include <memory>
57
#include <optional>
68
#include <string>
@@ -101,7 +103,7 @@ struct FileResolver
101103

102104
virtual std::optional<SourceCode> readSource(const ModuleName& name) = 0;
103105

104-
virtual std::optional<ModuleInfo> resolveModule(const ModuleInfo* context, AstExpr* expr)
106+
virtual std::optional<ModuleInfo> resolveModule(const ModuleInfo* context, AstExpr* expr, const TypeCheckLimits& limits)
105107
{
106108
return std::nullopt;
107109
}

Analysis/include/Luau/Frontend.h

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

44
#include "Luau/Config.h"
5+
#include "Luau/ConfigResolver.h"
56
#include "Luau/GlobalTypes.h"
67
#include "Luau/Module.h"
78
#include "Luau/ModuleResolver.h"
@@ -235,7 +236,7 @@ struct Frontend
235236
);
236237

237238
std::optional<CheckResult> getCheckResult(const ModuleName& name, bool accumulateNested, bool forAutocomplete = false);
238-
std::vector<ModuleName> getRequiredScripts(const ModuleName& name);
239+
std::vector<ModuleName> getRequiredScripts(const ModuleName& name, const TypeCheckLimits& limits);
239240

240241
private:
241242
ModulePtr check(
@@ -249,12 +250,13 @@ struct Frontend
249250
TypeCheckLimits typeCheckLimits
250251
);
251252

252-
std::pair<SourceNode*, SourceModule*> getSourceNode(const ModuleName& name);
253+
std::pair<SourceNode*, SourceModule*> getSourceNode(const ModuleName& name, const TypeCheckLimits& limits);
253254
SourceModule parse(const ModuleName& name, std::string_view src, const ParseOptions& parseOptions);
254255

255256
bool parseGraph(
256257
std::vector<ModuleName>& buildQueue,
257258
const ModuleName& root,
259+
const TypeCheckLimits& limits,
258260
bool forAutocomplete,
259261
std::function<bool(const ModuleName&)> canSkip = {}
260262
);

Analysis/include/Luau/Instantiation2.h

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

44
#include "Luau/NotNull.h"
55
#include "Luau/Substitution.h"
6+
#include "Luau/Subtyping.h"
67
#include "Luau/TxnLog.h"
78
#include "Luau/TypeFwd.h"
89
#include "Luau/Unifiable.h"
@@ -60,30 +61,70 @@ struct Instantiation2 final : Substitution
6061
// Mapping from generic type packs to `TypePack`s of free types to be used in instantiation.
6162
DenseHashMap<TypePackId, TypePackId> genericPackSubstitutions{nullptr};
6263

64+
// Make `NotNull` with LuauInstantiationUsesGenericPolarity
65+
Subtyping* subtyping = nullptr;
66+
Scope* scope = nullptr;
67+
6368
Instantiation2(TypeArena* arena, DenseHashMap<TypeId, TypeId> genericSubstitutions, DenseHashMap<TypePackId, TypePackId> genericPackSubstitutions)
6469
: Substitution(TxnLog::empty(), arena)
6570
, genericSubstitutions(std::move(genericSubstitutions))
6671
, genericPackSubstitutions(std::move(genericPackSubstitutions))
6772
{
6873
}
6974

75+
Instantiation2(
76+
TypeArena* arena,
77+
DenseHashMap<TypeId, TypeId> genericSubstitutions,
78+
DenseHashMap<TypePackId, TypePackId> genericPackSubstitutions,
79+
NotNull<Subtyping> subtyping,
80+
NotNull<Scope> scope
81+
)
82+
: Substitution(TxnLog::empty(), arena)
83+
, genericSubstitutions(std::move(genericSubstitutions))
84+
, genericPackSubstitutions(std::move(genericPackSubstitutions))
85+
, subtyping(subtyping)
86+
, scope(scope)
87+
{
88+
}
89+
7090
bool ignoreChildren(TypeId ty) override;
7191
bool isDirty(TypeId ty) override;
7292
bool isDirty(TypePackId tp) override;
7393
TypeId clean(TypeId ty) override;
7494
TypePackId clean(TypePackId tp) override;
7595
};
7696

97+
// Clip with LuauInstantiationUsesGenericPolarity
98+
std::optional<TypeId> instantiate2_DEPRECATED(
99+
TypeArena* arena,
100+
DenseHashMap<TypeId, TypeId> genericSubstitutions,
101+
DenseHashMap<TypePackId, TypePackId> genericPackSubstitutions,
102+
TypeId ty
103+
);
104+
105+
// Clip with LuauInstantiationUsesGenericPolarity
106+
std::optional<TypePackId> instantiate2_DEPRECATED(
107+
TypeArena* arena,
108+
DenseHashMap<TypeId, TypeId> genericSubstitutions,
109+
DenseHashMap<TypePackId, TypePackId> genericPackSubstitutions,
110+
TypePackId tp
111+
);
112+
77113
std::optional<TypeId> instantiate2(
78114
TypeArena* arena,
79115
DenseHashMap<TypeId, TypeId> genericSubstitutions,
80116
DenseHashMap<TypePackId, TypePackId> genericPackSubstitutions,
117+
NotNull<Subtyping> subtyping,
118+
NotNull<Scope> scope,
81119
TypeId ty
82120
);
121+
83122
std::optional<TypePackId> instantiate2(
84123
TypeArena* arena,
85124
DenseHashMap<TypeId, TypeId> genericSubstitutions,
86125
DenseHashMap<TypePackId, TypePackId> genericPackSubstitutions,
126+
NotNull<Subtyping> subtyping,
127+
NotNull<Scope> scope,
87128
TypePackId tp
88129
);
89130

Analysis/include/Luau/OverloadResolution.h

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,40 @@ struct Subtyping;
2222

2323
class Normalizer;
2424

25+
// There are essentially two reasons why we might consider an overload
26+
// to be unsuitable:
27+
//
28+
// First, subtyping might fail. This also includes cases where we
29+
// cannot find a generic substitution scheme that results in a
30+
// callable function.
31+
//
32+
// Second, subtyping might succeed, but it might result in the
33+
// presence of an unreducible type function. (eg add<string, string>)
34+
//
35+
// TODO: Subtyping should probably also be the thing that checks for
36+
// unreducible type functions. This would be nice because it would
37+
// mean that overload resolution would not have to talk about type
38+
// functions at all.
39+
using IncompatibilityReason = Variant<SubtypingReasonings, ErrorVec>;
40+
41+
struct OverloadResolution
42+
{
43+
// Overloads that will work
44+
std::vector<TypeId> ok;
45+
46+
// "Overloads" that aren't callable.
47+
std::vector<TypeId> nonFunctions;
48+
49+
// Overloads that could match, but require that other constraints also be satisfied.
50+
std::vector<std::pair<TypeId, std::vector<ConstraintV>>> potentialOverloads;
51+
52+
// Overloads that have the correct arity, but do not work.
53+
std::vector<std::pair<TypeId, IncompatibilityReason>> incompatibleOverloads;
54+
55+
// Overloads that will never work specifically because of an arity mismatch.
56+
std::vector<TypeId> arityMismatches;
57+
};
58+
2559
struct OverloadResolver
2660
{
2761
enum Analysis
@@ -62,7 +96,44 @@ struct OverloadResolver
6296
std::vector<std::pair<TypeId, ErrorVec>> nonviableOverloads;
6397
InsertionOrderedMap<TypeId, std::pair<OverloadResolver::Analysis, size_t>> resolution;
6498

65-
std::pair<OverloadResolver::Analysis, TypeId> selectOverload(
99+
// Given a (potentially overloaded) function and a set of arguments, test each overload.
100+
OverloadResolution resolveOverload(
101+
TypeId fnTy,
102+
TypePackId args,
103+
Location fnLocation,
104+
NotNull<DenseHashSet<TypeId>> uniqueTypes,
105+
bool useFreeTypeBounds
106+
);
107+
108+
void reportErrors(
109+
ErrorVec& errors,
110+
TypeId fnTy,
111+
Location fnLocation,
112+
const ModuleName& moduleName,
113+
TypePackId argPack,
114+
const std::vector<AstExpr*>& argExprs,
115+
const SubtypingReasoning& reason
116+
) const;
117+
118+
private:
119+
void testFunction(
120+
OverloadResolution& result,
121+
TypeId fnTy,
122+
TypePackId argsPack,
123+
Location fnLocation,
124+
NotNull<DenseHashSet<TypeId>> uniqueTypes
125+
);
126+
127+
void testFunctionOrCallMetamethod(
128+
OverloadResolution& result,
129+
TypeId fnTy,
130+
TypePackId argsPack,
131+
Location fnLocation,
132+
NotNull<DenseHashSet<TypeId>> uniqueTypes
133+
);
134+
135+
public:
136+
std::pair<Analysis, TypeId> selectOverload(
66137
TypeId ty,
67138
TypePackId args,
68139
NotNull<DenseHashSet<TypeId>> uniqueTypes,
@@ -104,8 +175,35 @@ struct OverloadResolver
104175
ErrorVec* errors,
105176
Location argLocation,
106177
const SubtypingReasoning* reason,
107-
std::optional<TypeId> failedSubTy,
108-
std::optional<TypeId> failedSuperTy
178+
std::optional<TypeId> wantedTy,
179+
std::optional<TypeId> givenTy
180+
) const;
181+
182+
void maybeEmplaceError(
183+
ErrorVec* errors,
184+
Location argLocation,
185+
const ModuleName& moduleName,
186+
const SubtypingReasoning* reason,
187+
std::optional<TypeId> wantedTy,
188+
std::optional<TypeId> givenTy
189+
) const;
190+
191+
void maybeEmplaceError(
192+
ErrorVec* errors,
193+
Location argLocation,
194+
const ModuleName& moduleName,
195+
const SubtypingReasoning* reason,
196+
std::optional<TypePackId> wantedTp,
197+
std::optional<TypePackId> givenTp
198+
) const;
199+
200+
void maybeEmplaceError(
201+
ErrorVec* errors,
202+
Location argLocation,
203+
const ModuleName& moduleName,
204+
const SubtypingReasoning* reason,
205+
std::optional<TypeOrPack> wantedType,
206+
std::optional<TypeOrPack> givenType
109207
) const;
110208

111209
// Checks if the candidate args are arity-compatible with the desired parameters.

Analysis/include/Luau/RecursionCounter.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,14 @@ struct RecursionLimiter : RecursionCounter
3737
RecursionLimiter(const std::string& system, int* count, int limit);
3838
};
3939

40+
struct NonExceptionalRecursionLimiter : RecursionCounter
41+
{
42+
NativeStackGuard nativeStackGuard;
43+
44+
bool isOk(int limit) const;
45+
46+
NonExceptionalRecursionLimiter(int* count);
47+
48+
};
49+
4050
} // namespace Luau

Analysis/include/Luau/RequireTracer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ struct RequireTraceResult
2121
std::vector<std::pair<ModuleName, Location>> requireList;
2222
};
2323

24-
RequireTraceResult traceRequires(FileResolver* fileResolver, AstStatBlock* root, const ModuleName& currentModuleName);
24+
RequireTraceResult traceRequires(FileResolver* fileResolver, AstStatBlock* root, const ModuleName& currentModuleName, const TypeCheckLimits& limits);
2525

2626
} // namespace Luau

Analysis/include/Luau/Subtyping.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ struct SubtypingResult
117117
// If this subtype result required testing free types, we might be making
118118
// assumptions about what the free type eventually resolves to. If so,
119119
// those assumptions are recorded here.
120-
std::vector<SubtypeConstraint> assumedConstraints;
120+
std::vector<ConstraintV> assumedConstraints;
121121

122122
/// If any generic bounds were invalid, report them here
123123
std::vector<GenericBoundsMismatch> genericBoundsMismatches;
@@ -211,15 +211,6 @@ struct Subtyping
211211
// a covariant test where an invariant test would otherwise be required.
212212
const DenseHashSet<TypeId>* uniqueTypes = nullptr;
213213

214-
enum class Variance
215-
{
216-
Covariant,
217-
Contravariant
218-
};
219-
220-
// TODO: Clip in CLI-170986
221-
Variance variance = Variance::Covariant;
222-
223214
using SeenSet = Set<std::pair<TypeId, TypeId>, TypePairHash>;
224215
using SeenTypePackSet = Set<std::pair<TypePackId, TypePackId>, TypePairHash>;
225216

@@ -252,7 +243,19 @@ struct Subtyping
252243
// TODO recursion limits
253244

254245
SubtypingResult isSubtype(TypeId subTy, TypeId superTy, NotNull<Scope> scope);
255-
SubtypingResult isSubtype(TypePackId subTp, TypePackId superTp, NotNull<Scope> scope, const std::vector<TypeId>& bindableGenerics);
246+
SubtypingResult isSubtype(
247+
TypePackId subTp,
248+
TypePackId superTp,
249+
NotNull<Scope> scope,
250+
const std::vector<TypeId>& bindableGenerics
251+
);
252+
SubtypingResult isSubtype(
253+
TypePackId subTp,
254+
TypePackId superTp,
255+
NotNull<Scope> scope,
256+
const std::vector<TypeId>& bindableGenerics,
257+
const std::vector<TypePackId>& bindableGenericPacks
258+
);
256259
// Clip with FFlagLuauPassBindableGenericsByReference
257260
SubtypingResult isSubtype_DEPRECATED(
258261
TypePackId subTp,

Analysis/src/AstQuery.cpp

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

1414
LUAU_FASTFLAG(LuauSolverV2)
15-
LUAU_FASTFLAGVARIABLE(LuauUnfinishedRepeatAncestryFix)
1615

1716
namespace Luau
1817
{
@@ -32,22 +31,11 @@ struct AutocompleteNodeFinder : public AstVisitor
3231

3332
bool visit(AstExpr* expr) override
3433
{
35-
if (FFlag::LuauUnfinishedRepeatAncestryFix)
34+
// If the expression size is 0 (begin == end), we don't want to include it in the ancestry
35+
if (expr->location.begin <= pos && pos <= expr->location.end && expr->location.begin != expr->location.end)
3636
{
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-
}
37+
ancestry.push_back(expr);
38+
return true;
5139
}
5240
return false;
5341
}

0 commit comments

Comments
 (0)