Skip to content

Commit a36a3c4

Browse files
hgoldsteinaatxeandyfriesendcope-rbxvrn-sn
authored
Sync to upstream/release/651 (#1513)
### What's New? * Fragment Autocomplete: a new API allows for type checking a small fragment of code against an existing file, significantly speeding up autocomplete performance in large files. ### New Solver * E-Graphs have landed: this is an ongoing approach to make the new type solver simplify types in a more consistent and principled manner, based on similar work (see: https://egraphs-good.github.io/). * Adds support for exporting / local user type functions (previously they were always exported). * Fixes a set of bugs in which the new solver will fail to complete inference for simple expressions with just literals and operators. ### General Updates * Requiring a path with a ".lua" or ".luau" extension will now have a bespoke error suggesting to remove said extension. * Fixes a bug in which whether two `Luau::Symbol`s are equal depends on whether the new solver is enabled. --- Internal Contributors: Co-authored-by: Aaron Weiss <[email protected]> Co-authored-by: Andy Friesen <[email protected]> Co-authored-by: David Cope <[email protected]> Co-authored-by: Hunter Goldstein <[email protected]> Co-authored-by: Varun Saini <[email protected]> Co-authored-by: Vighnesh Vijay <[email protected]> Co-authored-by: Vyacheslav Egorov <[email protected]>
1 parent 26b2307 commit a36a3c4

Some content is hidden

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

62 files changed

+7315
-2456
lines changed

Analysis/include/Luau/Autocomplete.h

+2-84
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
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/AutocompleteTypes.h"
45
#include "Luau/Location.h"
56
#include "Luau/Type.h"
67

7-
#include <unordered_map>
88
#include <string>
99
#include <memory>
1010
#include <optional>
@@ -16,90 +16,8 @@ struct Frontend;
1616
struct SourceModule;
1717
struct Module;
1818
struct TypeChecker;
19-
20-
using ModulePtr = std::shared_ptr<Module>;
21-
22-
enum class AutocompleteContext
23-
{
24-
Unknown,
25-
Expression,
26-
Statement,
27-
Property,
28-
Type,
29-
Keyword,
30-
String,
31-
};
32-
33-
enum class AutocompleteEntryKind
34-
{
35-
Property,
36-
Binding,
37-
Keyword,
38-
String,
39-
Type,
40-
Module,
41-
GeneratedFunction,
42-
RequirePath,
43-
};
44-
45-
enum class ParenthesesRecommendation
46-
{
47-
None,
48-
CursorAfter,
49-
CursorInside,
50-
};
51-
52-
enum class TypeCorrectKind
53-
{
54-
None,
55-
Correct,
56-
CorrectFunctionResult,
57-
};
58-
59-
struct AutocompleteEntry
60-
{
61-
AutocompleteEntryKind kind = AutocompleteEntryKind::Property;
62-
// Nullopt if kind is Keyword
63-
std::optional<TypeId> type = std::nullopt;
64-
bool deprecated = false;
65-
// Only meaningful if kind is Property.
66-
bool wrongIndexType = false;
67-
// Set if this suggestion matches the type expected in the context
68-
TypeCorrectKind typeCorrect = TypeCorrectKind::None;
69-
70-
std::optional<const ClassType*> containingClass = std::nullopt;
71-
std::optional<const Property*> prop = std::nullopt;
72-
std::optional<std::string> documentationSymbol = std::nullopt;
73-
Tags tags;
74-
ParenthesesRecommendation parens = ParenthesesRecommendation::None;
75-
std::optional<std::string> insertText;
76-
77-
// Only meaningful if kind is Property.
78-
bool indexedWithSelf = false;
79-
};
80-
81-
using AutocompleteEntryMap = std::unordered_map<std::string, AutocompleteEntry>;
82-
struct AutocompleteResult
83-
{
84-
AutocompleteEntryMap entryMap;
85-
std::vector<AstNode*> ancestry;
86-
AutocompleteContext context = AutocompleteContext::Unknown;
87-
88-
AutocompleteResult() = default;
89-
AutocompleteResult(AutocompleteEntryMap entryMap, std::vector<AstNode*> ancestry, AutocompleteContext context)
90-
: entryMap(std::move(entryMap))
91-
, ancestry(std::move(ancestry))
92-
, context(context)
93-
{
94-
}
95-
};
96-
97-
using ModuleName = std::string;
98-
using StringCompletionCallback =
99-
std::function<std::optional<AutocompleteEntryMap>(std::string tag, std::optional<const ClassType*> ctx, std::optional<std::string> contents)>;
19+
struct FileResolver;
10020

10121
AutocompleteResult autocomplete(Frontend& frontend, const ModuleName& moduleName, Position position, StringCompletionCallback callback);
10222

103-
constexpr char kGeneratedAnonymousFunctionEntryName[] = "function (anonymous autofilled)";
104-
10523
} // namespace Luau
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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/Ast.h"
5+
#include "Luau/Type.h"
6+
7+
#include <unordered_map>
8+
9+
namespace Luau
10+
{
11+
12+
enum class AutocompleteContext
13+
{
14+
Unknown,
15+
Expression,
16+
Statement,
17+
Property,
18+
Type,
19+
Keyword,
20+
String,
21+
};
22+
23+
enum class AutocompleteEntryKind
24+
{
25+
Property,
26+
Binding,
27+
Keyword,
28+
String,
29+
Type,
30+
Module,
31+
GeneratedFunction,
32+
RequirePath,
33+
};
34+
35+
enum class ParenthesesRecommendation
36+
{
37+
None,
38+
CursorAfter,
39+
CursorInside,
40+
};
41+
42+
enum class TypeCorrectKind
43+
{
44+
None,
45+
Correct,
46+
CorrectFunctionResult,
47+
};
48+
49+
struct AutocompleteEntry
50+
{
51+
AutocompleteEntryKind kind = AutocompleteEntryKind::Property;
52+
// Nullopt if kind is Keyword
53+
std::optional<TypeId> type = std::nullopt;
54+
bool deprecated = false;
55+
// Only meaningful if kind is Property.
56+
bool wrongIndexType = false;
57+
// Set if this suggestion matches the type expected in the context
58+
TypeCorrectKind typeCorrect = TypeCorrectKind::None;
59+
60+
std::optional<const ClassType*> containingClass = std::nullopt;
61+
std::optional<const Property*> prop = std::nullopt;
62+
std::optional<std::string> documentationSymbol = std::nullopt;
63+
Tags tags;
64+
ParenthesesRecommendation parens = ParenthesesRecommendation::None;
65+
std::optional<std::string> insertText;
66+
67+
// Only meaningful if kind is Property.
68+
bool indexedWithSelf = false;
69+
};
70+
71+
using AutocompleteEntryMap = std::unordered_map<std::string, AutocompleteEntry>;
72+
struct AutocompleteResult
73+
{
74+
AutocompleteEntryMap entryMap;
75+
std::vector<AstNode*> ancestry;
76+
AutocompleteContext context = AutocompleteContext::Unknown;
77+
78+
AutocompleteResult() = default;
79+
AutocompleteResult(AutocompleteEntryMap entryMap, std::vector<AstNode*> ancestry, AutocompleteContext context)
80+
: entryMap(std::move(entryMap))
81+
, ancestry(std::move(ancestry))
82+
, context(context)
83+
{
84+
}
85+
};
86+
87+
using StringCompletionCallback =
88+
std::function<std::optional<AutocompleteEntryMap>(std::string tag, std::optional<const ClassType*> ctx, std::optional<std::string> contents)>;
89+
90+
constexpr char kGeneratedAnonymousFunctionEntryName[] = "function (anonymous autofilled)";
91+
92+
} // namespace Luau

