Skip to content

Commit 6b33251

Browse files
ayoungbloodrbxhgoldsteinvrn-snmenarulalamAviral Goel
authored
Sync to upstream/release/667 (#1754)
After a very auspicious release last week, we have a new bevy of changes for you! ## What's Changed ### Deprecated Attribute This release includes an implementation of the `@deprecated` attribute proposed in [this RFC](https://rfcs.luau.org/syntax-attribute-functions-deprecated.html). It relies on the new type solver to propagate deprecation information from function and method AST nodes to the corresponding type objects. These objects are queried by a linter pass when it encounters local, global, or indexed variables, to issue deprecation warnings. Uses of deprecated functions and methods in recursion are ignored. To support deprecation of class methods, the parser has been extended to allow attribute declarations on class methods. The implementation does not support parameters, so it is not currently possible for users to customize deprecation messages. ### General - Add a limit for normalization of function types. ### New Type Solver - Fix type checker to accept numbers as concat operands (Fixes #1671). - Fix user-defined type functions failing when used inside type aliases/nested calls (Fixes #1738, Fixes #1679). - Improve constraint generation for overloaded functions (in part thanks to @vvatheus in #1694). - Improve type inference for indexers on table literals, especially when passing table literals directly as a function call argument. - Equate regular error type and intersection with a negation of an error type. - Avoid swapping types in 2-part union when RHS is optional. - Use simplification when doing `~nil` refinements. - `len<>` now works on metatables without `__len` function. ### AST - Retain source information for `AstTypeUnion` and `AstTypeIntersection`. ### Transpiler - Print attributes on functions. ### Parser - Allow types in indexers to begin with string literals by @jackdotink in #1750. ### Autocomplete - Evaluate user-defined type functions in ill-formed source code to provide autocomplete. - Fix the start location of functions that have attributes. - Implement better fragment selection. ### Internal Contributors Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Ariel Weiss <aaronweiss@roblox.com> Co-authored-by: Aviral Goel <agoel@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> **Full Changelog**: 0.666...0.667 --------- Co-authored-by: Hunter Goldstein <hgoldstein@roblox.com> Co-authored-by: Varun Saini <61795485+vrn-sn@users.noreply.github.com> Co-authored-by: Menarul Alam <malam@roblox.com> Co-authored-by: Aviral Goel <agoel@roblox.com> Co-authored-by: Vighnesh <vvijay@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com> Co-authored-by: Ariel Weiss <aaronweiss@roblox.com>
1 parent 12dac2f commit 6b33251

59 files changed

Lines changed: 3959 additions & 2747 deletions

Some content is hidden

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

Analysis/include/Luau/AnyTypeSummary.h

Lines changed: 0 additions & 148 deletions
This file was deleted.

Analysis/include/Luau/Constraint.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct GeneralizationConstraint
5050
TypeId sourceType;
5151

5252
std::vector<TypeId> interiorTypes;
53+
bool hasDeprecatedAttribute = false;
5354
};
5455

5556
// variables ~ iterate iterator

Analysis/include/Luau/ConstraintSolver.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ struct ConstraintSolver
365365
* @returns a non-free type that generalizes the argument, or `std::nullopt` if one
366366
* does not exist
367367
*/
368-
std::optional<TypeId> generalizeFreeType(NotNull<Scope> scope, TypeId type, bool avoidSealingTables = false);
368+
std::optional<TypeId> generalizeFreeType(NotNull<Scope> scope, TypeId type);
369369

