Skip to content

Commit

Permalink
Sync to upstream/release/517 (#408)
Browse files Browse the repository at this point in the history
  • Loading branch information
zeux committed Mar 4, 2022
1 parent 6c923b8 commit dbdf91f
Show file tree
Hide file tree
Showing 55 changed files with 1,262 additions and 769 deletions.
32 changes: 25 additions & 7 deletions Analysis/include/Luau/TxnLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ LUAU_FASTFLAG(LuauShareTxnSeen);
namespace Luau
{

using TypeOrPackId = const void*;

// Log of where what TypeIds we are rebinding and what they used to be
// Remove with LuauUseCommitTxnLog
struct DEPRECATED_TxnLog
Expand All @@ -23,7 +25,7 @@ struct DEPRECATED_TxnLog
{
}

explicit DEPRECATED_TxnLog(std::vector<std::pair<TypeId, TypeId>>* sharedSeen)
explicit DEPRECATED_TxnLog(std::vector<std::pair<TypeOrPackId, TypeOrPackId>>* sharedSeen)
: originalSeenSize(sharedSeen->size())
, ownedSeen()
, sharedSeen(sharedSeen)
Expand All @@ -48,15 +50,23 @@ struct DEPRECATED_TxnLog
void pushSeen(TypeId lhs, TypeId rhs);
void popSeen(TypeId lhs, TypeId rhs);

bool haveSeen(TypePackId lhs, TypePackId rhs);
void pushSeen(TypePackId lhs, TypePackId rhs);
void popSeen(TypePackId lhs, TypePackId rhs);

private:
std::vector<std::pair<TypeId, TypeVar>> typeVarChanges;
std::vector<std::pair<TypePackId, TypePackVar>> typePackChanges;
std::vector<std::pair<TableTypeVar*, std::optional<TypeId>>> tableChanges;
size_t originalSeenSize;

bool haveSeen(TypeOrPackId lhs, TypeOrPackId rhs);
void pushSeen(TypeOrPackId lhs, TypeOrPackId rhs);
void popSeen(TypeOrPackId lhs, TypeOrPackId rhs);

public:
std::vector<std::pair<TypeId, TypeId>> ownedSeen; // used to avoid infinite recursion when types are cyclic
std::vector<std::pair<TypeId, TypeId>>* sharedSeen; // shared with all the descendent logs
std::vector<std::pair<TypeOrPackId, TypeOrPackId>> ownedSeen; // used to avoid infinite recursion when types are cyclic
std::vector<std::pair<TypeOrPackId, TypeOrPackId>>* sharedSeen; // shared with all the descendent logs
};

// Pending state for a TypeVar. Generated by a TxnLog and committed via
Expand Down Expand Up @@ -127,12 +137,12 @@ struct TxnLog
}
}

explicit TxnLog(std::vector<std::pair<TypeId, TypeId>>* sharedSeen)
explicit TxnLog(std::vector<std::pair<TypeOrPackId, TypeOrPackId>>* sharedSeen)
: sharedSeen(sharedSeen)
{
}

TxnLog(TxnLog* parent, std::vector<std::pair<TypeId, TypeId>>* sharedSeen)
TxnLog(TxnLog* parent, std::vector<std::pair<TypeOrPackId, TypeOrPackId>>* sharedSeen)
: parent(parent)
, sharedSeen(sharedSeen)
{
Expand Down Expand Up @@ -173,6 +183,10 @@ struct TxnLog
void pushSeen(TypeId lhs, TypeId rhs);
void popSeen(TypeId lhs, TypeId rhs);

bool haveSeen(TypePackId lhs, TypePackId rhs) const;
void pushSeen(TypePackId lhs, TypePackId rhs);
void popSeen(TypePackId lhs, TypePackId rhs);

// Queues a type for modification. The original type will not change until commit
// is called. Use pending to get the pending state.
//
Expand Down Expand Up @@ -316,12 +330,16 @@ struct TxnLog
// TxnLogs; use sharedSeen instead. This field exists because in the tree
// of TxnLogs, the root must own its seen set. In all descendant TxnLogs,
// this is an empty vector.
std::vector<std::pair<TypeId, TypeId>> ownedSeen;
std::vector<std::pair<TypeOrPackId, TypeOrPackId>> ownedSeen;

bool haveSeen(TypeOrPackId lhs, TypeOrPackId rhs) const;
void pushSeen(TypeOrPackId lhs, TypeOrPackId rhs);
void popSeen(TypeOrPackId lhs, TypeOrPackId rhs);

public:
// Used to avoid infinite recursion when types are cyclic.
// Shared with all the descendent TxnLogs.
std::vector<std::pair<TypeId, TypeId>>* sharedSeen;
std::vector<std::pair<TypeOrPackId, TypeOrPackId>>* sharedSeen;
};

} // namespace Luau
18 changes: 0 additions & 18 deletions Analysis/include/Luau/TypeInfer.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,24 +73,6 @@ struct Instantiation : Substitution
TypePackId clean(TypePackId tp) override;
};