Analysis/include/Luau/ConstraintGenerator.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "Luau/Constraint.h"
66
#include "Luau/ControlFlow.h"
77
#include "Luau/DataFlowGraph.h"
8+
#include "Luau/EqSatSimplification.h"
89
#include "Luau/InsertionOrderedMap.h"
910
#include "Luau/Module.h"
1011
#include "Luau/ModuleResolver.h"
@@ -15,7 +16,6 @@
1516
#include "Luau/TypeFwd.h"
1617
#include "Luau/TypeUtils.h"
1718
#include "Luau/Variant.h"
18-
#include "Luau/Normalize.h"
1919

2020
#include <memory>
2121
#include <vector>
@@ -109,6 +109,9 @@ struct ConstraintGenerator
109109

110110
// Needed to be able to enable error-suppression preservation for immediate refinements.
111111
NotNull<Normalizer> normalizer;
112+
113+
NotNull<Simplifier> simplifier;
114+
112115
// Needed to register all available type functions for execution at later stages.
113116
NotNull<TypeFunctionRuntime> typeFunctionRuntime;
114117
// Needed to resolve modules to make 'require' import types properly.
@@ -128,6 +131,7 @@ struct ConstraintGenerator
128131
ConstraintGenerator(
129132
ModulePtr module,
130133
NotNull<Normalizer> normalizer,
134+
NotNull<Simplifier> simplifier,
131135
NotNull<TypeFunctionRuntime> typeFunctionRuntime,
132136
NotNull<ModuleResolver> moduleResolver,
133137
NotNull<BuiltinTypes> builtinTypes,
@@ -405,6 +409,7 @@ struct ConstraintGenerator
405409
TypeId makeUnion(const ScopePtr& scope, Location location, TypeId lhs, TypeId rhs);
406410
// make an intersect type function of these two types
407411
TypeId makeIntersect(const ScopePtr& scope, Location location, TypeId lhs, TypeId rhs);
412+
void prepopulateGlobalScopeForFragmentTypecheck(const ScopePtr& globalScope, const ScopePtr& resumeScope, AstStatBlock* program);
408413

409414
/** Scan the program for global definitions.
410415
*
@@ -435,6 +440,8 @@ struct ConstraintGenerator
435440
const ScopePtr& scope,
436441
Location location
437442
);
443+
444+
TypeId simplifyUnion(const ScopePtr& scope, Location location, TypeId left, TypeId right);
438445
};
439446

440447
/** Borrow a vector of pointers from a vector of owning pointers to constraints.

Analysis/include/Luau/ConstraintSolver.h

+7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "Luau/Constraint.h"
66
#include "Luau/DataFlowGraph.h"
77
#include "Luau/DenseHash.h"
8+
#include "Luau/EqSatSimplification.h"
89
#include "Luau/Error.h"
910
#include "Luau/Location.h"
1011
#include "Luau/Module.h"
@@ -64,6 +65,7 @@ struct ConstraintSolver
6465
NotNull<BuiltinTypes> builtinTypes;
6566
InternalErrorReporter iceReporter;
6667
NotNull<Normalizer> normalizer;
68+
NotNull<Simplifier> simplifier;
6769
NotNull<TypeFunctionRuntime> typeFunctionRuntime;
6870
// The entire set of constraints that the solver is trying to resolve.
6971
std::vector<NotNull<Constraint>> constraints;
@@ -117,6 +119,7 @@ struct ConstraintSolver
117119

118120
explicit ConstraintSolver(
119121
NotNull<Normalizer> normalizer,
122+
NotNull<Simplifier> simplifier,
120123
NotNull<TypeFunctionRuntime> typeFunctionRuntime,
121124
NotNull<Scope> rootScope,
122125
std::vector<NotNull<Constraint>> constraints,
@@ -384,6 +387,10 @@ struct ConstraintSolver
384387
**/
385388
void reproduceConstraints(NotNull<Scope> scope, const Location& location, const Substitution& subst);
386389

390+
TypeId simplifyIntersection(NotNull<Scope> scope, Location location, TypeId left, TypeId right);
391+
TypeId simplifyIntersection(NotNull<Scope> scope, Location location, std::set<TypeId> parts);
392+
TypeId simplifyUnion(NotNull<Scope> scope, Location location, TypeId left, TypeId right);
393+
387394
TypeId errorRecoveryType() const;
388395
TypePackId errorRecoveryTypePack() const;
389396

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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/TypeFwd.h"
6+
#include "Luau/NotNull.h"
7+
#include "Luau/DenseHash.h"
8+
9+
#include <memory>
10+
#include <optional>
11+
#include <vector>
12+
13+
namespace Luau
14+
{
15+
struct TypeArena;
16+
}
17+
18+
// The EqSat stuff is pretty template heavy, so we go to some lengths to prevent
19+
// the complexity from leaking outside its implementation sources.
20+
namespace Luau::EqSatSimplification
21+
{
22+
23+
struct Simplifier;
24+
25+
using SimplifierPtr = std::unique_ptr<Simplifier, void (*)(Simplifier*)>;
26+
27+
SimplifierPtr newSimplifier(NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtinTypes);
28+
29+
} // namespace Luau::EqSatSimplification
30+
31+
namespace Luau
32+
{
33+
34+
struct EqSatSimplificationResult
35+
{
36+
TypeId result;
37+
38+
// New type function applications that were created by the reduction phase.
39+
// We return these so that the ConstraintSolver can know to try to reduce
40+
// them.
41+
std::vector<TypeId> newTypeFunctions;
42+
};
43+
44+
using EqSatSimplification::newSimplifier; // NOLINT: clang-tidy thinks these are unused. It is incorrect.
45+
using Luau::EqSatSimplification::Simplifier; // NOLINT
46+
using Luau::EqSatSimplification::SimplifierPtr;
47+
48+
std::optional<EqSatSimplificationResult> eqSatSimplify(NotNull<Simplifier> simplifier, TypeId ty);
49+
50+
} // namespace Luau

0 commit comments

Comments
 (0)