Skip to content

Commit

Permalink
Sync to upstream/release/527 (#491)
Browse files Browse the repository at this point in the history
  • Loading branch information
zeux committed May 20, 2022
1 parent 8b4c6aa commit f5923ae
Show file tree
Hide file tree
Showing 52 changed files with 1,095 additions and 1,367 deletions.
2 changes: 1 addition & 1 deletion Analysis/include/Luau/Clone.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
#pragma once

#include "Luau/TypeArena.h"
#include "Luau/TypeVar.h"

#include <unordered_map>
Expand All @@ -18,7 +19,6 @@ struct CloneState
SeenTypePacks seenTypePacks;

int recursionCount = 0;
bool encounteredFreeType = false; // TODO: Remove with LuauLosslessClone.
};

TypePackId clone(TypePackId tp, TypeArena& dest, CloneState& cloneState);
Expand Down
4 changes: 1 addition & 3 deletions Analysis/include/Luau/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Luau/Location.h"
#include "Luau/TypeVar.h"
#include "Luau/Variant.h"
#include "Luau/TypeArena.h"

namespace Luau
{
Expand Down Expand Up @@ -108,9 +109,6 @@ struct FunctionDoesNotTakeSelf

struct FunctionRequiresSelf
{
// TODO: Delete with LuauAnyInIsOptionalIsOptional
int requiredExtraNils = 0;

bool operator==(const FunctionRequiresSelf& rhs) const;
};

Expand Down
4 changes: 0 additions & 4 deletions Analysis/include/Luau/LValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ const LValue* baseof(const LValue& lvalue);

std::optional<LValue> tryGetLValue(const class AstExpr& expr);

// Utility function: breaks down an LValue to get at the Symbol, and reverses the vector of keys.
// TODO: remove with FFlagLuauTypecheckOptPass
std::pair<Symbol, std::vector<std::string>> getFullName(const LValue& lvalue);

// Utility function: breaks down an LValue to get at the Symbol
Symbol getBaseSymbol(const LValue& lvalue);

Expand Down
36 changes: 2 additions & 34 deletions Analysis/include/Luau/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
#pragma once

#include "Luau/FileResolver.h"
#include "Luau/TypePack.h"
#include "Luau/TypedAllocator.h"
#include "Luau/ParseOptions.h"
#include "Luau/Error.h"
#include "Luau/ParseResult.h"
#include "Luau/TypeArena.h"

#include <memory>
#include <vector>
Expand Down Expand Up @@ -54,35 +53,6 @@ struct RequireCycle
std::vector<ModuleName> path; // one of the paths for a require() to go all the way back to the originating module
};

struct TypeArena
{
TypedAllocator<TypeVar> typeVars;
TypedAllocator<TypePackVar> typePacks;

void clear();

template<typename T>
TypeId addType(T tv)
{
if constexpr (std::is_same_v<T, UnionTypeVar>)
LUAU_ASSERT(tv.options.size() >= 2);

return addTV(TypeVar(std::move(tv)));
}

TypeId addTV(TypeVar&& tv);

TypeId freshType(TypeLevel level);

TypePackId addTypePack(std::initializer_list<TypeId> types);
TypePackId addTypePack(std::vector<TypeId> types);
TypePackId addTypePack(TypePack pack);
TypePackId addTypePack(TypePackVar pack);
};

void freeze(TypeArena& arena);
void unfreeze(TypeArena& arena);

struct Module
{
~Module();
Expand Down Expand Up @@ -111,9 +81,7 @@ struct Module

// Once a module has been typechecked, we clone its public interface into a separate arena.
// This helps us to force TypeVar ownership into a DAG rather than a DCG.
// Returns true if there were any free types encountered in the public interface. This
// indicates a bug in the type checker that we want to surface.
bool clonePublicInterface(InternalErrorReporter& ice);
void clonePublicInterface(InternalErrorReporter& ice);
};

} // namespace Luau
3 changes: 1 addition & 2 deletions Analysis/include/Luau/Substitution.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
#pragma once

#include "Luau/Module.h"
#include "Luau/ModuleResolver.h"
#include "Luau/TypeArena.h"
#include "Luau/TypePack.h"
#include "Luau/TypeVar.h"
#include "Luau/DenseHash.h"
Expand Down
11 changes: 0 additions & 11 deletions Analysis/include/Luau/TxnLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
#include "Luau/TypeVar.h"
#include "Luau/TypePack.h"

LUAU_FASTFLAG(LuauTypecheckOptPass)