370370
/**
371371
* Checks the existing set of constraints to see if there exist any that contain

Analysis/include/Luau/DataFlowGraph.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ struct DataFlowGraph
3838
DefId getDef(const AstExpr* expr) const;
3939
// Look up the definition optionally, knowing it may not be present.
4040
std::optional<DefId> getDefOptional(const AstExpr* expr) const;
41-
// Look up for the rvalue def for a compound assignment.
42-
std::optional<DefId> getRValueDefForCompoundAssign(const AstExpr* expr) const;
4341

4442
DefId getDef(const AstLocal* local) const;
4543

@@ -66,10 +64,6 @@ struct DataFlowGraph
6664
// All keys in this maps are really only statements that ambiently declares a symbol.
6765
DenseHashMap<const AstStat*, const Def*> declaredDefs{nullptr};
6866

69-
// Compound assignments are in a weird situation where the local being assigned to is also being used at its
70-
// previous type implicitly in an rvalue position. This map provides the previous binding.
71-
DenseHashMap<const AstExpr*, const Def*> compoundAssignDefs{nullptr};
72-
7367
DenseHashMap<const AstExpr*, const RefinementKey*> astRefinementKeys{nullptr};
7468
friend struct DataFlowGraphBuilder;
7569
};

Analysis/include/Luau/FragmentAutocomplete.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ struct FragmentAutocompleteAncestryResult
4949
std::vector<AstLocal*> localStack;
5050
std::vector<AstNode*> ancestry;
5151
AstStat* nearestStatement = nullptr;
52+
AstStatBlock* parentBlock = nullptr;
53+
Location fragmentSelectionRegion;
5254
};
5355

5456
struct FragmentParseResult
@@ -59,6 +61,7 @@ struct FragmentParseResult
5961
AstStat* nearestStatement = nullptr;
6062
std::vector<Comment> commentLocations;
6163
std::unique_ptr<Allocator> alloc = std::make_unique<Allocator>();
64+
Position scopePos{0, 0};
6265
};
6366

6467
struct FragmentTypeCheckResult
@@ -76,23 +79,42 @@ struct FragmentAutocompleteResult
7679
AutocompleteResult acResults;
7780
};
7881

79-
FragmentAutocompleteAncestryResult findAncestryForFragmentParse(AstStatBlock* root, const Position& cursorPos);
82+
struct FragmentRegion
83+
{
84+
Location fragmentLocation;
85+
AstStat* nearestStatement = nullptr; // used for tests
86+
AstStatBlock* parentBlock = nullptr; // used for scope detection
87+
};
8088

81-
std::optional<FragmentParseResult> parseFragment(
89+
FragmentRegion getFragmentRegion(AstStatBlock* root, const Position& cursorPosition);
90+
FragmentAutocompleteAncestryResult findAncestryForFragmentParse(AstStatBlock* stale, const Position& cursorPos, AstStatBlock* lastGoodParse);
91+
FragmentAutocompleteAncestryResult findAncestryForFragmentParse_DEPRECATED(AstStatBlock* root, const Position& cursorPos);
92+
93+
std::optional<FragmentParseResult> parseFragment_DEPRECATED(
8294
AstStatBlock* root,
8395
AstNameTable* names,
8496
std::string_view src,
8597
const Position& cursorPos,
8698
std::optional<Position> fragmentEndPosition
8799
);
88100

101+
std::optional<FragmentParseResult> parseFragment(
102+
AstStatBlock* stale,
103+
AstStatBlock* mostRecentParse,
104+
AstNameTable* names,
105+
std::string_view src,
106+
const Position& cursorPos,
107+
std::optional<Position> fragmentEndPosition
108+
);
109+
89110
std::pair<FragmentTypeCheckStatus, FragmentTypeCheckResult> typecheckFragment(
90111
Frontend& frontend,
91112
const ModuleName& moduleName,
92113
const Position& cursorPos,
93114
std::optional<FrontendOptions> opts,
94115
std::string_view src,
95116
std::optional<Position> fragmentEndPosition,
117+
AstStatBlock* recentParse = nullptr,
96118
IFragmentAutocompleteReporter* reporter = nullptr
97119
);
98120

@@ -104,6 +126,7 @@ FragmentAutocompleteResult fragmentAutocomplete(
104126
std::optional<FrontendOptions> opts,
105127
StringCompletionCallback callback,
106128
std::optional<Position> fragmentEndPosition = std::nullopt,
129+
AstStatBlock* recentParse = nullptr,
107130
IFragmentAutocompleteReporter* reporter = nullptr
108131
);
109132

Analysis/include/Luau/Frontend.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "Luau/Set.h"
1111
#include "Luau/TypeCheckLimits.h"
1212
#include "Luau/Variant.h"
13-
#include "Luau/AnyTypeSummary.h"
1413

1514
#include <mutex>
1615
#include <string>
@@ -34,7 +33,6 @@ struct HotComment;
3433
struct BuildQueueItem;
3534
struct BuildQueueWorkState;
3635
struct FrontendCancellationToken;
37-
struct AnyTypeSummary;
3836

3937
struct LoadDefinitionFileResult
4038
{

Analysis/include/Luau/Generalization.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ std::optional<TypeId> generalize(
1313
NotNull<BuiltinTypes> builtinTypes,
1414
NotNull<Scope> scope,
1515
NotNull<DenseHashSet<TypeId>> cachedTypes,
16-
TypeId ty,
17-
/* avoid sealing tables*/ bool avoidSealingTables = false
16+
TypeId ty
1817
);
1918

