Skip to content

Commit

Permalink
Sync to upstream/release/510 (#313)
Browse files Browse the repository at this point in the history
  • Loading branch information
zeux authored Jan 14, 2022
1 parent b2af550 commit 32c39e2
Show file tree
Hide file tree
Showing 47 changed files with 2,638 additions and 1,258 deletions.
12 changes: 9 additions & 3 deletions Analysis/include/Luau/TypeInfer.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ struct ApplyTypeFunction : Substitution
TypePackId clean(TypePackId tp) override;
};

struct GenericTypeDefinitions
{
std::vector<GenericTypeDefinition> genericTypes;
std::vector<GenericTypePackDefinition> genericPacks;
};

// All TypeVars are retained via Environment::typeVars. All TypeIds
// within a program are borrowed pointers into this set.
struct TypeChecker
Expand Down Expand Up @@ -146,7 +152,7 @@ struct TypeChecker
ExprResult<TypeId> checkExpr(const ScopePtr& scope, const AstExprBinary& expr);
ExprResult<TypeId> checkExpr(const ScopePtr& scope, const AstExprTypeAssertion& expr);
ExprResult<TypeId> checkExpr(const ScopePtr& scope, const AstExprError& expr);
ExprResult<TypeId> checkExpr(const ScopePtr& scope, const AstExprIfElse& expr);
ExprResult<TypeId> checkExpr(const ScopePtr& scope, const AstExprIfElse& expr, std::optional<TypeId> expectedType = std::nullopt);

TypeId checkExprTable(const ScopePtr& scope, const AstExprTable& expr, const std::vector<std::pair<TypeId, TypeId>>& fieldTypes,
std::optional<TypeId> expectedType);
Expand Down Expand Up @@ -336,8 +342,8 @@ struct TypeChecker
const std::vector<TypePackId>& typePackParams, const Location& location);

// Note: `scope` must be a fresh scope.
std::pair<std::vector<TypeId>, std::vector<TypePackId>> createGenericTypes(const ScopePtr& scope, std::optional<TypeLevel> levelOpt,
const AstNode& node, const AstArray<AstName>& genericNames, const AstArray<AstName>& genericPackNames);
GenericTypeDefinitions createGenericTypes(const ScopePtr& scope, std::optional<TypeLevel> levelOpt, const AstNode& node,
const AstArray<AstGenericType>& genericNames, const AstArray<AstGenericTypePack>& genericPackNames);

public:
ErrorVec resolve(const PredicateVec& predicates, const ScopePtr& scope, bool sense);
Expand Down
20 changes: 16 additions & 4 deletions Analysis/include/Luau/TypeVar.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,18 @@ const T* get(const SingletonTypeVar* stv)
return nullptr;
}

struct GenericTypeDefinition
{
TypeId ty;
std::optional<TypeId> defaultValue;
};

struct GenericTypePackDefinition
{
TypePackId tp;
std::optional<TypePackId> defaultValue;
};