// A substitution which replaces free types by generic types.
struct Quantification : Substitution
{
Quantification(TypeArena* arena, TypeLevel level)
: Substitution(TxnLog::empty(), arena)
, level(level)
{
}

TypeLevel level;
std::vector<TypeId> generics;
std::vector<TypePackId> genericPacks;
bool isDirty(TypeId ty) override;
bool isDirty(TypePackId tp) override;
TypeId clean(TypeId ty) override;
TypePackId clean(TypePackId tp) override;
};

// A substitution which replaces free types by any
struct Anyification : Substitution
{
Expand Down
5 changes: 4 additions & 1 deletion Analysis/include/Luau/TypeVar.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ struct TableTypeVar

TableTypeVar() = default;
explicit TableTypeVar(TableState state, TypeLevel level);
TableTypeVar(const Props& props, const std::optional<TableIndexer>& indexer, TypeLevel level, TableState state = TableState::Unsealed);
TableTypeVar(const Props& props, const std::optional<TableIndexer>& indexer, TypeLevel level, TableState state);

Props props;
std::optional<TableIndexer> indexer;
Expand Down Expand Up @@ -477,6 +477,9 @@ bool isOptional(TypeId ty);
bool isTableIntersection(TypeId ty);
bool isOverloadedFunction(TypeId ty);

// True when string is a subtype of ty
bool maybeString(TypeId ty);

std::optional<TypeId> getMetatable(TypeId type);
TableTypeVar* getMutableTableType(TypeId type);
const TableTypeVar* getTableType(TypeId type);
Expand Down
2 changes: 1 addition & 1 deletion Analysis/include/Luau/Unifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct Unifier

Unifier(TypeArena* types, Mode mode, const Location& location, Variance variance, UnifierSharedState& sharedState,
TxnLog* parentLog = nullptr);
Unifier(TypeArena* types, Mode mode, std::vector<std::pair<TypeId, TypeId>>* sharedSeen, const Location& location,
Unifier(TypeArena* types, Mode mode, std::vector<std::pair<TypeOrPackId, TypeOrPackId>>* sharedSeen, const Location& location,
Variance variance, UnifierSharedState& sharedState, TxnLog* parentLog = nullptr);

// Test whether the two type vars unify. Never commits the result.
Expand Down
62 changes: 20 additions & 42 deletions Analysis/src/Autocomplete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
LUAU_FASTFLAG(LuauUseCommittingTxnLog)
LUAU_FASTFLAGVARIABLE(LuauAutocompleteAvoidMutation, false);
LUAU_FASTFLAGVARIABLE(LuauMissingFollowACMetatables, false);
LUAU_FASTFLAGVARIABLE(PreferToCallFunctionsForIntersects, false);
LUAU_FASTFLAGVARIABLE(LuauIfElseExprFixCompletionIssue, false);

static const std::unordered_set<std::string> kStatementStartingKeywords = {
Expand Down Expand Up @@ -272,55 +271,34 @@ static TypeCorrectKind checkTypeCorrectKind(const Module& module, TypeArena* typ

TypeId expectedType = follow(*typeAtPosition);

if (FFlag::PreferToCallFunctionsForIntersects)
{
auto checkFunctionType = [&canUnify, &expectedType](const FunctionTypeVar* ftv) {
auto [retHead, retTail] = flatten(ftv->retType);

if (!retHead.empty() && canUnify(retHead.front(), expectedType))
return true;

// 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 true;
}
auto checkFunctionType = [&canUnify, &expectedType](const FunctionTypeVar* ftv) {
auto [retHead, retTail] = flatten(ftv->retType);

return false;
};
if (!retHead.empty() && canUnify(retHead.front(), expectedType))
return true;

// We also want to suggest functions that return compatible result
if (const FunctionTypeVar* ftv = get<FunctionTypeVar>(ty); ftv && checkFunctionType(ftv))
// We might only have a variadic tail pack, check if the element is compatible
if (retTail)
{
return TypeCorrectKind::CorrectFunctionResult;
}
else if (const IntersectionTypeVar* itv = get<IntersectionTypeVar>(ty))
{
for (TypeId id : itv->parts)
{
if (const FunctionTypeVar* ftv = get<FunctionTypeVar>(id); ftv && checkFunctionType(ftv))
{
return TypeCorrectKind::CorrectFunctionResult;
}
}
if (const VariadicTypePack* vtp = get<VariadicTypePack>(follow(*retTail)); vtp && canUnify(vtp->ty, expectedType))
return true;
}

return false;
};

// We also want to suggest functions that return compatible result
if (const FunctionTypeVar* ftv = get<FunctionTypeVar>(ty); ftv && checkFunctionType(ftv))
{
return TypeCorrectKind::CorrectFunctionResult;
}
else
else if (const IntersectionTypeVar* itv = get<IntersectionTypeVar>(ty))
{
// We also want to suggest functions that return compatible result
if (const FunctionTypeVar* ftv = get<FunctionTypeVar>(ty))
for (TypeId id : itv->parts)
{
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 FunctionTypeVar* ftv = get<FunctionTypeVar>(id); ftv && checkFunctionType(ftv))
{
if (const VariadicTypePack* vtp = get<VariadicTypePack>(follow(*retTail)); vtp && canUnify(vtp->ty, expectedType))
return TypeCorrectKind::CorrectFunctionResult;
return TypeCorrectKind::CorrectFunctionResult;
}
}
}
Expand Down
13 changes: 11 additions & 2 deletions Analysis/src/BuiltinDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <algorithm>

LUAU_FASTFLAG(LuauAssertStripsFalsyTypes)
LUAU_FASTFLAGVARIABLE(LuauTableCloneType, false)

/** FIXME: Many of these type definitions are not quite completely accurate.
*
Expand Down Expand Up @@ -283,8 +284,16 @@ void registerBuiltinTypes(TypeChecker& typeChecker)
attachMagicFunction(getGlobalBinding(typeChecker, "setmetatable"), magicFunctionSetMetaTable);
attachMagicFunction(getGlobalBinding(typeChecker, "select"), magicFunctionSelect);

auto tableLib = getMutable<TableTypeVar>(getGlobalBinding(typeChecker, "table"));
attachMagicFunction(tableLib->props["pack"].type, magicFunctionPack);
if (TableTypeVar* ttv = getMutable<TableTypeVar>(getGlobalBinding(typeChecker, "table")))
{
// tabTy is a generic table type which we can't express via declaration syntax yet
ttv->props["freeze"] = makeProperty(makeFunction(arena, std::nullopt, {tabTy}, {tabTy}), "@luau/global/table.freeze");

if (FFlag::LuauTableCloneType)
ttv->props["clone"] = makeProperty(makeFunction(arena, std::nullopt, {tabTy}, {tabTy}), "@luau/global/table.clone");

attachMagicFunction(ttv->props["pack"].type, magicFunctionPack);
}

attachMagicFunction(getGlobalBinding(typeChecker, "require"), magicFunctionRequire);
}
Expand Down
1 change: 0 additions & 1 deletion Analysis/src/EmbeddedBuiltinDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ declare function gcinfo(): number
move: <V>({V}, number, number, number, {V}?) -> {V},
clear: <K, V>({[K]: V}) -> (),
freeze: <K, V>({[K]: V}) -> {[K]: V},
isfrozen: <K, V>({[K]: V}) -> boolean,
}
Expand Down
44 changes: 14 additions & 30 deletions Analysis/src/JsonEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
#include "Luau/StringUtils.h"
#include "Luau/Common.h"

LUAU_FASTFLAG(LuauTypeAliasDefaults)

namespace Luau
{

Expand Down Expand Up @@ -369,38 +367,24 @@ struct AstJsonEncoder : public AstVisitor

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);
}
writeRaw("{");
bool c = pushComma();
write("name", genericType.name);
if (genericType.defaultValue)
write("type", genericType.defaultValue);
popComma(c);
writeRaw("}");
}

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);
}
writeRaw("{");
bool c = pushComma();
write("name", genericTypePack.name);
if (genericTypePack.defaultValue)
write("type", genericTypePack.defaultValue);
popComma(c);
writeRaw("}");
}

void write(AstExprTable::Item::Kind kind)
Expand Down
Loading

0 comments on commit dbdf91f

Please sign in to comment.