2019
}

Analysis/include/Luau/Module.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include "Luau/ParseResult.h"
99
#include "Luau/Scope.h"
1010
#include "Luau/TypeArena.h"
11-
#include "Luau/AnyTypeSummary.h"
1211
#include "Luau/DataFlowGraph.h"
1312

1413
#include <memory>
@@ -21,14 +20,13 @@ LUAU_FASTFLAG(LuauIncrementalAutocompleteCommentDetection)
2120
namespace Luau
2221
{
2322

24-
using LogLuauProc = void (*)(std::string_view);
23+
using LogLuauProc = void (*)(std::string_view, std::string_view);
2524
extern LogLuauProc logLuau;
2625

2726
void setLogLuau(LogLuauProc ll);
2827
void resetLogLuauProc();
2928

3029
struct Module;
31-
struct AnyTypeSummary;
3230

3331
using ScopePtr = std::shared_ptr<struct Scope>;
3432
using ModulePtr = std::shared_ptr<Module>;
@@ -86,10 +84,6 @@ struct Module
8684
TypeArena interfaceTypes;
8785
TypeArena internalTypes;
8886

89-
// Summary of Ast Nodes that either contain
90-
// user annotated anys or typechecker inferred anys
91-
AnyTypeSummary ats{};
92-
9387
// Scopes and AST types refer to parse data, so we need to keep that alive
9488
std::shared_ptr<Allocator> allocator;
9589
std::shared_ptr<AstNameTable> names;

Analysis/include/Luau/NonStrictTypeChecker.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +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/DataFlowGraph.h"
5+
#include "Luau/EqSatSimplification.h"
46
#include "Luau/Module.h"
57
#include "Luau/NotNull.h"
6-
#include "Luau/DataFlowGraph.h"
78

89
namespace Luau
910
{

Analysis/include/Luau/Type.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include <optional>
2020
#include <set>
2121
#include <string>
22-
#include <unordered_map>
2322
#include <vector>
2423

2524
LUAU_FASTINT(LuauTableTypeMaximumStringifierLength)
@@ -38,6 +37,15 @@ struct Constraint;
3837
struct Subtyping;
3938
struct TypeChecker2;
4039

40+
enum struct Polarity : uint8_t
41+
{
42+
None = 0b000,
43+
Positive = 0b001,
44+
Negative = 0b010,
45+
Mixed = 0b011,
46+
Unknown = 0b100,
47+
};
48+
4149
/**
4250
* There are three kinds of type variables:
4351
* - `Free` variables are metavariables, which stand for unconstrained types.
@@ -396,6 +404,7 @@ struct FunctionType
396404
// this flag is used as an optimization to exit early from procedures that manipulate free or generic types.
397405
bool hasNoFreeOrGenericTypes = false;
398406
bool isCheckedFunction = false;
407+
bool isDeprecatedFunction = false;
399408
};
400409

401410
enum class TableState

0 commit comments

Comments
 (0)