struct FunctionArgument
{
Name name;
Expand Down Expand Up @@ -358,8 +370,8 @@ struct ClassTypeVar
struct TypeFun
{
// These should all be generic
std::vector<TypeId> typeParams;
std::vector<TypePackId> typePackParams;
std::vector<GenericTypeDefinition> typeParams;
std::vector<GenericTypePackDefinition> typePackParams;

/** The underlying type.
*
Expand All @@ -369,13 +381,13 @@ struct TypeFun
TypeId type;

TypeFun() = default;
TypeFun(std::vector<TypeId> typeParams, TypeId type)
TypeFun(std::vector<GenericTypeDefinition> typeParams, TypeId type)
: typeParams(std::move(typeParams))
, type(type)
{
}

TypeFun(std::vector<TypeId> typeParams, std::vector<TypePackId> typePackParams, TypeId type)
TypeFun(std::vector<GenericTypeDefinition> typeParams, std::vector<GenericTypePackDefinition> typePackParams, TypeId type)
: typeParams(std::move(typeParams))
, typePackParams(std::move(typePackParams))
, type(type)
Expand Down
79 changes: 32 additions & 47 deletions Analysis/src/Autocomplete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@
#include <utility>

LUAU_FASTFLAG(LuauUseCommittingTxnLog)
LUAU_FASTFLAG(LuauIfElseExpressionAnalysisSupport)
LUAU_FASTFLAGVARIABLE(LuauAutocompleteAvoidMutation, false);
LUAU_FASTFLAGVARIABLE(LuauAutocompletePreferToCallFunctions, false);
LUAU_FASTFLAGVARIABLE(LuauAutocompleteFirstArg, false);
LUAU_FASTFLAGVARIABLE(LuauCompleteBrokenStringParams, false);
LUAU_FASTFLAGVARIABLE(LuauMissingFollowACMetatables, false);

static const std::unordered_set<std::string> kStatementStartingKeywords = {
"while", "if", "local", "repeat", "function", "do", "for", "return", "break", "continue", "type", "export"};
Expand Down Expand Up @@ -291,51 +290,23 @@ static TypeCorrectKind checkTypeCorrectKind(const Module& module, TypeArena* typ
expectedType = follow(*it);
}

if (FFlag::LuauAutocompletePreferToCallFunctions)
// We also want to suggest functions that return compatible result
if (const FunctionTypeVar* ftv = get<FunctionTypeVar>(ty))
{
// We also want to suggest functions that return compatible result
if (const FunctionTypeVar* ftv = get<FunctionTypeVar>(ty))
{
auto [retHead, retTail] = flatten(ftv->retType);

if (!retHead.empty() && canUnify(retHead.front(), expectedType))
return TypeCorrectKind::CorrectFunctionResult;

// We might only have a variadic tail pack, check if the element is compatible
if (retTail)
{
if (const VariadicTypePack* vtp = get<VariadicTypePack>(follow(*retTail)); vtp && canUnify(vtp->ty, expectedType))
return TypeCorrectKind::CorrectFunctionResult;
}
}

return canUnify(ty, expectedType) ? TypeCorrectKind::Correct : TypeCorrectKind::None;
}
else
{
if (canUnify(ty, expectedType))
return TypeCorrectKind::Correct;

// We also want to suggest functions that return compatible result
const FunctionTypeVar* ftv = get<FunctionTypeVar>(ty);

if (!ftv)
return TypeCorrectKind::None;

auto [retHead, retTail] = flatten(ftv->retType);

if (!retHead.empty())
return canUnify(retHead.front(), expectedType) ? TypeCorrectKind::CorrectFunctionResult : TypeCorrectKind::None;
if (!retHead.empty() && canUnify(retHead.front(), expectedType))
return TypeCorrectKind::CorrectFunctionResult;

// We might only have a variadic tail pack, check if the element is compatible
if (retTail)
{
if (const VariadicTypePack* vtp = get<VariadicTypePack>(follow(*retTail)))
return canUnify(vtp->ty, expectedType) ? TypeCorrectKind::CorrectFunctionResult : TypeCorrectKind::None;
if (const VariadicTypePack* vtp = get<VariadicTypePack>(follow(*retTail)); vtp && canUnify(vtp->ty, expectedType))
return TypeCorrectKind::CorrectFunctionResult;
}

return TypeCorrectKind::None;
}

return canUnify(ty, expectedType) ? TypeCorrectKind::Correct : TypeCorrectKind::None;
}

enum class PropIndexType
Expand Down Expand Up @@ -435,13 +406,28 @@ static void autocompleteProps(const Module& module, TypeArena* typeArena, TypeId
auto indexIt = mtable->props.find("__index");
if (indexIt != mtable->props.end())
{
if (get<TableTypeVar>(indexIt->second.type) || get<MetatableTypeVar>(indexIt->second.type))
autocompleteProps(module, typeArena, indexIt->second.type, indexType, nodes, result, seen);
else if (auto indexFunction = get<FunctionTypeVar>(indexIt->second.type))
if (FFlag::LuauMissingFollowACMetatables)
{
std::optional<TypeId> indexFunctionResult = first(indexFunction->retType);
if (indexFunctionResult)
autocompleteProps(module, typeArena, *indexFunctionResult, indexType, nodes, result, seen);
TypeId followed = follow(indexIt->second.type);
if (get<TableTypeVar>(followed) || get<MetatableTypeVar>(followed))
autocompleteProps(module, typeArena, followed, indexType, nodes, result, seen);
else if (auto indexFunction = get<FunctionTypeVar>(followed))
{
std::optional<TypeId> indexFunctionResult = first(indexFunction->retType);
if (indexFunctionResult)
autocompleteProps(module, typeArena, *indexFunctionResult, indexType, nodes, result, seen);
}
}
else
{
if (get<TableTypeVar>(indexIt->second.type) || get<MetatableTypeVar>(indexIt->second.type))
autocompleteProps(module, typeArena, indexIt->second.type, indexType, nodes, result, seen);
else if (auto indexFunction = get<FunctionTypeVar>(indexIt->second.type))
{
std::optional<TypeId> indexFunctionResult = first(indexFunction->retType);
if (indexFunctionResult)
autocompleteProps(module, typeArena, *indexFunctionResult, indexType, nodes, result, seen);
}
}
}
}
Expand Down Expand Up @@ -1224,7 +1210,7 @@ static void autocompleteExpression(const SourceModule& sourceModule, const Modul
if (auto it = module.astTypes.find(node->asExpr()))
autocompleteProps(module, typeArena, *it, PropIndexType::Point, ancestry, result);
}
else if (FFlag::LuauIfElseExpressionAnalysisSupport && autocompleteIfElseExpression(node, ancestry, position, result))
else if (autocompleteIfElseExpression(node, ancestry, position, result))
return;
else if (node->is<AstExprFunction>())
return;
Expand Down Expand Up @@ -1261,8 +1247,7 @@ static void autocompleteExpression(const SourceModule& sourceModule, const Modul
TypeCorrectKind correctForFunction =
functionIsExpectedAt(module, node, position).value_or(false) ? TypeCorrectKind::Correct : TypeCorrectKind::None;

if (FFlag::LuauIfElseExpressionAnalysisSupport)
result["if"] = {AutocompleteEntryKind::Keyword, std::nullopt, false, false};
result["if"] = {AutocompleteEntryKind::Keyword, std::nullopt, false, false};
result["true"] = {AutocompleteEntryKind::Keyword, typeChecker.booleanType, false, false, correctForBoolean};
result["false"] = {AutocompleteEntryKind::Keyword, typeChecker.booleanType, false, false, correctForBoolean};
result["nil"] = {AutocompleteEntryKind::Keyword, typeChecker.nilType, false, false, correctForNil};
Expand Down
12 changes: 6 additions & 6 deletions Analysis/src/Error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,24 +190,24 @@ struct ErrorConverter
{
name += "<";
bool first = true;
for (TypeId t : e.typeFun.typeParams)
for (auto param : e.typeFun.typeParams)
{
if (first)
first = false;
else
name += ", ";

name += toString(t);
name += toString(param.ty);
}

for (TypePackId t : e.typeFun.typePackParams)
for (auto param : e.typeFun.typePackParams)
{
if (first)
first = false;
else
name += ", ";

name += toString(t);
name += toString(param.tp);
}

name += ">";
Expand Down Expand Up @@ -544,13 +544,13 @@ bool IncorrectGenericParameterCount::operator==(const IncorrectGenericParameterC

for (size_t i = 0; i < typeFun.typeParams.size(); ++i)
{
if (typeFun.typeParams[i] != rhs.typeFun.typeParams[i])
if (typeFun.typeParams[i].ty != rhs.typeFun.typeParams[i].ty)
return false;
}

for (size_t i = 0; i < typeFun.typePackParams.size(); ++i)
{
if (typeFun.typePackParams[i] != rhs.typeFun.typePackParams[i])
if (typeFun.typePackParams[i].tp != rhs.typeFun.typePackParams[i].tp)
return false;
}

Expand Down
8 changes: 4 additions & 4 deletions Analysis/src/IostreamHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,24 +96,24 @@ std::ostream& operator<<(std::ostream& stream, const IncorrectGenericParameterCo
{
stream << "<";
bool first = true;
for (TypeId t : error.typeFun.typeParams)
for (auto param : error.typeFun.typeParams)
{
if (first)
first = false;
else
stream << ", ";

stream << toString(t);
stream << toString(param.ty);
}

for (TypePackId t : error.typeFun.typePackParams)
for (auto param : error.typeFun.typePackParams)
{
if (first)
first = false;
else
stream << ", ";

stream << toString(t);
stream << toString(param.tp);
}

stream << ">";
Expand Down
38 changes: 38 additions & 0 deletions Analysis/src/JsonEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "Luau/StringUtils.h"
#include "Luau/Common.h"

LUAU_FASTFLAG(LuauTypeAliasDefaults)

namespace Luau
{

Expand Down Expand Up @@ -337,6 +339,42 @@ struct AstJsonEncoder : public AstVisitor
writeRaw("}");
}

void write(const AstGenericType& genericType)
{
if (FFlag::LuauTypeAliasDefaults)
{
writeRaw("{");
bool c = pushComma();
write("name", genericType.name);
if (genericType.defaultValue)
write("type", genericType.defaultValue);
popComma(c);
writeRaw("}");
}
else
{
write(genericType.name);
}
}

void write(const AstGenericTypePack& genericTypePack)
{
if (FFlag::LuauTypeAliasDefaults)
{
writeRaw("{");
bool c = pushComma();
write("name", genericTypePack.name);
if (genericTypePack.defaultValue)
write("type", genericTypePack.defaultValue);
popComma(c);
writeRaw("}");
}
else
{
write(genericTypePack.name);
}
}

void write(AstExprTable::Item::Kind kind)
{
switch (kind)
Expand Down
26 changes: 22 additions & 4 deletions Analysis/src/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
LUAU_FASTFLAGVARIABLE(DebugLuauFreezeArena, false)
LUAU_FASTFLAGVARIABLE(DebugLuauTrackOwningArena, false)
LUAU_FASTINTVARIABLE(LuauTypeCloneRecursionLimit, 300)
LUAU_FASTFLAG(LuauTypeAliasDefaults)

namespace Luau
{
Expand Down Expand Up @@ -447,11 +448,28 @@ TypeId clone(TypeId typeId, TypeArena& dest, SeenTypes& seenTypes, SeenTypePacks
TypeFun clone(const TypeFun& typeFun, TypeArena& dest, SeenTypes& seenTypes, SeenTypePacks& seenTypePacks, CloneState& cloneState)
{
TypeFun result;
for (TypeId ty : typeFun.typeParams)
result.typeParams.push_back(clone(ty, dest, seenTypes, seenTypePacks, cloneState));

for (TypePackId tp : typeFun.typePackParams)
result.typePackParams.push_back(clone(tp, dest, seenTypes, seenTypePacks, cloneState));
for (auto param : typeFun.typeParams)
{
TypeId ty = clone(param.ty, dest, seenTypes, seenTypePacks, cloneState);
std::optional<TypeId> defaultValue;

if (FFlag::LuauTypeAliasDefaults && param.defaultValue)
defaultValue = clone(*param.defaultValue, dest, seenTypes, seenTypePacks, cloneState);

result.typeParams.push_back({ty, defaultValue});
}

for (auto param : typeFun.typePackParams)
{
TypePackId tp = clone(param.tp, dest, seenTypes, seenTypePacks, cloneState);
std::optional<TypePackId> defaultValue;

if (FFlag::LuauTypeAliasDefaults && param.defaultValue)
defaultValue = clone(*param.defaultValue, dest, seenTypes, seenTypePacks, cloneState);

result.typePackParams.push_back({tp, defaultValue});
}

result.type = clone(typeFun.type, dest, seenTypes, seenTypePacks, cloneState);

Expand Down
Loading

0 comments on commit 32c39e2

Please sign in to comment.