namespace Luau
{

Expand Down Expand Up @@ -93,15 +91,6 @@ struct TxnLog
{
}

TxnLog(TxnLog* parent, std::vector<std::pair<TypeOrPackId, TypeOrPackId>>* sharedSeen)
: typeVarChanges(nullptr)
, typePackChanges(nullptr)
, parent(parent)
, sharedSeen(sharedSeen)
{
LUAU_ASSERT(!FFlag::LuauTypecheckOptPass);
}

TxnLog(const TxnLog&) = delete;
TxnLog& operator=(const TxnLog&) = delete;

Expand Down
42 changes: 42 additions & 0 deletions Analysis/include/Luau/TypeArena.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
#pragma once

#include "Luau/TypedAllocator.h"
#include "Luau/TypeVar.h"
#include "Luau/TypePack.h"

#include <vector>

namespace Luau
{

struct TypeArena
{
TypedAllocator<TypeVar> typeVars;
TypedAllocator<TypePackVar> typePacks;

void clear();

template<typename T>
TypeId addType(T tv)
{
if constexpr (std::is_same_v<T, UnionTypeVar>)
LUAU_ASSERT(tv.options.size() >= 2);

return addTV(TypeVar(std::move(tv)));
}

TypeId addTV(TypeVar&& tv);

TypeId freshType(TypeLevel level);

TypePackId addTypePack(std::initializer_list<TypeId> types);
TypePackId addTypePack(std::vector<TypeId> types);
TypePackId addTypePack(TypePack pack);
TypePackId addTypePack(TypePackVar pack);
};

void freeze(TypeArena& arena);
void unfreeze(TypeArena& arena);

}
19 changes: 9 additions & 10 deletions Analysis/include/Luau/TypeInfer.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ struct TypeChecker
ExprResult<TypeId> checkExpr(const ScopePtr& scope, const AstExprIndexExpr& expr);
ExprResult<TypeId> checkExpr(const ScopePtr& scope, const AstExprFunction& expr, std::optional<TypeId> expectedType = std::nullopt);
ExprResult<TypeId> checkExpr(const ScopePtr& scope, const AstExprTable& expr, std::optional<TypeId> expectedType = std::nullopt);
ExprResult<TypeId> checkExpr_(const ScopePtr& scope, const AstExprTable& expr, std::optional<TypeId> expectedType = std::nullopt);
ExprResult<TypeId> checkExpr(const ScopePtr& scope, const AstExprUnary& expr);
TypeId checkRelationalOperation(
const ScopePtr& scope, const AstExprBinary& expr, TypeId lhsType, TypeId rhsType, const PredicateVec& predicates = {});
Expand Down Expand Up @@ -395,22 +394,22 @@ struct TypeChecker
const AstArray<AstGenericType>& genericNames, const AstArray<AstGenericTypePack>& genericPackNames, bool useCache = false);

public:
ErrorVec resolve(const PredicateVec& predicates, const ScopePtr& scope, bool sense);
void resolve(const PredicateVec& predicates, const ScopePtr& scope, bool sense);

private:
void refineLValue(const LValue& lvalue, RefinementMap& refis, const ScopePtr& scope, TypeIdPredicate predicate);

std::optional<TypeId> resolveLValue(const ScopePtr& scope, const LValue& lvalue);
std::optional<TypeId> resolveLValue(const RefinementMap& refis, const ScopePtr& scope, const LValue& lvalue);

void resolve(const PredicateVec& predicates, ErrorVec& errVec, RefinementMap& refis, const ScopePtr& scope, bool sense, bool fromOr = false);
void resolve(const Predicate& predicate, ErrorVec& errVec, RefinementMap& refis, const ScopePtr& scope, bool sense, bool fromOr);
void resolve(const TruthyPredicate& truthyP, ErrorVec& errVec, RefinementMap& refis, const ScopePtr& scope, bool sense, bool fromOr);
void resolve(const AndPredicate& andP, ErrorVec& errVec, RefinementMap& refis, const ScopePtr& scope, bool sense);
void resolve(const OrPredicate& orP, ErrorVec& errVec, RefinementMap& refis, const ScopePtr& scope, bool sense);
void resolve(const IsAPredicate& isaP, ErrorVec& errVec, RefinementMap& refis, const ScopePtr& scope, bool sense);
void resolve(const TypeGuardPredicate& typeguardP, ErrorVec& errVec, RefinementMap& refis, const ScopePtr& scope, bool sense);
void resolve(const EqPredicate& eqP, ErrorVec& errVec, RefinementMap& refis, const ScopePtr& scope, bool sense);
void resolve(const PredicateVec& predicates, RefinementMap& refis, const ScopePtr& scope, bool sense, bool fromOr = false);
void resolve(const Predicate& predicate, RefinementMap& refis, const ScopePtr& scope, bool sense, bool fromOr);
void resolve(const TruthyPredicate& truthyP, RefinementMap& refis, const ScopePtr& scope, bool sense, bool fromOr);
void resolve(const AndPredicate& andP, RefinementMap& refis, const ScopePtr& scope, bool sense);
void resolve(const OrPredicate& orP, RefinementMap& refis, const ScopePtr& scope, bool sense);
void resolve(const IsAPredicate& isaP, RefinementMap& refis, const ScopePtr& scope, bool sense);
void resolve(const TypeGuardPredicate& typeguardP, RefinementMap& refis, const ScopePtr& scope, bool sense);
void resolve(const EqPredicate& eqP, RefinementMap& refis, const ScopePtr& scope, bool sense);

bool isNonstrictMode() const;
bool useConstrainedIntersections() const;
Expand Down
4 changes: 1 addition & 3 deletions Analysis/include/Luau/Unifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "Luau/Location.h"
#include "Luau/TxnLog.h"
#include "Luau/TypeInfer.h"
#include "Luau/Module.h" // FIXME: For TypeArena. It merits breaking out into its own header.
#include "Luau/TypeArena.h"
#include "Luau/UnifierSharedState.h"

#include <unordered_set>
Expand Down Expand Up @@ -55,8 +55,6 @@ struct Unifier
UnifierSharedState& sharedState;

Unifier(TypeArena* types, Mode mode, const Location& location, Variance variance, UnifierSharedState& sharedState, TxnLog* parentLog = nullptr);
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.
ErrorVec canUnify(TypeId subTy, TypeId superTy);
Expand Down
20 changes: 12 additions & 8 deletions Analysis/include/Luau/VisitTypeVar.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

LUAU_FASTFLAG(LuauUseVisitRecursionLimit)
LUAU_FASTINT(LuauVisitRecursionLimit)
LUAU_FASTFLAG(LuauNormalizeFlagIsConservative)

namespace Luau
{
Expand Down Expand Up @@ -471,18 +472,21 @@ struct GenericTypeVarVisitor

else if (auto pack = get<TypePack>(tp))
{
visit(tp, *pack);

for (TypeId ty : pack->head)
traverse(ty);
bool res = visit(tp, *pack);
if (!FFlag::LuauNormalizeFlagIsConservative || res)
{
for (TypeId ty : pack->head)
traverse(ty);

if (pack->tail)
traverse(*pack->tail);
if (pack->tail)
traverse(*pack->tail);
}
}
else if (auto pack = get<VariadicTypePack>(tp))
{
visit(tp, *pack);
traverse(pack->ty);
bool res = visit(tp, *pack);
if (!FFlag::LuauNormalizeFlagIsConservative || res)
traverse(pack->ty);
}
else
LUAU_ASSERT(!"GenericTypeVarVisitor::traverse(TypePackId) is not exhaustive!");
Expand Down
47 changes: 17 additions & 30 deletions Analysis/src/BuiltinDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

#include <algorithm>

LUAU_FASTFLAG(LuauAssertStripsFalsyTypes)
LUAU_FASTFLAGVARIABLE(LuauSetMetaTableArgsCheck, false)

/** FIXME: Many of these type definitions are not quite completely accurate.
Expand Down Expand Up @@ -408,41 +407,29 @@ static std::optional<ExprResult<TypePackId>> magicFunctionAssert(
{
auto [paramPack, predicates] = exprResult;

if (FFlag::LuauAssertStripsFalsyTypes)
{
TypeArena& arena = typechecker.currentModule->internalTypes;

auto [head, tail] = flatten(paramPack);
if (head.empty() && tail)
{
std::optional<TypeId> fst = first(*tail);
if (!fst)
return ExprResult<TypePackId>{paramPack};
head.push_back(*fst);
}

typechecker.reportErrors(typechecker.resolve(predicates, scope, true));

if (head.size() > 0)
{
std::optional<TypeId> newhead = typechecker.pickTypesFromSense(head[0], true);
if (!newhead)
head = {typechecker.nilType};
else
head[0] = *newhead;
}
TypeArena& arena = typechecker.currentModule->internalTypes;

return ExprResult<TypePackId>{arena.addTypePack(TypePack{std::move(head), tail})};
}
else
auto [head, tail] = flatten(paramPack);
if (head.empty() && tail)
{
if (expr.args.size < 1)
std::optional<TypeId> fst = first(*tail);
if (!fst)
return ExprResult<TypePackId>{paramPack};
head.push_back(*fst);
}

typechecker.reportErrors(typechecker.resolve(predicates, scope, true));
typechecker.resolve(predicates, scope, true);

return ExprResult<TypePackId>{paramPack};
if (head.size() > 0)
{
std::optional<TypeId> newhead = typechecker.pickTypesFromSense(head[0], true);
if (!newhead)
head = {typechecker.nilType};
else
head[0] = *newhead;
}

return ExprResult<TypePackId>{arena.addTypePack(TypePack{std::move(head), tail})};
}

static std::optional<ExprResult<TypePackId>> magicFunctionPack(
Expand Down

0 comments on commit f5923ae

Please sign in to comment.