mirror of
https://github.com/luau-lang/luau.git
synced 2024-12-13 13:30:40 +00:00
Sync to upstream/release/527 (#481)
This commit is contained in:
parent
87fe15ac51
commit
a36b1eb29b
48 changed files with 511 additions and 416 deletions
|
@ -329,7 +329,7 @@ struct TableTypeVar
|
||||||
// We need to know which is which when we stringify types.
|
// We need to know which is which when we stringify types.
|
||||||
std::optional<std::string> syntheticName;
|
std::optional<std::string> syntheticName;
|
||||||
|
|
||||||
std::map<Name, Location> methodDefinitionLocations;
|
std::map<Name, Location> methodDefinitionLocations; // TODO: Remove with FFlag::LuauNoMethodLocations
|
||||||
std::vector<TypeId> instantiatedTypeParams;
|
std::vector<TypeId> instantiatedTypeParams;
|
||||||
std::vector<TypePackId> instantiatedTypePackParams;
|
std::vector<TypePackId> instantiatedTypePackParams;
|
||||||
ModuleName definitionModuleName;
|
ModuleName definitionModuleName;
|
||||||
|
|
|
@ -11,6 +11,7 @@ LUAU_FASTFLAG(DebugLuauCopyBeforeNormalizing)
|
||||||
LUAU_FASTINTVARIABLE(LuauTypeCloneRecursionLimit, 300)
|
LUAU_FASTINTVARIABLE(LuauTypeCloneRecursionLimit, 300)
|
||||||
LUAU_FASTFLAG(LuauTypecheckOptPass)
|
LUAU_FASTFLAG(LuauTypecheckOptPass)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauLosslessClone, false)
|
LUAU_FASTFLAGVARIABLE(LuauLosslessClone, false)
|
||||||
|
LUAU_FASTFLAG(LuauNoMethodLocations)
|
||||||
|
|
||||||
namespace Luau
|
namespace Luau
|
||||||
{
|
{
|
||||||
|
@ -277,6 +278,7 @@ void TypeCloner::operator()(const TableTypeVar& t)
|
||||||
}
|
}
|
||||||
|
|
||||||
ttv->definitionModuleName = t.definitionModuleName;
|
ttv->definitionModuleName = t.definitionModuleName;
|
||||||
|
if (!FFlag::LuauNoMethodLocations)
|
||||||
ttv->methodDefinitionLocations = t.methodDefinitionLocations;
|
ttv->methodDefinitionLocations = t.methodDefinitionLocations;
|
||||||
ttv->tags = t.tags;
|
ttv->tags = t.tags;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ LUAU_FASTFLAGVARIABLE(DebugLuauCopyBeforeNormalizing, false)
|
||||||
// This could theoretically be 2000 on amd64, but x86 requires this.
|
// This could theoretically be 2000 on amd64, but x86 requires this.
|
||||||
LUAU_FASTINTVARIABLE(LuauNormalizeIterationLimit, 1200);
|
LUAU_FASTINTVARIABLE(LuauNormalizeIterationLimit, 1200);
|
||||||
LUAU_FASTFLAGVARIABLE(LuauNormalizeCombineTableFix, false);
|
LUAU_FASTFLAGVARIABLE(LuauNormalizeCombineTableFix, false);
|
||||||
LUAU_FASTFLAGVARIABLE(LuauNormalizeCombineIntersectionFix, false);
|
|
||||||
|
|
||||||
namespace Luau
|
namespace Luau
|
||||||
{
|
{
|
||||||
|
@ -863,7 +862,7 @@ struct Normalize final : TypeVarVisitor
|
||||||
|
|
||||||
TypeId theTable = result->parts.back();
|
TypeId theTable = result->parts.back();
|
||||||
|
|
||||||
if (!get<TableTypeVar>(FFlag::LuauNormalizeCombineIntersectionFix ? follow(theTable) : theTable))
|
if (!get<TableTypeVar>(follow(theTable)))
|
||||||
{
|
{
|
||||||
result->parts.push_back(arena.addType(TableTypeVar{TableState::Sealed, TypeLevel{}}));
|
result->parts.push_back(arena.addType(TableTypeVar{TableState::Sealed, TypeLevel{}}));
|
||||||
theTable = result->parts.back();
|
theTable = result->parts.back();
|
||||||
|
|
|
@ -12,6 +12,7 @@ LUAU_FASTINTVARIABLE(LuauTarjanChildLimit, 10000)
|
||||||
LUAU_FASTFLAG(LuauTypecheckOptPass)
|
LUAU_FASTFLAG(LuauTypecheckOptPass)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauSubstituteFollowNewTypes, false)
|
LUAU_FASTFLAGVARIABLE(LuauSubstituteFollowNewTypes, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauSubstituteFollowPossibleMutations, false)
|
LUAU_FASTFLAGVARIABLE(LuauSubstituteFollowPossibleMutations, false)
|
||||||
|
LUAU_FASTFLAG(LuauNoMethodLocations)
|
||||||
|
|
||||||
namespace Luau
|
namespace Luau
|
||||||
{
|
{
|
||||||
|
@ -408,6 +409,7 @@ TypeId Substitution::clone(TypeId ty)
|
||||||
{
|
{
|
||||||
LUAU_ASSERT(!ttv->boundTo);
|
LUAU_ASSERT(!ttv->boundTo);
|
||||||
TableTypeVar clone = TableTypeVar{ttv->props, ttv->indexer, ttv->level, ttv->state};
|
TableTypeVar clone = TableTypeVar{ttv->props, ttv->indexer, ttv->level, ttv->state};
|
||||||
|
if (!FFlag::LuauNoMethodLocations)
|
||||||
clone.methodDefinitionLocations = ttv->methodDefinitionLocations;
|
clone.methodDefinitionLocations = ttv->methodDefinitionLocations;
|
||||||
clone.definitionModuleName = ttv->definitionModuleName;
|
clone.definitionModuleName = ttv->definitionModuleName;
|
||||||
clone.name = ttv->name;
|
clone.name = ttv->name;
|
||||||
|
|
|
@ -248,6 +248,13 @@ struct StringifierState
|
||||||
result.name += s;
|
result.name += s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emit(TypeLevel level)
|
||||||
|
{
|
||||||
|
emit(std::to_string(level.level));
|
||||||
|
emit("-");
|
||||||
|
emit(std::to_string(level.subLevel));
|
||||||
|
}
|
||||||
|
|
||||||
void emit(const char* s)
|
void emit(const char* s)
|
||||||
{
|
{
|
||||||
if (opts.maxTypeLength > 0 && result.name.length() > opts.maxTypeLength)
|
if (opts.maxTypeLength > 0 && result.name.length() > opts.maxTypeLength)
|
||||||
|
@ -379,7 +386,7 @@ struct TypeVarStringifier
|
||||||
if (FFlag::DebugLuauVerboseTypeNames)
|
if (FFlag::DebugLuauVerboseTypeNames)
|
||||||
{
|
{
|
||||||
state.emit("-");
|
state.emit("-");
|
||||||
state.emit(std::to_string(ftv.level.level));
|
state.emit(ftv.level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +410,10 @@ struct TypeVarStringifier
|
||||||
{
|
{
|
||||||
state.result.invalid = true;
|
state.result.invalid = true;
|
||||||
|
|
||||||
state.emit("[[");
|
state.emit("[");
|
||||||
|
if (FFlag::DebugLuauVerboseTypeNames)
|
||||||
|
state.emit(ctv.level);
|
||||||
|
state.emit("[");
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (TypeId ty : ctv.parts)
|
for (TypeId ty : ctv.parts)
|
||||||
|
@ -947,7 +957,7 @@ struct TypePackStringifier
|
||||||
if (FFlag::DebugLuauVerboseTypeNames)
|
if (FFlag::DebugLuauVerboseTypeNames)
|
||||||
{
|
{
|
||||||
state.emit("-");
|
state.emit("-");
|
||||||
state.emit(std::to_string(pack.level.level));
|
state.emit(pack.level);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.emit("...");
|
state.emit("...");
|
||||||
|
|
|
@ -36,13 +36,11 @@ LUAU_FASTFLAGVARIABLE(LuauEqConstraint, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauWeakEqConstraint, false) // Eventually removed as false.
|
LUAU_FASTFLAGVARIABLE(LuauWeakEqConstraint, false) // Eventually removed as false.
|
||||||
LUAU_FASTFLAGVARIABLE(LuauLowerBoundsCalculation, false)
|
LUAU_FASTFLAGVARIABLE(LuauLowerBoundsCalculation, false)
|
||||||
LUAU_FASTFLAGVARIABLE(DebugLuauFreezeDuringUnification, false)
|
LUAU_FASTFLAGVARIABLE(DebugLuauFreezeDuringUnification, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauInferStatFunction, false)
|
|
||||||
LUAU_FASTFLAGVARIABLE(LuauInstantiateFollows, false)
|
LUAU_FASTFLAGVARIABLE(LuauInstantiateFollows, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauSelfCallAutocompleteFix, false)
|
LUAU_FASTFLAGVARIABLE(LuauSelfCallAutocompleteFix, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauDiscriminableUnions2, false)
|
LUAU_FASTFLAGVARIABLE(LuauDiscriminableUnions2, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauReduceUnionRecursion, false)
|
LUAU_FASTFLAGVARIABLE(LuauReduceUnionRecursion, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauOnlyMutateInstantiatedTables, false)
|
LUAU_FASTFLAGVARIABLE(LuauOnlyMutateInstantiatedTables, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauStatFunctionSimplify4, false)
|
|
||||||
LUAU_FASTFLAGVARIABLE(LuauTypecheckOptPass, false)
|
LUAU_FASTFLAGVARIABLE(LuauTypecheckOptPass, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauUnsealedTableLiteral, false)
|
LUAU_FASTFLAGVARIABLE(LuauUnsealedTableLiteral, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauTwoPassAliasDefinitionFix, false)
|
LUAU_FASTFLAGVARIABLE(LuauTwoPassAliasDefinitionFix, false)
|
||||||
|
@ -53,12 +51,13 @@ LUAU_FASTFLAGVARIABLE(LuauDoNotTryToReduce, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauDoNotAccidentallyDependOnPointerOrdering, false)
|
LUAU_FASTFLAGVARIABLE(LuauDoNotAccidentallyDependOnPointerOrdering, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauCheckImplicitNumbericKeys, false)
|
LUAU_FASTFLAGVARIABLE(LuauCheckImplicitNumbericKeys, false)
|
||||||
LUAU_FASTFLAG(LuauAnyInIsOptionalIsOptional)
|
LUAU_FASTFLAG(LuauAnyInIsOptionalIsOptional)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauDecoupleOperatorInferenceFromUnifiedTypeInference, false)
|
|
||||||
LUAU_FASTFLAGVARIABLE(LuauTableUseCounterInstead, false)
|
LUAU_FASTFLAGVARIABLE(LuauTableUseCounterInstead, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauReturnTypeInferenceInNonstrict, false)
|
LUAU_FASTFLAGVARIABLE(LuauReturnTypeInferenceInNonstrict, false)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauRecursionLimitException, false);
|
LUAU_FASTFLAGVARIABLE(LuauRecursionLimitException, false);
|
||||||
LUAU_FASTFLAG(LuauLosslessClone)
|
LUAU_FASTFLAG(LuauLosslessClone)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauTypecheckIter, false);
|
LUAU_FASTFLAGVARIABLE(LuauTypecheckIter, false);
|
||||||
|
LUAU_FASTFLAGVARIABLE(LuauSuccessTypingForEqualityOperations, false)
|
||||||
|
LUAU_FASTFLAGVARIABLE(LuauNoMethodLocations, false);
|
||||||
|
|
||||||
namespace Luau
|
namespace Luau
|
||||||
{
|
{
|
||||||
|
@ -587,7 +586,7 @@ void TypeChecker::checkBlockWithoutRecursionCheck(const ScopePtr& scope, const A
|
||||||
{
|
{
|
||||||
std::optional<TypeId> expectedType;
|
std::optional<TypeId> expectedType;
|
||||||
|
|
||||||
if (FFlag::LuauInferStatFunction && !fun->func->self)
|
if (!fun->func->self)
|
||||||
{
|
{
|
||||||
if (auto name = fun->name->as<AstExprIndexName>())
|
if (auto name = fun->name->as<AstExprIndexName>())
|
||||||
{
|
{
|
||||||
|
@ -1307,7 +1306,7 @@ void TypeChecker::check(const ScopePtr& scope, TypeId ty, const ScopePtr& funSco
|
||||||
scope->bindings[name->local] = {anyIfNonstrict(quantify(funScope, ty, name->local->location)), name->local->location};
|
scope->bindings[name->local] = {anyIfNonstrict(quantify(funScope, ty, name->local->location)), name->local->location};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (auto name = function.name->as<AstExprIndexName>(); name && FFlag::LuauStatFunctionSimplify4)
|
else if (auto name = function.name->as<AstExprIndexName>())
|
||||||
{
|
{
|
||||||
TypeId exprTy = checkExpr(scope, *name->expr).type;
|
TypeId exprTy = checkExpr(scope, *name->expr).type;
|
||||||
TableTypeVar* ttv = getMutableTableType(exprTy);
|
TableTypeVar* ttv = getMutableTableType(exprTy);
|
||||||
|
@ -1341,7 +1340,7 @@ void TypeChecker::check(const ScopePtr& scope, TypeId ty, const ScopePtr& funSco
|
||||||
if (ttv && ttv->state != TableState::Sealed)
|
if (ttv && ttv->state != TableState::Sealed)
|
||||||
ttv->props[name->index.value] = {follow(quantify(funScope, ty, name->indexLocation)), /* deprecated */ false, {}, name->indexLocation};
|
ttv->props[name->index.value] = {follow(quantify(funScope, ty, name->indexLocation)), /* deprecated */ false, {}, name->indexLocation};
|
||||||
}
|
}
|
||||||
else if (FFlag::LuauStatFunctionSimplify4)
|
else
|
||||||
{
|
{
|
||||||
LUAU_ASSERT(function.name->is<AstExprError>());
|
LUAU_ASSERT(function.name->is<AstExprError>());
|
||||||
|
|
||||||
|
@ -1349,71 +1348,6 @@ void TypeChecker::check(const ScopePtr& scope, TypeId ty, const ScopePtr& funSco
|
||||||
|
|
||||||
checkFunctionBody(funScope, ty, *function.func);
|
checkFunctionBody(funScope, ty, *function.func);
|
||||||
}
|
}
|
||||||
else if (function.func->self)
|
|
||||||
{
|
|
||||||
LUAU_ASSERT(!FFlag::LuauStatFunctionSimplify4);
|
|
||||||
|
|
||||||
AstExprIndexName* indexName = function.name->as<AstExprIndexName>();
|
|
||||||
if (!indexName)
|
|
||||||
ice("member function declaration has malformed name expression");
|
|
||||||
|
|
||||||
TypeId selfTy = checkExpr(scope, *indexName->expr).type;
|
|
||||||
TableTypeVar* tableSelf = getMutableTableType(selfTy);
|
|
||||||
if (!tableSelf)
|
|
||||||
{
|
|
||||||
if (isTableIntersection(selfTy))
|
|
||||||
reportError(TypeError{function.location, CannotExtendTable{selfTy, CannotExtendTable::Property, indexName->index.value}});
|
|
||||||
else if (!get<ErrorTypeVar>(selfTy) && !get<AnyTypeVar>(selfTy))
|
|
||||||
reportError(TypeError{function.location, OnlyTablesCanHaveMethods{selfTy}});
|
|
||||||
}
|
|
||||||
else if (tableSelf->state == TableState::Sealed)
|
|
||||||
reportError(TypeError{function.location, CannotExtendTable{selfTy, CannotExtendTable::Property, indexName->index.value}});
|
|
||||||
|
|
||||||
const bool tableIsExtendable = tableSelf && tableSelf->state != TableState::Sealed;
|
|
||||||
|
|
||||||
ty = follow(ty);
|
|
||||||
|
|
||||||
if (tableIsExtendable)
|
|
||||||
tableSelf->props[indexName->index.value] = {ty, /* deprecated */ false, {}, indexName->indexLocation};
|
|
||||||
|
|
||||||
const FunctionTypeVar* funTy = get<FunctionTypeVar>(ty);
|
|
||||||
if (!funTy)
|
|
||||||
ice("Methods should be functions");
|
|
||||||
|
|
||||||
std::optional<TypeId> arg0 = first(funTy->argTypes);
|
|
||||||
if (!arg0)
|
|
||||||
ice("Methods should always have at least 1 argument (self)");
|
|
||||||
|
|
||||||
checkFunctionBody(funScope, ty, *function.func);
|
|
||||||
|
|
||||||
if (tableIsExtendable)
|
|
||||||
tableSelf->props[indexName->index.value] = {
|
|
||||||
follow(quantify(funScope, ty, indexName->indexLocation)), /* deprecated */ false, {}, indexName->indexLocation};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LUAU_ASSERT(!FFlag::LuauStatFunctionSimplify4);
|
|
||||||
|
|
||||||
TypeId leftType = checkLValueBinding(scope, *function.name);
|
|
||||||
|
|
||||||
checkFunctionBody(funScope, ty, *function.func);
|
|
||||||
|
|
||||||
unify(ty, leftType, function.location);
|
|
||||||
|
|
||||||
LUAU_ASSERT(function.name->is<AstExprIndexName>() || function.name->is<AstExprError>());
|
|
||||||
|
|
||||||
if (auto exprIndexName = function.name->as<AstExprIndexName>())
|
|
||||||
{
|
|
||||||
if (auto typeIt = currentModule->astTypes.find(exprIndexName->expr))
|
|
||||||
{
|
|
||||||
if (auto ttv = getMutableTableType(*typeIt))
|
|
||||||
{
|
|
||||||
if (auto it = ttv->props.find(exprIndexName->index.value); it != ttv->props.end())
|
|
||||||
it->second.type = follow(quantify(funScope, leftType, function.name->location));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeChecker::check(const ScopePtr& scope, TypeId ty, const ScopePtr& funScope, const AstStatLocalFunction& function)
|
void TypeChecker::check(const ScopePtr& scope, TypeId ty, const ScopePtr& funScope, const AstStatLocalFunction& function)
|
||||||
|
@ -1523,6 +1457,7 @@ void TypeChecker::check(const ScopePtr& scope, const AstStatTypeAlias& typealias
|
||||||
// This is a shallow clone, original recursive links to self are not updated
|
// This is a shallow clone, original recursive links to self are not updated
|
||||||
TableTypeVar clone = TableTypeVar{ttv->props, ttv->indexer, ttv->level, ttv->state};
|
TableTypeVar clone = TableTypeVar{ttv->props, ttv->indexer, ttv->level, ttv->state};
|
||||||
|
|
||||||
|
if (!FFlag::LuauNoMethodLocations)
|
||||||
clone.methodDefinitionLocations = ttv->methodDefinitionLocations;
|
clone.methodDefinitionLocations = ttv->methodDefinitionLocations;
|
||||||
clone.definitionModuleName = ttv->definitionModuleName;
|
clone.definitionModuleName = ttv->definitionModuleName;
|
||||||
clone.name = name;
|
clone.name = name;
|
||||||
|
@ -2652,14 +2587,59 @@ TypeId TypeChecker::checkRelationalOperation(
|
||||||
std::optional<TypeId> leftMetatable = isString(lhsType) ? std::nullopt : getMetatable(follow(lhsType));
|
std::optional<TypeId> leftMetatable = isString(lhsType) ? std::nullopt : getMetatable(follow(lhsType));
|
||||||
std::optional<TypeId> rightMetatable = isString(rhsType) ? std::nullopt : getMetatable(follow(rhsType));
|
std::optional<TypeId> rightMetatable = isString(rhsType) ? std::nullopt : getMetatable(follow(rhsType));
|
||||||
|
|
||||||
// TODO: this check seems odd, the second part is redundant
|
if (FFlag::LuauSuccessTypingForEqualityOperations)
|
||||||
// is it meant to be if (leftMetatable && rightMetatable && leftMetatable != rightMetatable)
|
{
|
||||||
|
if (leftMetatable != rightMetatable)
|
||||||
|
{
|
||||||
|
bool matches = false;
|
||||||
|
if (isEquality)
|
||||||
|
{
|
||||||
|
if (const UnionTypeVar* utv = get<UnionTypeVar>(leftType); utv && rightMetatable)
|
||||||
|
{
|
||||||
|
for (TypeId leftOption : utv)
|
||||||
|
{
|
||||||
|
if (getMetatable(follow(leftOption)) == rightMetatable)
|
||||||
|
{
|
||||||
|
matches = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matches)
|
||||||
|
{
|
||||||
|
if (const UnionTypeVar* utv = get<UnionTypeVar>(rhsType); utv && leftMetatable)
|
||||||
|
{
|
||||||
|
for (TypeId rightOption : utv)
|
||||||
|
{
|
||||||
|
if (getMetatable(follow(rightOption)) == leftMetatable)
|
||||||
|
{
|
||||||
|
matches = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!matches)
|
||||||
|
{
|
||||||
|
reportError(expr.location, GenericError{format("Types %s and %s cannot be compared with %s because they do not have the same metatable",
|
||||||
|
toString(lhsType).c_str(), toString(rhsType).c_str(), toString(expr.op).c_str())});
|
||||||
|
return errorRecoveryType(booleanType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (bool(leftMetatable) != bool(rightMetatable) && leftMetatable != rightMetatable)
|
if (bool(leftMetatable) != bool(rightMetatable) && leftMetatable != rightMetatable)
|
||||||
{
|
{
|
||||||
reportError(expr.location, GenericError{format("Types %s and %s cannot be compared with %s because they do not have the same metatable",
|
reportError(expr.location, GenericError{format("Types %s and %s cannot be compared with %s because they do not have the same metatable",
|
||||||
toString(lhsType).c_str(), toString(rhsType).c_str(), toString(expr.op).c_str())});
|
toString(lhsType).c_str(), toString(rhsType).c_str(), toString(expr.op).c_str())});
|
||||||
return errorRecoveryType(booleanType);
|
return errorRecoveryType(booleanType);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (leftMetatable)
|
if (leftMetatable)
|
||||||
{
|
{
|
||||||
|
@ -2754,23 +2734,12 @@ TypeId TypeChecker::checkBinaryOperation(
|
||||||
lhsType = follow(lhsType);
|
lhsType = follow(lhsType);
|
||||||
rhsType = follow(rhsType);
|
rhsType = follow(rhsType);
|
||||||
|
|
||||||
if (FFlag::LuauDecoupleOperatorInferenceFromUnifiedTypeInference)
|
|
||||||
{
|
|
||||||
if (!isNonstrictMode() && get<FreeTypeVar>(lhsType))
|
if (!isNonstrictMode() && get<FreeTypeVar>(lhsType))
|
||||||
{
|
{
|
||||||
auto name = getIdentifierOfBaseVar(expr.left);
|
auto name = getIdentifierOfBaseVar(expr.left);
|
||||||
reportError(expr.location, CannotInferBinaryOperation{expr.op, name, CannotInferBinaryOperation::Operation});
|
reportError(expr.location, CannotInferBinaryOperation{expr.op, name, CannotInferBinaryOperation::Operation});
|
||||||
// We will fall-through to the `return anyType` check below.
|
// We will fall-through to the `return anyType` check below.
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!isNonstrictMode() && get<FreeTypeVar>(lhsType))
|
|
||||||
{
|
|
||||||
auto name = getIdentifierOfBaseVar(expr.left);
|
|
||||||
reportError(expr.location, CannotInferBinaryOperation{expr.op, name, CannotInferBinaryOperation::Operation});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we know nothing at all about the lhs type, we can usually say nothing about the result.
|
// If we know nothing at all about the lhs type, we can usually say nothing about the result.
|
||||||
// The notable exception to this is the equality and inequality operators, which always produce a boolean.
|
// The notable exception to this is the equality and inequality operators, which always produce a boolean.
|
||||||
|
@ -3231,14 +3200,8 @@ TypeId TypeChecker::checkFunctionName(const ScopePtr& scope, AstExpr& funName, T
|
||||||
else if (auto indexName = funName.as<AstExprIndexName>())
|
else if (auto indexName = funName.as<AstExprIndexName>())
|
||||||
{
|
{
|
||||||
TypeId lhsType = checkExpr(scope, *indexName->expr).type;
|
TypeId lhsType = checkExpr(scope, *indexName->expr).type;
|
||||||
|
|
||||||
if (!FFlag::LuauStatFunctionSimplify4 && (get<ErrorTypeVar>(lhsType) || get<AnyTypeVar>(lhsType)))
|
|
||||||
return lhsType;
|
|
||||||
|
|
||||||
TableTypeVar* ttv = getMutableTableType(lhsType);
|
TableTypeVar* ttv = getMutableTableType(lhsType);
|
||||||
|
|
||||||
if (FFlag::LuauStatFunctionSimplify4)
|
|
||||||
{
|
|
||||||
if (!ttv || ttv->state == TableState::Sealed)
|
if (!ttv || ttv->state == TableState::Sealed)
|
||||||
{
|
{
|
||||||
if (auto ty = getIndexTypeFromType(scope, lhsType, indexName->index.value, indexName->indexLocation, false))
|
if (auto ty = getIndexTypeFromType(scope, lhsType, indexName->index.value, indexName->indexLocation, false))
|
||||||
|
@ -3246,27 +3209,17 @@ TypeId TypeChecker::checkFunctionName(const ScopePtr& scope, AstExpr& funName, T
|
||||||
|
|
||||||
return errorRecoveryType(scope);
|
return errorRecoveryType(scope);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!ttv || lhsType->persistent || ttv->state == TableState::Sealed)
|
|
||||||
return errorRecoveryType(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
Name name = indexName->index.value;
|
Name name = indexName->index.value;
|
||||||
|
|
||||||
if (ttv->props.count(name))
|
if (ttv->props.count(name))
|
||||||
{
|
|
||||||
if (FFlag::LuauStatFunctionSimplify4)
|
|
||||||
return ttv->props[name].type;
|
return ttv->props[name].type;
|
||||||
else
|
|
||||||
return errorRecoveryType(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
Property& property = ttv->props[name];
|
Property& property = ttv->props[name];
|
||||||
|
|
||||||
property.type = freshTy();
|
property.type = freshTy();
|
||||||
property.location = indexName->indexLocation;
|
property.location = indexName->indexLocation;
|
||||||
|
if (!FFlag::LuauNoMethodLocations)
|
||||||
ttv->methodDefinitionLocations[name] = funName.location;
|
ttv->methodDefinitionLocations[name] = funName.location;
|
||||||
return property.type;
|
return property.type;
|
||||||
}
|
}
|
||||||
|
@ -4669,6 +4622,7 @@ TypeId ReplaceGenerics::clean(TypeId ty)
|
||||||
if (const TableTypeVar* ttv = log->getMutable<TableTypeVar>(ty))
|
if (const TableTypeVar* ttv = log->getMutable<TableTypeVar>(ty))
|
||||||
{
|
{
|
||||||
TableTypeVar clone = TableTypeVar{ttv->props, ttv->indexer, level, TableState::Free};
|
TableTypeVar clone = TableTypeVar{ttv->props, ttv->indexer, level, TableState::Free};
|
||||||
|
if (!FFlag::LuauNoMethodLocations)
|
||||||
clone.methodDefinitionLocations = ttv->methodDefinitionLocations;
|
clone.methodDefinitionLocations = ttv->methodDefinitionLocations;
|
||||||
clone.definitionModuleName = ttv->definitionModuleName;
|
clone.definitionModuleName = ttv->definitionModuleName;
|
||||||
return addType(std::move(clone));
|
return addType(std::move(clone));
|
||||||
|
@ -4715,6 +4669,7 @@ TypeId Anyification::clean(TypeId ty)
|
||||||
if (const TableTypeVar* ttv = log->getMutable<TableTypeVar>(ty))
|
if (const TableTypeVar* ttv = log->getMutable<TableTypeVar>(ty))
|
||||||
{
|
{
|
||||||
TableTypeVar clone = TableTypeVar{ttv->props, ttv->indexer, ttv->level, TableState::Sealed};
|
TableTypeVar clone = TableTypeVar{ttv->props, ttv->indexer, ttv->level, TableState::Sealed};
|
||||||
|
if (!FFlag::LuauNoMethodLocations)
|
||||||
clone.methodDefinitionLocations = ttv->methodDefinitionLocations;
|
clone.methodDefinitionLocations = ttv->methodDefinitionLocations;
|
||||||
clone.definitionModuleName = ttv->definitionModuleName;
|
clone.definitionModuleName = ttv->definitionModuleName;
|
||||||
clone.name = ttv->name;
|
clone.name = ttv->name;
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
// See docs/SyntaxChanges.md for an explanation.
|
// See docs/SyntaxChanges.md for an explanation.
|
||||||
LUAU_FASTINTVARIABLE(LuauRecursionLimit, 1000)
|
LUAU_FASTINTVARIABLE(LuauRecursionLimit, 1000)
|
||||||
LUAU_FASTINTVARIABLE(LuauParseErrorLimit, 100)
|
LUAU_FASTINTVARIABLE(LuauParseErrorLimit, 100)
|
||||||
LUAU_FASTFLAGVARIABLE(LuauParseLocationIgnoreCommentSkipInCapture, false)
|
|
||||||
|
|
||||||
namespace Luau
|
namespace Luau
|
||||||
{
|
{
|
||||||
|
@ -2821,7 +2820,7 @@ void Parser::nextLexeme()
|
||||||
hotcomments.push_back({hotcommentHeader, lexeme.location, std::string(text + 1, text + end)});
|
hotcomments.push_back({hotcommentHeader, lexeme.location, std::string(text + 1, text + end)});
|
||||||
}
|
}
|
||||||
|
|
||||||
type = lexer.next(/* skipComments= */ false, !FFlag::LuauParseLocationIgnoreCommentSkipInCapture).type;
|
type = lexer.next(/* skipComments= */ false, /* updatePrevLocation= */ false).type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -110,6 +110,12 @@ if (MSVC AND MSVC_VERSION GREATER_EQUAL 1924)
|
||||||
set_source_files_properties(VM/src/lvmexecute.cpp PROPERTIES COMPILE_FLAGS /d2ssa-pre-)
|
set_source_files_properties(VM/src/lvmexecute.cpp PROPERTIES COMPILE_FLAGS /d2ssa-pre-)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(MSVC AND LUAU_BUILD_CLI)
|
||||||
|
# the default stack size that MSVC linker uses is 1 MB; we need more stack space in Debug because stack frames are larger
|
||||||
|
set_target_properties(Luau.Analyze.CLI PROPERTIES LINK_FLAGS_DEBUG /STACK:2097152)
|
||||||
|
set_target_properties(Luau.Repl.CLI PROPERTIES LINK_FLAGS_DEBUG /STACK:2097152)
|
||||||
|
endif()
|
||||||
|
|
||||||
# embed .natvis inside the library debug information
|
# embed .natvis inside the library debug information
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_link_options(Luau.Ast INTERFACE /NATVIS:${CMAKE_CURRENT_SOURCE_DIR}/tools/natvis/Ast.natvis)
|
target_link_options(Luau.Ast INTERFACE /NATVIS:${CMAKE_CURRENT_SOURCE_DIR}/tools/natvis/Ast.natvis)
|
||||||
|
|
|
@ -628,8 +628,13 @@ struct Compiler
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fi && !fi->canInline)
|
if (fi && !fi->canInline)
|
||||||
|
{
|
||||||
|
if (func->vararg)
|
||||||
|
bytecode.addDebugRemark("inlining failed: function is variadic");
|
||||||
|
else
|
||||||
bytecode.addDebugRemark("inlining failed: complex constructs in function body");
|
bytecode.addDebugRemark("inlining failed: complex constructs in function body");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RegScope rs(this);
|
RegScope rs(this);
|
||||||
|
|
||||||
|
@ -2342,17 +2347,28 @@ struct Compiler
|
||||||
RegScope rs(this);
|
RegScope rs(this);
|
||||||
|
|
||||||
uint8_t temp = 0;
|
uint8_t temp = 0;
|
||||||
|
bool consecutive = false;
|
||||||
bool multRet = false;
|
bool multRet = false;
|
||||||
|
|
||||||
// Optimization: return local value directly instead of copying it into a temporary
|
// Optimization: return locals directly instead of copying them into a temporary
|
||||||
if (stat->list.size == 1 && isExprLocalReg(stat->list.data[0]))
|
// this is very important for a single return value and occasionally effective for multiple values
|
||||||
|
if (stat->list.size > 0 && isExprLocalReg(stat->list.data[0]))
|
||||||
{
|
{
|
||||||
AstExprLocal* le = stat->list.data[0]->as<AstExprLocal>();
|
temp = getLocal(stat->list.data[0]->as<AstExprLocal>()->local);
|
||||||
LUAU_ASSERT(le);
|
consecutive = true;
|
||||||
|
|
||||||
temp = getLocal(le->local);
|
for (size_t i = 1; i < stat->list.size; ++i)
|
||||||
|
{
|
||||||
|
AstExpr* v = stat->list.data[i];
|
||||||
|
if (!isExprLocalReg(v) || getLocal(v->as<AstExprLocal>()->local) != temp + i)
|
||||||
|
{
|
||||||
|
consecutive = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (stat->list.size > 0)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!consecutive && stat->list.size > 0)
|
||||||
{
|
{
|
||||||
temp = allocReg(stat, unsigned(stat->list.size));
|
temp = allocReg(stat, unsigned(stat->list.size));
|
||||||
|
|
||||||
|
|
|
@ -195,12 +195,16 @@ struct ConstantVisitor : AstVisitor
|
||||||
DenseHashMap<AstLocal*, Variable>& variables;
|
DenseHashMap<AstLocal*, Variable>& variables;
|
||||||
DenseHashMap<AstLocal*, Constant>& locals;
|
DenseHashMap<AstLocal*, Constant>& locals;
|
||||||
|
|
||||||
|
bool wasEmpty = false;
|
||||||
|
|
||||||
ConstantVisitor(
|
ConstantVisitor(
|
||||||
DenseHashMap<AstExpr*, Constant>& constants, DenseHashMap<AstLocal*, Variable>& variables, DenseHashMap<AstLocal*, Constant>& locals)
|
DenseHashMap<AstExpr*, Constant>& constants, DenseHashMap<AstLocal*, Variable>& variables, DenseHashMap<AstLocal*, Constant>& locals)
|
||||||
: constants(constants)
|
: constants(constants)
|
||||||
, variables(variables)
|
, variables(variables)
|
||||||
, locals(locals)
|
, locals(locals)
|
||||||
{
|
{
|
||||||
|
// since we do a single pass over the tree, if the initial state was empty we don't need to clear out old entries
|
||||||
|
wasEmpty = constants.empty() && locals.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
Constant analyze(AstExpr* node)
|
Constant analyze(AstExpr* node)
|
||||||
|
@ -326,7 +330,7 @@ struct ConstantVisitor : AstVisitor
|
||||||
{
|
{
|
||||||
if (value.type != Constant::Type_Unknown)
|
if (value.type != Constant::Type_Unknown)
|
||||||
map[key] = value;
|
map[key] = value;
|
||||||
else if (!FFlag::LuauCompileSupportInlining)
|
else if (!FFlag::LuauCompileSupportInlining || wasEmpty)
|
||||||
;
|
;
|
||||||
else if (Constant* old = map.find(key))
|
else if (Constant* old = map.find(key))
|
||||||
old->type = Constant::Type_Unknown;
|
old->type = Constant::Type_Unknown;
|
||||||
|
|
|
@ -187,7 +187,7 @@ struct CostVisitor : AstVisitor
|
||||||
if (node->is<AstStatIf>())
|
if (node->is<AstStatIf>())
|
||||||
result += 2;
|
result += 2;
|
||||||
else if (node->is<AstStatWhile>() || node->is<AstStatRepeat>() || node->is<AstStatFor>() || node->is<AstStatForIn>())
|
else if (node->is<AstStatWhile>() || node->is<AstStatRepeat>() || node->is<AstStatFor>() || node->is<AstStatForIn>())
|
||||||
result += 2;
|
result += 5;
|
||||||
else if (node->is<AstStatBreak>() || node->is<AstStatContinue>())
|
else if (node->is<AstStatBreak>() || node->is<AstStatContinue>())
|
||||||
result += 1;
|
result += 1;
|
||||||
|
|
||||||
|
|
1
extern/isocline/src/bbcode.c
vendored
1
extern/isocline/src/bbcode.c
vendored
|
@ -575,6 +575,7 @@ ic_private const char* parse_tag_value( tag_t* tag, char* idbuf, const char* s,
|
||||||
}
|
}
|
||||||
// limit name and attr to 128 bytes
|
// limit name and attr to 128 bytes
|
||||||
char valbuf[128];
|
char valbuf[128];
|
||||||
|
valbuf[0] = 0; // fixes gcc uninitialized warning
|
||||||
ic_strncpy( idbuf, 128, id, idend - id);
|
ic_strncpy( idbuf, 128, id, idend - id);
|
||||||
ic_strncpy( valbuf, 128, val, valend - val);
|
ic_strncpy( valbuf, 128, val, valend - val);
|
||||||
ic_str_tolower(idbuf);
|
ic_str_tolower(idbuf);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
using namespace Luau;
|
using namespace Luau;
|
||||||
|
|
||||||
struct DocumentationSymbolFixture : Fixture
|
struct DocumentationSymbolFixture : BuiltinsFixture
|
||||||
{
|
{
|
||||||
std::optional<DocumentationSymbol> getDocSymbol(const std::string& source, Position position)
|
std::optional<DocumentationSymbol> getDocSymbol(const std::string& source, Position position)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@ template<class BaseType>
|
||||||
struct ACFixtureImpl : BaseType
|
struct ACFixtureImpl : BaseType
|
||||||
{
|
{
|
||||||
ACFixtureImpl()
|
ACFixtureImpl()
|
||||||
: Fixture(true, true)
|
: BaseType(true, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +111,18 @@ struct ACFixtureImpl : BaseType
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ACFixture : ACFixtureImpl<Fixture>
|
struct ACFixture : ACFixtureImpl<Fixture>
|
||||||
|
{
|
||||||
|
ACFixture()
|
||||||
|
: ACFixtureImpl<Fixture>()
|
||||||
|
{
|
||||||
|
addGlobalBinding(frontend.typeChecker, "table", Binding{typeChecker.anyType});
|
||||||
|
addGlobalBinding(frontend.typeChecker, "math", Binding{typeChecker.anyType});
|
||||||
|
addGlobalBinding(frontend.typeCheckerForAutocomplete, "table", Binding{typeChecker.anyType});
|
||||||
|
addGlobalBinding(frontend.typeCheckerForAutocomplete, "math", Binding{typeChecker.anyType});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ACBuiltinsFixture : ACFixtureImpl<BuiltinsFixture>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -277,7 +289,7 @@ TEST_CASE_FIXTURE(ACFixture, "function_parameters")
|
||||||
CHECK(ac.entryMap.count("test"));
|
CHECK(ac.entryMap.count("test"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(ACFixture, "get_member_completions")
|
TEST_CASE_FIXTURE(ACBuiltinsFixture, "get_member_completions")
|
||||||
{
|
{
|
||||||
check(R"(
|
check(R"(
|
||||||
local a = table.@1
|
local a = table.@1
|
||||||
|
@ -376,7 +388,7 @@ TEST_CASE_FIXTURE(ACFixture, "table_intersection")
|
||||||
CHECK(ac.entryMap.count("c3"));
|
CHECK(ac.entryMap.count("c3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(ACFixture, "get_string_completions")
|
TEST_CASE_FIXTURE(ACBuiltinsFixture, "get_string_completions")
|
||||||
{
|
{
|
||||||
check(R"(
|
check(R"(
|
||||||
local a = ("foo"):@1
|
local a = ("foo"):@1
|
||||||
|
@ -427,7 +439,7 @@ TEST_CASE_FIXTURE(ACFixture, "method_call_inside_function_body")
|
||||||
CHECK(!ac.entryMap.count("math"));
|
CHECK(!ac.entryMap.count("math"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(ACFixture, "method_call_inside_if_conditional")
|
TEST_CASE_FIXTURE(ACBuiltinsFixture, "method_call_inside_if_conditional")
|
||||||
{
|
{
|
||||||
check(R"(
|
check(R"(
|
||||||
if table: @1
|
if table: @1
|
||||||
|
@ -1884,7 +1896,7 @@ ex.b(function(x:
|
||||||
CHECK(!ac.entryMap.count("(done) -> number"));
|
CHECK(!ac.entryMap.count("(done) -> number"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(ACFixture, "suggest_external_module_type")
|
TEST_CASE_FIXTURE(ACBuiltinsFixture, "suggest_external_module_type")
|
||||||
{
|
{
|
||||||
fileResolver.source["Module/A"] = R"(
|
fileResolver.source["Module/A"] = R"(
|
||||||
export type done = { x: number, y: number }
|
export type done = { x: number, y: number }
|
||||||
|
@ -2235,7 +2247,7 @@ local a: aaa.do
|
||||||
CHECK(ac.entryMap.count("other"));
|
CHECK(ac.entryMap.count("other"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(ACFixture, "autocompleteSource")
|
TEST_CASE_FIXTURE(ACBuiltinsFixture, "autocompleteSource")
|
||||||
{
|
{
|
||||||
std::string_view source = R"(
|
std::string_view source = R"(
|
||||||
local a = table. -- Line 1
|
local a = table. -- Line 1
|
||||||
|
@ -2269,7 +2281,7 @@ TEST_CASE_FIXTURE(ACFixture, "autocompleteSource_comments")
|
||||||
CHECK_EQ(0, ac.entryMap.size());
|
CHECK_EQ(0, ac.entryMap.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(ACFixture, "autocompleteProp_index_function_metamethod_is_variadic")
|
TEST_CASE_FIXTURE(ACBuiltinsFixture, "autocompleteProp_index_function_metamethod_is_variadic")
|
||||||
{
|
{
|
||||||
std::string_view source = R"(
|
std::string_view source = R"(
|
||||||
type Foo = {x: number}
|
type Foo = {x: number}
|
||||||
|
@ -2720,7 +2732,7 @@ type A<T... = ...@1> = () -> T
|
||||||
CHECK(ac.entryMap.count("string"));
|
CHECK(ac.entryMap.count("string"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(ACFixture, "autocomplete_oop_implicit_self")
|
TEST_CASE_FIXTURE(ACBuiltinsFixture, "autocomplete_oop_implicit_self")
|
||||||
{
|
{
|
||||||
check(R"(
|
check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -2745,7 +2757,7 @@ end
|
||||||
CHECK(ac.entryMap.count("getx"));
|
CHECK(ac.entryMap.count("getx"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(ACFixture, "autocomplete_on_string_singletons")
|
TEST_CASE_FIXTURE(ACBuiltinsFixture, "autocomplete_on_string_singletons")
|
||||||
{
|
{
|
||||||
check(R"(
|
check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -2989,7 +3001,7 @@ s.@1
|
||||||
CHECK(ac.entryMap["sub"].wrongIndexType == true);
|
CHECK(ac.entryMap["sub"].wrongIndexType == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(ACFixture, "string_library_non_self_calls_are_fine")
|
TEST_CASE_FIXTURE(ACBuiltinsFixture, "string_library_non_self_calls_are_fine")
|
||||||
{
|
{
|
||||||
ScopedFastFlag selfCallAutocompleteFix{"LuauSelfCallAutocompleteFix", true};
|
ScopedFastFlag selfCallAutocompleteFix{"LuauSelfCallAutocompleteFix", true};
|
||||||
|
|
||||||
|
@ -3007,7 +3019,7 @@ string.@1
|
||||||
CHECK(ac.entryMap["sub"].wrongIndexType == false);
|
CHECK(ac.entryMap["sub"].wrongIndexType == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(ACFixture, "string_library_self_calls_are_invalid")
|
TEST_CASE_FIXTURE(ACBuiltinsFixture, "string_library_self_calls_are_invalid")
|
||||||
{
|
{
|
||||||
ScopedFastFlag selfCallAutocompleteFix{"LuauSelfCallAutocompleteFix", true};
|
ScopedFastFlag selfCallAutocompleteFix{"LuauSelfCallAutocompleteFix", true};
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,10 @@ using namespace Luau;
|
||||||
|
|
||||||
TEST_SUITE_BEGIN("BuiltinDefinitionsTest");
|
TEST_SUITE_BEGIN("BuiltinDefinitionsTest");
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "lib_documentation_symbols")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "lib_documentation_symbols")
|
||||||
{
|
{
|
||||||
|
CHECK(!typeChecker.globalScope->bindings.empty());
|
||||||
|
|
||||||
for (const auto& [name, binding] : typeChecker.globalScope->bindings)
|
for (const auto& [name, binding] : typeChecker.globalScope->bindings)
|
||||||
{
|
{
|
||||||
std::string nameString(name.c_str());
|
std::string nameString(name.c_str());
|
||||||
|
|
|
@ -4713,7 +4713,6 @@ local function foo()
|
||||||
end
|
end
|
||||||
|
|
||||||
local a, b = foo()
|
local a, b = foo()
|
||||||
|
|
||||||
return a, b
|
return a, b
|
||||||
)",
|
)",
|
||||||
1, 2),
|
1, 2),
|
||||||
|
@ -4721,9 +4720,7 @@ return a, b
|
||||||
DUPCLOSURE R0 K0
|
DUPCLOSURE R0 K0
|
||||||
LOADNIL R1
|
LOADNIL R1
|
||||||
LOADNIL R2
|
LOADNIL R2
|
||||||
MOVE R3 R1
|
RETURN R1 2
|
||||||
MOVE R4 R2
|
|
||||||
RETURN R3 2
|
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// this happens even if the function returns conditionally
|
// this happens even if the function returns conditionally
|
||||||
|
@ -4733,7 +4730,6 @@ local function foo(a)
|
||||||
end
|
end
|
||||||
|
|
||||||
local a, b = foo(false)
|
local a, b = foo(false)
|
||||||
|
|
||||||
return a, b
|
return a, b
|
||||||
)",
|
)",
|
||||||
1, 2),
|
1, 2),
|
||||||
|
@ -4741,9 +4737,7 @@ return a, b
|
||||||
DUPCLOSURE R0 K0
|
DUPCLOSURE R0 K0
|
||||||
LOADNIL R1
|
LOADNIL R1
|
||||||
LOADNIL R2
|
LOADNIL R2
|
||||||
MOVE R3 R1
|
RETURN R1 2
|
||||||
MOVE R4 R2
|
|
||||||
RETURN R3 2
|
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// note though that we can't inline a function like this in multret context
|
// note though that we can't inline a function like this in multret context
|
||||||
|
@ -4880,11 +4874,7 @@ LOADN R5 1
|
||||||
ADD R4 R5 R1
|
ADD R4 R5 R1
|
||||||
LOADN R5 3
|
LOADN R5 3
|
||||||
ADD R6 R1 R2
|
ADD R6 R1 R2
|
||||||
MOVE R7 R3
|
RETURN R3 4
|
||||||
MOVE R8 R4
|
|
||||||
MOVE R9 R5
|
|
||||||
MOVE R10 R6
|
|
||||||
RETURN R7 4
|
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5151,4 +5141,59 @@ RETURN R0 0
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ReturnConsecutive")
|
||||||
|
{
|
||||||
|
// we can return a single local directly
|
||||||
|
CHECK_EQ("\n" + compileFunction0(R"(
|
||||||
|
local x = ...
|
||||||
|
return x
|
||||||
|
)"),
|
||||||
|
R"(
|
||||||
|
GETVARARGS R0 1
|
||||||
|
RETURN R0 1
|
||||||
|
)");
|
||||||
|
|
||||||
|
// or multiple, when they are allocated in consecutive registers
|
||||||
|
CHECK_EQ("\n" + compileFunction0(R"(
|
||||||
|
local x, y = ...
|
||||||
|
return x, y
|
||||||
|
)"),
|
||||||
|
R"(
|
||||||
|
GETVARARGS R0 2
|
||||||
|
RETURN R0 2
|
||||||
|
)");
|
||||||
|
|
||||||
|
// but not if it's an expression
|
||||||
|
CHECK_EQ("\n" + compileFunction0(R"(
|
||||||
|
local x, y = ...
|
||||||
|
return x, y + 1
|
||||||
|
)"),
|
||||||
|
R"(
|
||||||
|
GETVARARGS R0 2
|
||||||
|
MOVE R2 R0
|
||||||
|
ADDK R3 R1 K0
|
||||||
|
RETURN R2 2
|
||||||
|
)");
|
||||||
|
|
||||||
|
// or a local with wrong register number
|
||||||
|
CHECK_EQ("\n" + compileFunction0(R"(
|
||||||
|
local x, y = ...
|
||||||
|
return y, x
|
||||||
|
)"),
|
||||||
|
R"(
|
||||||
|
GETVARARGS R0 2
|
||||||
|
MOVE R2 R1
|
||||||
|
MOVE R3 R0
|
||||||
|
RETURN R2 2
|
||||||
|
)");
|
||||||
|
|
||||||
|
// also double check the optimization doesn't trip on no-argument return (these are rare)
|
||||||
|
CHECK_EQ("\n" + compileFunction0(R"(
|
||||||
|
return
|
||||||
|
)"),
|
||||||
|
R"(
|
||||||
|
RETURN R0 0
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_SUITE_END();
|
TEST_SUITE_END();
|
||||||
|
|
|
@ -76,9 +76,9 @@ end
|
||||||
const bool args1[] = {false};
|
const bool args1[] = {false};
|
||||||
const bool args2[] = {true};
|
const bool args2[] = {true};
|
||||||
|
|
||||||
// loop baseline cost is 2
|
// loop baseline cost is 5
|
||||||
CHECK_EQ(3, Luau::Compile::computeCost(model, args1, 1));
|
CHECK_EQ(6, Luau::Compile::computeCost(model, args1, 1));
|
||||||
CHECK_EQ(3, Luau::Compile::computeCost(model, args2, 1));
|
CHECK_EQ(6, Luau::Compile::computeCost(model, args2, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("MutableVariable")
|
TEST_CASE("MutableVariable")
|
||||||
|
@ -154,8 +154,8 @@ end
|
||||||
const bool args1[] = {false};
|
const bool args1[] = {false};
|
||||||
const bool args2[] = {true};
|
const bool args2[] = {true};
|
||||||
|
|
||||||
CHECK_EQ(38, Luau::Compile::computeCost(model, args1, 1));
|
CHECK_EQ(50, Luau::Compile::computeCost(model, args1, 1));
|
||||||
CHECK_EQ(37, Luau::Compile::computeCost(model, args2, 1));
|
CHECK_EQ(49, Luau::Compile::computeCost(model, args2, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Conditional")
|
TEST_CASE("Conditional")
|
||||||
|
@ -219,8 +219,8 @@ end
|
||||||
const bool args1[] = {false};
|
const bool args1[] = {false};
|
||||||
const bool args2[] = {true};
|
const bool args2[] = {true};
|
||||||
|
|
||||||
CHECK_EQ(4, Luau::Compile::computeCost(model, args1, 1));
|
CHECK_EQ(7, Luau::Compile::computeCost(model, args1, 1));
|
||||||
CHECK_EQ(3, Luau::Compile::computeCost(model, args2, 1));
|
CHECK_EQ(6, Luau::Compile::computeCost(model, args2, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_SUITE_END();
|
TEST_SUITE_END();
|
||||||
|
|
|
@ -92,10 +92,6 @@ Fixture::Fixture(bool freeze, bool prepareAutocomplete)
|
||||||
configResolver.defaultConfig.enabledLint.warningMask = ~0ull;
|
configResolver.defaultConfig.enabledLint.warningMask = ~0ull;
|
||||||
configResolver.defaultConfig.parseOptions.captureComments = true;
|
configResolver.defaultConfig.parseOptions.captureComments = true;
|
||||||
|
|
||||||
registerBuiltinTypes(frontend.typeChecker);
|
|
||||||
if (prepareAutocomplete)
|
|
||||||
registerBuiltinTypes(frontend.typeCheckerForAutocomplete);
|
|
||||||
registerTestTypes();
|
|
||||||
Luau::freeze(frontend.typeChecker.globalTypes);
|
Luau::freeze(frontend.typeChecker.globalTypes);
|
||||||
Luau::freeze(frontend.typeCheckerForAutocomplete.globalTypes);
|
Luau::freeze(frontend.typeCheckerForAutocomplete.globalTypes);
|
||||||
|
|
||||||
|
@ -410,6 +406,21 @@ LoadDefinitionFileResult Fixture::loadDefinition(const std::string& source)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BuiltinsFixture::BuiltinsFixture(bool freeze, bool prepareAutocomplete)
|
||||||
|
: Fixture(freeze, prepareAutocomplete)
|
||||||
|
{
|
||||||
|
Luau::unfreeze(frontend.typeChecker.globalTypes);
|
||||||
|
Luau::unfreeze(frontend.typeCheckerForAutocomplete.globalTypes);
|
||||||
|
|
||||||
|
registerBuiltinTypes(frontend.typeChecker);
|
||||||
|
if (prepareAutocomplete)
|
||||||
|
registerBuiltinTypes(frontend.typeCheckerForAutocomplete);
|
||||||
|
registerTestTypes();
|
||||||
|
|
||||||
|
Luau::freeze(frontend.typeChecker.globalTypes);
|
||||||
|
Luau::freeze(frontend.typeCheckerForAutocomplete.globalTypes);
|
||||||
|
}
|
||||||
|
|
||||||
ModuleName fromString(std::string_view name)
|
ModuleName fromString(std::string_view name)
|
||||||
{
|
{
|
||||||
return ModuleName(name);
|
return ModuleName(name);
|
||||||
|
|
|
@ -151,6 +151,11 @@ struct Fixture
|
||||||
LoadDefinitionFileResult loadDefinition(const std::string& source);
|
LoadDefinitionFileResult loadDefinition(const std::string& source);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BuiltinsFixture : Fixture
|
||||||
|
{
|
||||||
|
BuiltinsFixture(bool freeze = true, bool prepareAutocomplete = false);
|
||||||
|
};
|
||||||
|
|
||||||
ModuleName fromString(std::string_view name);
|
ModuleName fromString(std::string_view name);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -77,7 +77,7 @@ struct NaiveFileResolver : NullFileResolver
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct FrontendFixture : Fixture
|
struct FrontendFixture : BuiltinsFixture
|
||||||
{
|
{
|
||||||
FrontendFixture()
|
FrontendFixture()
|
||||||
{
|
{
|
||||||
|
|
|
@ -75,7 +75,7 @@ _ = 6
|
||||||
CHECK_EQ(result.warnings.size(), 0);
|
CHECK_EQ(result.warnings.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "BuiltinGlobalWrite")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "BuiltinGlobalWrite")
|
||||||
{
|
{
|
||||||
LintResult result = lint(R"(
|
LintResult result = lint(R"(
|
||||||
math = {}
|
math = {}
|
||||||
|
@ -309,7 +309,7 @@ print(arg)
|
||||||
CHECK_EQ(result.warnings[0].text, "Variable 'arg' shadows previous declaration at line 2");
|
CHECK_EQ(result.warnings[0].text, "Variable 'arg' shadows previous declaration at line 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "LocalShadowGlobal")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "LocalShadowGlobal")
|
||||||
{
|
{
|
||||||
LintResult result = lint(R"(
|
LintResult result = lint(R"(
|
||||||
local math = math
|
local math = math
|
||||||
|
@ -1470,7 +1470,7 @@ end
|
||||||
CHECK_EQ(result.warnings[2].text, "Member 'Instance.DataCost' is deprecated");
|
CHECK_EQ(result.warnings[2].text, "Member 'Instance.DataCost' is deprecated");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "TableOperations")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "TableOperations")
|
||||||
{
|
{
|
||||||
LintResult result = lintTyped(R"(
|
LintResult result = lintTyped(R"(
|
||||||
local t = {}
|
local t = {}
|
||||||
|
|
|
@ -113,7 +113,7 @@ TEST_CASE_FIXTURE(Fixture, "deepClone_cyclic_table")
|
||||||
CHECK_EQ(2, dest.typeVars.size()); // One table and one function
|
CHECK_EQ(2, dest.typeVars.size()); // One table and one function
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "builtin_types_point_into_globalTypes_arena")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "builtin_types_point_into_globalTypes_arena")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
return {sign=math.sign}
|
return {sign=math.sign}
|
||||||
|
@ -250,7 +250,7 @@ TEST_CASE_FIXTURE(Fixture, "clone_constrained_intersection")
|
||||||
CHECK_EQ(getSingletonTypes().stringType, ctv->parts[1]);
|
CHECK_EQ(getSingletonTypes().stringType, ctv->parts[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "clone_self_property")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "clone_self_property")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff{"LuauAnyInIsOptionalIsOptional", true};
|
ScopedFastFlag sff{"LuauAnyInIsOptionalIsOptional", true};
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ using namespace Luau;
|
||||||
|
|
||||||
TEST_SUITE_BEGIN("NonstrictModeTests");
|
TEST_SUITE_BEGIN("NonstrictModeTests");
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "function_returns_number_or_string")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "function_returns_number_or_string")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff[]{
|
ScopedFastFlag sff[]{
|
||||||
{"LuauReturnTypeInferenceInNonstrict", true},
|
{"LuauReturnTypeInferenceInNonstrict", true},
|
||||||
|
@ -224,7 +224,7 @@ TEST_CASE_FIXTURE(Fixture, "inline_table_props_are_also_any")
|
||||||
CHECK_MESSAGE(get<FunctionTypeVar>(ttv->props["three"].type), "Should be a function: " << *ttv->props["three"].type);
|
CHECK_MESSAGE(get<FunctionTypeVar>(ttv->props["three"].type), "Should be a function: " << *ttv->props["three"].type);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "for_in_iterator_variables_are_any")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_iterator_variables_are_any")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
|
@ -243,7 +243,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_iterator_variables_are_any")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_dot_insert_and_recursive_calls")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_dot_insert_and_recursive_calls")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
|
|
|
@ -739,7 +739,7 @@ TEST_CASE_FIXTURE(Fixture, "cyclic_table_normalizes_sensibly")
|
||||||
CHECK_EQ("t1 where t1 = { get: () -> t1 }", toString(ty, {true}));
|
CHECK_EQ("t1 where t1 = { get: () -> t1 }", toString(ty, {true}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "union_of_distinct_free_types")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "union_of_distinct_free_types")
|
||||||
{
|
{
|
||||||
ScopedFastFlag flags[] = {
|
ScopedFastFlag flags[] = {
|
||||||
{"LuauLowerBoundsCalculation", true},
|
{"LuauLowerBoundsCalculation", true},
|
||||||
|
@ -760,7 +760,7 @@ TEST_CASE_FIXTURE(Fixture, "union_of_distinct_free_types")
|
||||||
CHECK("<a, b>(a, b) -> a | b" == toString(requireType("fussy")));
|
CHECK("<a, b>(a, b) -> a | b" == toString(requireType("fussy")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "constrained_intersection_of_intersections")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "constrained_intersection_of_intersections")
|
||||||
{
|
{
|
||||||
ScopedFastFlag flags[] = {
|
ScopedFastFlag flags[] = {
|
||||||
{"LuauLowerBoundsCalculation", true},
|
{"LuauLowerBoundsCalculation", true},
|
||||||
|
@ -951,7 +951,7 @@ TEST_CASE_FIXTURE(Fixture, "nested_table_normalization_with_non_table__no_ice")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "visiting_a_type_twice_is_not_considered_normal")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "visiting_a_type_twice_is_not_considered_normal")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff{"LuauLowerBoundsCalculation", true};
|
ScopedFastFlag sff{"LuauLowerBoundsCalculation", true};
|
||||||
|
|
||||||
|
@ -976,7 +976,6 @@ TEST_CASE_FIXTURE(Fixture, "fuzz_failure_instersection_combine_must_follow")
|
||||||
{
|
{
|
||||||
ScopedFastFlag flags[] = {
|
ScopedFastFlag flags[] = {
|
||||||
{"LuauLowerBoundsCalculation", true},
|
{"LuauLowerBoundsCalculation", true},
|
||||||
{"LuauNormalizeCombineIntersectionFix", true},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
|
|
|
@ -1618,8 +1618,6 @@ TEST_CASE_FIXTURE(Fixture, "end_extent_doesnt_consume_comments")
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "end_extent_doesnt_consume_comments_even_with_capture")
|
TEST_CASE_FIXTURE(Fixture, "end_extent_doesnt_consume_comments_even_with_capture")
|
||||||
{
|
{
|
||||||
ScopedFastFlag luauParseLocationIgnoreCommentSkipInCapture{"LuauParseLocationIgnoreCommentSkipInCapture", true};
|
|
||||||
|
|
||||||
// Same should hold when comments are captured
|
// Same should hold when comments are captured
|
||||||
ParseOptions opts;
|
ParseOptions opts;
|
||||||
opts.captureComments = true;
|
opts.captureComments = true;
|
||||||
|
|
|
@ -17,7 +17,7 @@ using namespace Luau;
|
||||||
|
|
||||||
LUAU_FASTFLAG(LuauLowerBoundsCalculation);
|
LUAU_FASTFLAG(LuauLowerBoundsCalculation);
|
||||||
|
|
||||||
struct LimitFixture : Fixture
|
struct LimitFixture : BuiltinsFixture
|
||||||
{
|
{
|
||||||
#if defined(_NOOPT) || defined(_DEBUG)
|
#if defined(_NOOPT) || defined(_DEBUG)
|
||||||
ScopedFastInt LuauTypeInferRecursionLimit{"LuauTypeInferRecursionLimit", 100};
|
ScopedFastInt LuauTypeInferRecursionLimit{"LuauTypeInferRecursionLimit", 100};
|
||||||
|
|
|
@ -224,7 +224,7 @@ n1 -> n4 [label="typePackParam"];
|
||||||
(void)toDot(requireType("a"));
|
(void)toDot(requireType("a"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "metatable")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "metatable")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a: typeof(setmetatable({}, {}))
|
local a: typeof(setmetatable({}, {}))
|
||||||
|
|
|
@ -60,7 +60,7 @@ TEST_CASE_FIXTURE(Fixture, "named_table")
|
||||||
CHECK_EQ("TheTable", toString(&table));
|
CHECK_EQ("TheTable", toString(&table));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "exhaustive_toString_of_cyclic_table")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "exhaustive_toString_of_cyclic_table")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -338,7 +338,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringDetailed")
|
||||||
REQUIRE_EQ("c", toString(params[2], opts));
|
REQUIRE_EQ("c", toString(params[2], opts));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "toStringDetailed2")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "toStringDetailed2")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff{"LuauUnsealedTableLiteral", true};
|
ScopedFastFlag sff{"LuauUnsealedTableLiteral", true};
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,7 @@ TEST_CASE_FIXTURE(Fixture, "stringify_optional_parameterized_alias")
|
||||||
CHECK_EQ("Node<T>", toString(e->wantedType));
|
CHECK_EQ("Node<T>", toString(e->wantedType));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "general_require_multi_assign")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "general_require_multi_assign")
|
||||||
{
|
{
|
||||||
fileResolver.source["workspace/A"] = R"(
|
fileResolver.source["workspace/A"] = R"(
|
||||||
export type myvec2 = {x: number, y: number}
|
export type myvec2 = {x: number, y: number}
|
||||||
|
@ -317,7 +317,7 @@ TEST_CASE_FIXTURE(Fixture, "general_require_multi_assign")
|
||||||
REQUIRE(bType->props.size() == 3);
|
REQUIRE(bType->props.size() == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "type_alias_import_mutation")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "type_alias_import_mutation")
|
||||||
{
|
{
|
||||||
CheckResult result = check("type t10<x> = typeof(table)");
|
CheckResult result = check("type t10<x> = typeof(table)");
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
|
@ -385,7 +385,7 @@ type Cool = typeof(c)
|
||||||
CHECK_EQ(ttv->name, "Cool");
|
CHECK_EQ(ttv->name, "Cool");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "type_alias_of_an_imported_recursive_type")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "type_alias_of_an_imported_recursive_type")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
export type X = { a: number, b: X? }
|
export type X = { a: number, b: X? }
|
||||||
|
@ -410,7 +410,7 @@ type X = Import.X
|
||||||
CHECK_EQ(follow(*ty1), follow(*ty2));
|
CHECK_EQ(follow(*ty1), follow(*ty2));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "type_alias_of_an_imported_recursive_generic_type")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "type_alias_of_an_imported_recursive_generic_type")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
export type X<T, U> = { a: T, b: U, C: X<T, U>? }
|
export type X<T, U> = { a: T, b: U, C: X<T, U>? }
|
||||||
|
@ -564,7 +564,7 @@ TEST_CASE_FIXTURE(Fixture, "non_recursive_aliases_that_reuse_a_generic_name")
|
||||||
*
|
*
|
||||||
* We solved this by ascribing a unique subLevel to each prototyped alias.
|
* We solved this by ascribing a unique subLevel to each prototyped alias.
|
||||||
*/
|
*/
|
||||||
TEST_CASE_FIXTURE(Fixture, "do_not_quantify_unresolved_aliases")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "do_not_quantify_unresolved_aliases")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
|
|
@ -528,7 +528,7 @@ TEST_CASE_FIXTURE(Fixture, "cloned_interface_maintains_pointers_between_definiti
|
||||||
CHECK_EQ(recordType, bType);
|
CHECK_EQ(recordType, bType);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "use_type_required_from_another_file")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "use_type_required_from_another_file")
|
||||||
{
|
{
|
||||||
addGlobalBinding(frontend.typeChecker, "script", frontend.typeChecker.anyType, "@test");
|
addGlobalBinding(frontend.typeChecker, "script", frontend.typeChecker.anyType, "@test");
|
||||||
|
|
||||||
|
@ -554,7 +554,7 @@ TEST_CASE_FIXTURE(Fixture, "use_type_required_from_another_file")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "cannot_use_nonexported_type")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "cannot_use_nonexported_type")
|
||||||
{
|
{
|
||||||
addGlobalBinding(frontend.typeChecker, "script", frontend.typeChecker.anyType, "@test");
|
addGlobalBinding(frontend.typeChecker, "script", frontend.typeChecker.anyType, "@test");
|
||||||
|
|
||||||
|
@ -580,7 +580,7 @@ TEST_CASE_FIXTURE(Fixture, "cannot_use_nonexported_type")
|
||||||
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "builtin_types_are_not_exported")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "builtin_types_are_not_exported")
|
||||||
{
|
{
|
||||||
addGlobalBinding(frontend.typeChecker, "script", frontend.typeChecker.anyType, "@test");
|
addGlobalBinding(frontend.typeChecker, "script", frontend.typeChecker.anyType, "@test");
|
||||||
|
|
||||||
|
@ -676,7 +676,7 @@ TEST_CASE_FIXTURE(Fixture, "luau_ice_is_not_special_without_the_flag")
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "luau_print_is_magic_if_the_flag_is_set")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "luau_print_is_magic_if_the_flag_is_set")
|
||||||
{
|
{
|
||||||
// Luau::resetPrintLine();
|
// Luau::resetPrintLine();
|
||||||
ScopedFastFlag sffs{"DebugLuauMagicTypes", true};
|
ScopedFastFlag sffs{"DebugLuauMagicTypes", true};
|
||||||
|
|
|
@ -237,7 +237,7 @@ TEST_CASE_FIXTURE(Fixture, "chain_calling_error_type_yields_error")
|
||||||
CHECK_EQ("*unknown*", toString(requireType("a")));
|
CHECK_EQ("*unknown*", toString(requireType("a")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "replace_every_free_type_when_unifying_a_complex_function_with_any")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "replace_every_free_type_when_unifying_a_complex_function_with_any")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a: any
|
local a: any
|
||||||
|
@ -285,7 +285,7 @@ end
|
||||||
LUAU_REQUIRE_ERRORS(result);
|
LUAU_REQUIRE_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "metatable_of_any_can_be_a_table")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "metatable_of_any_can_be_a_table")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
|
|
@ -12,7 +12,7 @@ LUAU_FASTFLAG(LuauLowerBoundsCalculation);
|
||||||
|
|
||||||
TEST_SUITE_BEGIN("BuiltinTests");
|
TEST_SUITE_BEGIN("BuiltinTests");
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "math_things_are_defined")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "math_things_are_defined")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a00 = math.frexp
|
local a00 = math.frexp
|
||||||
|
@ -50,7 +50,7 @@ TEST_CASE_FIXTURE(Fixture, "math_things_are_defined")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "next_iterator_should_infer_types_and_type_check")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "next_iterator_should_infer_types_and_type_check")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a: string, b: number = next({ 1 })
|
local a: string, b: number = next({ 1 })
|
||||||
|
@ -63,7 +63,7 @@ TEST_CASE_FIXTURE(Fixture, "next_iterator_should_infer_types_and_type_check")
|
||||||
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "pairs_iterator_should_infer_types_and_type_check")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "pairs_iterator_should_infer_types_and_type_check")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
type Map<K, V> = { [K]: V }
|
type Map<K, V> = { [K]: V }
|
||||||
|
@ -75,7 +75,7 @@ TEST_CASE_FIXTURE(Fixture, "pairs_iterator_should_infer_types_and_type_check")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "ipairs_iterator_should_infer_types_and_type_check")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "ipairs_iterator_should_infer_types_and_type_check")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
type Map<K, V> = { [K]: V }
|
type Map<K, V> = { [K]: V }
|
||||||
|
@ -87,7 +87,7 @@ TEST_CASE_FIXTURE(Fixture, "ipairs_iterator_should_infer_types_and_type_check")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_dot_remove_optionally_returns_generic")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_dot_remove_optionally_returns_generic")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = { 1 }
|
local t = { 1 }
|
||||||
|
@ -98,7 +98,7 @@ TEST_CASE_FIXTURE(Fixture, "table_dot_remove_optionally_returns_generic")
|
||||||
CHECK_EQ(toString(requireType("n")), "number?");
|
CHECK_EQ(toString(requireType("n")), "number?");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_concat_returns_string")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_concat_returns_string")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local r = table.concat({1,2,3,4}, ",", 2);
|
local r = table.concat({1,2,3,4}, ",", 2);
|
||||||
|
@ -108,7 +108,7 @@ TEST_CASE_FIXTURE(Fixture, "table_concat_returns_string")
|
||||||
CHECK_EQ(*typeChecker.stringType, *requireType("r"));
|
CHECK_EQ(*typeChecker.stringType, *requireType("r"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "sort")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "sort")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = {1, 2, 3};
|
local t = {1, 2, 3};
|
||||||
|
@ -118,7 +118,7 @@ TEST_CASE_FIXTURE(Fixture, "sort")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "sort_with_predicate")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "sort_with_predicate")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -130,7 +130,7 @@ TEST_CASE_FIXTURE(Fixture, "sort_with_predicate")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "sort_with_bad_predicate")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "sort_with_bad_predicate")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -140,6 +140,12 @@ TEST_CASE_FIXTURE(Fixture, "sort_with_bad_predicate")
|
||||||
)");
|
)");
|
||||||
|
|
||||||
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
||||||
|
CHECK_EQ(R"(Type '(number, number) -> boolean' could not be converted into '((a, a) -> boolean)?'
|
||||||
|
caused by:
|
||||||
|
None of the union options are compatible. For example: Type '(number, number) -> boolean' could not be converted into '(a, a) -> boolean'
|
||||||
|
caused by:
|
||||||
|
Argument #1 type is not compatible. Type 'string' could not be converted into 'number')",
|
||||||
|
toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "strings_have_methods")
|
TEST_CASE_FIXTURE(Fixture, "strings_have_methods")
|
||||||
|
@ -152,7 +158,7 @@ TEST_CASE_FIXTURE(Fixture, "strings_have_methods")
|
||||||
CHECK_EQ(*typeChecker.stringType, *requireType("s"));
|
CHECK_EQ(*typeChecker.stringType, *requireType("s"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "math_max_variatic")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "math_max_variatic")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local n = math.max(1,2,3,4,5,6,7,8,9,0)
|
local n = math.max(1,2,3,4,5,6,7,8,9,0)
|
||||||
|
@ -162,16 +168,17 @@ TEST_CASE_FIXTURE(Fixture, "math_max_variatic")
|
||||||
CHECK_EQ(*typeChecker.numberType, *requireType("n"));
|
CHECK_EQ(*typeChecker.numberType, *requireType("n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "math_max_checks_for_numbers")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "math_max_checks_for_numbers")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local n = math.max(1,2,"3")
|
local n = math.max(1,2,"3")
|
||||||
)");
|
)");
|
||||||
|
|
||||||
CHECK(!result.errors.empty());
|
CHECK(!result.errors.empty());
|
||||||
|
CHECK_EQ("Type 'string' could not be converted into 'number'", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "builtin_tables_sealed")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "builtin_tables_sealed")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"LUA(
|
CheckResult result = check(R"LUA(
|
||||||
local b = bit32
|
local b = bit32
|
||||||
|
@ -183,7 +190,7 @@ TEST_CASE_FIXTURE(Fixture, "builtin_tables_sealed")
|
||||||
CHECK_EQ(bit32t->state, TableState::Sealed);
|
CHECK_EQ(bit32t->state, TableState::Sealed);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "lua_51_exported_globals_all_exist")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "lua_51_exported_globals_all_exist")
|
||||||
{
|
{
|
||||||
// Extracted from lua5.1
|
// Extracted from lua5.1
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
|
@ -340,7 +347,7 @@ TEST_CASE_FIXTURE(Fixture, "lua_51_exported_globals_all_exist")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "setmetatable_unpacks_arg_types_correctly")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "setmetatable_unpacks_arg_types_correctly")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
setmetatable({}, setmetatable({}, {}))
|
setmetatable({}, setmetatable({}, {}))
|
||||||
|
@ -348,7 +355,7 @@ TEST_CASE_FIXTURE(Fixture, "setmetatable_unpacks_arg_types_correctly")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_insert_correctly_infers_type_of_array_2_args_overload")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_correctly_infers_type_of_array_2_args_overload")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = {}
|
local t = {}
|
||||||
|
@ -360,7 +367,7 @@ TEST_CASE_FIXTURE(Fixture, "table_insert_correctly_infers_type_of_array_2_args_o
|
||||||
CHECK_EQ(typeChecker.stringType, requireType("s"));
|
CHECK_EQ(typeChecker.stringType, requireType("s"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_insert_correctly_infers_type_of_array_3_args_overload")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_correctly_infers_type_of_array_3_args_overload")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = {}
|
local t = {}
|
||||||
|
@ -372,7 +379,7 @@ TEST_CASE_FIXTURE(Fixture, "table_insert_correctly_infers_type_of_array_3_args_o
|
||||||
CHECK_EQ("string", toString(requireType("s")));
|
CHECK_EQ("string", toString(requireType("s")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_pack")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_pack")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = table.pack(1, "foo", true)
|
local t = table.pack(1, "foo", true)
|
||||||
|
@ -382,7 +389,7 @@ TEST_CASE_FIXTURE(Fixture, "table_pack")
|
||||||
CHECK_EQ("{| [number]: boolean | number | string, n: number |}", toString(requireType("t")));
|
CHECK_EQ("{| [number]: boolean | number | string, n: number |}", toString(requireType("t")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_pack_variadic")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_pack_variadic")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -397,7 +404,7 @@ local t = table.pack(f())
|
||||||
CHECK_EQ("{| [number]: number | string, n: number |}", toString(requireType("t")));
|
CHECK_EQ("{| [number]: number | string, n: number |}", toString(requireType("t")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_pack_reduce")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_pack_reduce")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = table.pack(1, 2, true)
|
local t = table.pack(1, 2, true)
|
||||||
|
@ -414,7 +421,7 @@ TEST_CASE_FIXTURE(Fixture, "table_pack_reduce")
|
||||||
CHECK_EQ("{| [number]: string, n: number |}", toString(requireType("t")));
|
CHECK_EQ("{| [number]: string, n: number |}", toString(requireType("t")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "gcinfo")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "gcinfo")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local n = gcinfo()
|
local n = gcinfo()
|
||||||
|
@ -424,12 +431,12 @@ TEST_CASE_FIXTURE(Fixture, "gcinfo")
|
||||||
CHECK_EQ(*typeChecker.numberType, *requireType("n"));
|
CHECK_EQ(*typeChecker.numberType, *requireType("n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "getfenv")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "getfenv")
|
||||||
{
|
{
|
||||||
LUAU_REQUIRE_NO_ERRORS(check("getfenv(1)"));
|
LUAU_REQUIRE_NO_ERRORS(check("getfenv(1)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "os_time_takes_optional_date_table")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "os_time_takes_optional_date_table")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local n1 = os.time()
|
local n1 = os.time()
|
||||||
|
@ -443,7 +450,7 @@ TEST_CASE_FIXTURE(Fixture, "os_time_takes_optional_date_table")
|
||||||
CHECK_EQ(*typeChecker.numberType, *requireType("n3"));
|
CHECK_EQ(*typeChecker.numberType, *requireType("n3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "thread_is_a_type")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "thread_is_a_type")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local co = coroutine.create(function() end)
|
local co = coroutine.create(function() end)
|
||||||
|
@ -453,7 +460,7 @@ TEST_CASE_FIXTURE(Fixture, "thread_is_a_type")
|
||||||
CHECK_EQ(*typeChecker.threadType, *requireType("co"));
|
CHECK_EQ(*typeChecker.threadType, *requireType("co"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "coroutine_resume_anything_goes")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "coroutine_resume_anything_goes")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function nifty(x, y)
|
local function nifty(x, y)
|
||||||
|
@ -471,7 +478,7 @@ TEST_CASE_FIXTURE(Fixture, "coroutine_resume_anything_goes")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "coroutine_wrap_anything_goes")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "coroutine_wrap_anything_goes")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
|
@ -490,7 +497,7 @@ TEST_CASE_FIXTURE(Fixture, "coroutine_wrap_anything_goes")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "setmetatable_should_not_mutate_persisted_types")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "setmetatable_should_not_mutate_persisted_types")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local string = string
|
local string = string
|
||||||
|
@ -505,7 +512,7 @@ TEST_CASE_FIXTURE(Fixture, "setmetatable_should_not_mutate_persisted_types")
|
||||||
REQUIRE(ttv);
|
REQUIRE(ttv);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "string_format_arg_types_inference")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "string_format_arg_types_inference")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -518,7 +525,7 @@ TEST_CASE_FIXTURE(Fixture, "string_format_arg_types_inference")
|
||||||
CHECK_EQ("(number, number, string) -> string", toString(requireType("f")));
|
CHECK_EQ("(number, number, string) -> string", toString(requireType("f")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "string_format_arg_count_mismatch")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "string_format_arg_count_mismatch")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -534,7 +541,7 @@ TEST_CASE_FIXTURE(Fixture, "string_format_arg_count_mismatch")
|
||||||
CHECK_EQ(result.errors[2].location.begin.line, 4);
|
CHECK_EQ(result.errors[2].location.begin.line, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "string_format_correctly_ordered_types")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "string_format_correctly_ordered_types")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -548,7 +555,7 @@ TEST_CASE_FIXTURE(Fixture, "string_format_correctly_ordered_types")
|
||||||
CHECK_EQ(tm->givenType, typeChecker.numberType);
|
CHECK_EQ(tm->givenType, typeChecker.numberType);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "xpcall")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "xpcall")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -564,7 +571,7 @@ TEST_CASE_FIXTURE(Fixture, "xpcall")
|
||||||
CHECK_EQ("boolean", toString(requireType("c")));
|
CHECK_EQ("boolean", toString(requireType("c")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "see_thru_select")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "see_thru_select")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a:number, b:boolean = select(2,"hi", 10, true)
|
local a:number, b:boolean = select(2,"hi", 10, true)
|
||||||
|
@ -573,7 +580,7 @@ TEST_CASE_FIXTURE(Fixture, "see_thru_select")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "see_thru_select_count")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "see_thru_select_count")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a = select("#","hi", 10, true)
|
local a = select("#","hi", 10, true)
|
||||||
|
@ -583,7 +590,7 @@ TEST_CASE_FIXTURE(Fixture, "see_thru_select_count")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "select_with_decimal_argument_is_rounded_down")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "select_with_decimal_argument_is_rounded_down")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a: number, b: boolean = select(2.9, "foo", 1, true)
|
local a: number, b: boolean = select(2.9, "foo", 1, true)
|
||||||
|
@ -608,7 +615,7 @@ TEST_CASE_FIXTURE(Fixture, "bad_select_should_not_crash")
|
||||||
CHECK_LE(0, result.errors.size());
|
CHECK_LE(0, result.errors.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "select_way_out_of_range")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "select_way_out_of_range")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
select(5432598430953240958)
|
select(5432598430953240958)
|
||||||
|
@ -619,7 +626,7 @@ TEST_CASE_FIXTURE(Fixture, "select_way_out_of_range")
|
||||||
CHECK_EQ("bad argument #1 to select (index out of range)", toString(result.errors[0]));
|
CHECK_EQ("bad argument #1 to select (index out of range)", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "select_slightly_out_of_range")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "select_slightly_out_of_range")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
select(3, "a", 1)
|
select(3, "a", 1)
|
||||||
|
@ -630,7 +637,7 @@ TEST_CASE_FIXTURE(Fixture, "select_slightly_out_of_range")
|
||||||
CHECK_EQ("bad argument #1 to select (index out of range)", toString(result.errors[0]));
|
CHECK_EQ("bad argument #1 to select (index out of range)", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "select_with_variadic_typepack_tail")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "select_with_variadic_typepack_tail")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
|
@ -649,7 +656,7 @@ TEST_CASE_FIXTURE(Fixture, "select_with_variadic_typepack_tail")
|
||||||
CHECK_EQ("any", toString(requireType("quux")));
|
CHECK_EQ("any", toString(requireType("quux")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "select_with_variadic_typepack_tail_and_string_head")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "select_with_variadic_typepack_tail_and_string_head")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
|
@ -703,7 +710,7 @@ TEST_CASE_FIXTURE(Fixture, "string_format_use_correct_argument2")
|
||||||
CHECK_EQ("Type 'number' could not be converted into 'string'", toString(result.errors[1]));
|
CHECK_EQ("Type 'number' could not be converted into 'string'", toString(result.errors[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "debug_traceback_is_crazy")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "debug_traceback_is_crazy")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local co: thread = ...
|
local co: thread = ...
|
||||||
|
@ -720,7 +727,7 @@ debug.traceback(co, "msg", 1)
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "debug_info_is_crazy")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "debug_info_is_crazy")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local co: thread, f: ()->() = ...
|
local co: thread, f: ()->() = ...
|
||||||
|
@ -734,7 +741,7 @@ debug.info(f, "n")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "aliased_string_format")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "aliased_string_format")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local fmt = string.format
|
local fmt = string.format
|
||||||
|
@ -745,7 +752,7 @@ TEST_CASE_FIXTURE(Fixture, "aliased_string_format")
|
||||||
CHECK_EQ("Type 'string' could not be converted into 'number'", toString(result.errors[0]));
|
CHECK_EQ("Type 'string' could not be converted into 'number'", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "string_lib_self_noself")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "string_lib_self_noself")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
|
@ -764,7 +771,7 @@ TEST_CASE_FIXTURE(Fixture, "string_lib_self_noself")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "gmatch_definition")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "gmatch_definition")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"_(
|
CheckResult result = check(R"_(
|
||||||
local a, b, c = ("hey"):gmatch("(.)(.)(.)")()
|
local a, b, c = ("hey"):gmatch("(.)(.)(.)")()
|
||||||
|
@ -777,7 +784,7 @@ end
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "select_on_variadic")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "select_on_variadic")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function f(): (number, ...(boolean | number))
|
local function f(): (number, ...(boolean | number))
|
||||||
|
@ -793,7 +800,7 @@ TEST_CASE_FIXTURE(Fixture, "select_on_variadic")
|
||||||
CHECK_EQ("any", toString(requireType("c")));
|
CHECK_EQ("any", toString(requireType("c")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "string_format_report_all_type_errors_at_correct_positions")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "string_format_report_all_type_errors_at_correct_positions")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
("%s%d%s"):format(1, "hello", true)
|
("%s%d%s"):format(1, "hello", true)
|
||||||
|
@ -825,7 +832,7 @@ TEST_CASE_FIXTURE(Fixture, "string_format_report_all_type_errors_at_correct_posi
|
||||||
CHECK_EQ(TypeErrorData(TypeMismatch{stringType, booleanType}), result.errors[5].data);
|
CHECK_EQ(TypeErrorData(TypeMismatch{stringType, booleanType}), result.errors[5].data);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "tonumber_returns_optional_number_type")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "tonumber_returns_optional_number_type")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -836,7 +843,7 @@ TEST_CASE_FIXTURE(Fixture, "tonumber_returns_optional_number_type")
|
||||||
CHECK_EQ("Type 'number?' could not be converted into 'number'", toString(result.errors[0]));
|
CHECK_EQ("Type 'number?' could not be converted into 'number'", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "tonumber_returns_optional_number_type2")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "tonumber_returns_optional_number_type2")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -846,7 +853,7 @@ TEST_CASE_FIXTURE(Fixture, "tonumber_returns_optional_number_type2")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "dont_add_definitions_to_persistent_types")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "dont_add_definitions_to_persistent_types")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local f = math.sin
|
local f = math.sin
|
||||||
|
@ -868,7 +875,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_add_definitions_to_persistent_types")
|
||||||
REQUIRE(gtv->definition);
|
REQUIRE(gtv->definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "assert_removes_falsy_types")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "assert_removes_falsy_types")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff[]{
|
ScopedFastFlag sff[]{
|
||||||
{"LuauAssertStripsFalsyTypes", true},
|
{"LuauAssertStripsFalsyTypes", true},
|
||||||
|
@ -889,7 +896,7 @@ TEST_CASE_FIXTURE(Fixture, "assert_removes_falsy_types")
|
||||||
CHECK_EQ("((boolean | number)?) -> boolean | number", toString(requireType("f")));
|
CHECK_EQ("((boolean | number)?) -> boolean | number", toString(requireType("f")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "assert_removes_falsy_types2")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "assert_removes_falsy_types2")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff[]{
|
ScopedFastFlag sff[]{
|
||||||
{"LuauAssertStripsFalsyTypes", true},
|
{"LuauAssertStripsFalsyTypes", true},
|
||||||
|
@ -907,7 +914,7 @@ TEST_CASE_FIXTURE(Fixture, "assert_removes_falsy_types2")
|
||||||
CHECK_EQ("((boolean | number)?) -> number | true", toString(requireType("f")));
|
CHECK_EQ("((boolean | number)?) -> number | true", toString(requireType("f")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "assert_removes_falsy_types_even_from_type_pack_tail_but_only_for_the_first_type")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "assert_removes_falsy_types_even_from_type_pack_tail_but_only_for_the_first_type")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff[]{
|
ScopedFastFlag sff[]{
|
||||||
{"LuauAssertStripsFalsyTypes", true},
|
{"LuauAssertStripsFalsyTypes", true},
|
||||||
|
@ -924,7 +931,7 @@ TEST_CASE_FIXTURE(Fixture, "assert_removes_falsy_types_even_from_type_pack_tail_
|
||||||
CHECK_EQ("(...number?) -> (number, ...number?)", toString(requireType("f")));
|
CHECK_EQ("(...number?) -> (number, ...number?)", toString(requireType("f")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "assert_returns_false_and_string_iff_it_knows_the_first_argument_cannot_be_truthy")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "assert_returns_false_and_string_iff_it_knows_the_first_argument_cannot_be_truthy")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff[]{
|
ScopedFastFlag sff[]{
|
||||||
{"LuauAssertStripsFalsyTypes", true},
|
{"LuauAssertStripsFalsyTypes", true},
|
||||||
|
@ -941,7 +948,7 @@ TEST_CASE_FIXTURE(Fixture, "assert_returns_false_and_string_iff_it_knows_the_fir
|
||||||
CHECK_EQ("(nil) -> nil", toString(requireType("f")));
|
CHECK_EQ("(nil) -> nil", toString(requireType("f")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_freeze_is_generic")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_freeze_is_generic")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t1: {a: number} = {a = 42}
|
local t1: {a: number} = {a = 42}
|
||||||
|
@ -968,7 +975,7 @@ TEST_CASE_FIXTURE(Fixture, "table_freeze_is_generic")
|
||||||
CHECK_EQ("*unknown*", toString(requireType("d")));
|
CHECK_EQ("*unknown*", toString(requireType("d")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "set_metatable_needs_arguments")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "set_metatable_needs_arguments")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff{"LuauSetMetaTableArgsCheck", true};
|
ScopedFastFlag sff{"LuauSetMetaTableArgsCheck", true};
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
|
@ -991,7 +998,7 @@ local function f(a: typeof(f)) end
|
||||||
CHECK_EQ("Unknown global 'f'", toString(result.errors[0]));
|
CHECK_EQ("Unknown global 'f'", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "no_persistent_typelevel_change")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "no_persistent_typelevel_change")
|
||||||
{
|
{
|
||||||
TypeId mathTy = requireType(typeChecker.globalScope, "math");
|
TypeId mathTy = requireType(typeChecker.globalScope, "math");
|
||||||
REQUIRE(mathTy);
|
REQUIRE(mathTy);
|
||||||
|
@ -1008,7 +1015,7 @@ TEST_CASE_FIXTURE(Fixture, "no_persistent_typelevel_change")
|
||||||
CHECK(ftv->level.subLevel == original.subLevel);
|
CHECK(ftv->level.subLevel == original.subLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "global_singleton_types_are_sealed")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "global_singleton_types_are_sealed")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function f(x: string)
|
local function f(x: string)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
using namespace Luau;
|
using namespace Luau;
|
||||||
using std::nullopt;
|
using std::nullopt;
|
||||||
|
|
||||||
struct ClassFixture : Fixture
|
struct ClassFixture : BuiltinsFixture
|
||||||
{
|
{
|
||||||
ClassFixture()
|
ClassFixture()
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,7 +85,7 @@ TEST_CASE_FIXTURE(Fixture, "vararg_functions_should_allow_calls_of_any_types_and
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "vararg_function_is_quantified")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "vararg_function_is_quantified")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local T = {}
|
local T = {}
|
||||||
|
@ -555,7 +555,7 @@ TEST_CASE_FIXTURE(Fixture, "higher_order_function_3")
|
||||||
CHECK(bool(argType->indexer));
|
CHECK(bool(argType->indexer));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "higher_order_function_4")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "higher_order_function_4")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
function bottomupmerge(comp, a, b, left, mid, right)
|
function bottomupmerge(comp, a, b, left, mid, right)
|
||||||
|
@ -620,7 +620,7 @@ TEST_CASE_FIXTURE(Fixture, "higher_order_function_4")
|
||||||
CHECK_EQ(*arg0->indexer->indexResultType, *arg1Args[1]);
|
CHECK_EQ(*arg0->indexer->indexResultType, *arg1Args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "mutual_recursion")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "mutual_recursion")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -639,7 +639,7 @@ TEST_CASE_FIXTURE(Fixture, "mutual_recursion")
|
||||||
dumpErrors(result);
|
dumpErrors(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "toposort_doesnt_break_mutual_recursion")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "toposort_doesnt_break_mutual_recursion")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -676,7 +676,7 @@ TEST_CASE_FIXTURE(Fixture, "check_function_before_lambda_that_uses_it")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "it_is_ok_to_oversaturate_a_higher_order_function_argument")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "it_is_ok_to_oversaturate_a_higher_order_function_argument")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
function onerror() end
|
function onerror() end
|
||||||
|
@ -794,7 +794,7 @@ TEST_CASE_FIXTURE(Fixture, "calling_function_with_incorrect_argument_type_yields
|
||||||
}}));
|
}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "calling_function_with_anytypepack_doesnt_leak_free_types")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "calling_function_with_anytypepack_doesnt_leak_free_types")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff[]{
|
ScopedFastFlag sff[]{
|
||||||
{"LuauReturnTypeInferenceInNonstrict", true},
|
{"LuauReturnTypeInferenceInNonstrict", true},
|
||||||
|
@ -966,7 +966,7 @@ TEST_CASE_FIXTURE(Fixture, "return_type_by_overload")
|
||||||
CHECK_EQ("string", toString(requireType("z")));
|
CHECK_EQ("string", toString(requireType("z")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "infer_anonymous_function_arguments")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "infer_anonymous_function_arguments")
|
||||||
{
|
{
|
||||||
// Simple direct arg to arg propagation
|
// Simple direct arg to arg propagation
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
|
@ -1068,7 +1068,7 @@ f(function(x) return x * 2 end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "infer_anonymous_function_arguments")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "infer_anonymous_function_arguments")
|
||||||
{
|
{
|
||||||
// Simple direct arg to arg propagation
|
// Simple direct arg to arg propagation
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
|
@ -1287,10 +1287,8 @@ caused by:
|
||||||
Return #2 type is not compatible. Type 'string' could not be converted into 'boolean')");
|
Return #2 type is not compatible. Type 'string' could not be converted into 'boolean')");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "function_decl_quantify_right_type")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "function_decl_quantify_right_type")
|
||||||
{
|
{
|
||||||
ScopedFastFlag statFunctionSimplify{"LuauStatFunctionSimplify4", true};
|
|
||||||
|
|
||||||
fileResolver.source["game/isAMagicMock"] = R"(
|
fileResolver.source["game/isAMagicMock"] = R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
return function(value)
|
return function(value)
|
||||||
|
@ -1311,10 +1309,8 @@ end
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "function_decl_non_self_sealed_overwrite")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "function_decl_non_self_sealed_overwrite")
|
||||||
{
|
{
|
||||||
ScopedFastFlag statFunctionSimplify{"LuauStatFunctionSimplify4", true};
|
|
||||||
|
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
function string.len(): number
|
function string.len(): number
|
||||||
return 1
|
return 1
|
||||||
|
@ -1333,11 +1329,8 @@ print(string.len('hello'))
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "function_decl_non_self_sealed_overwrite_2")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "function_decl_non_self_sealed_overwrite_2")
|
||||||
{
|
{
|
||||||
ScopedFastFlag statFunctionSimplify{"LuauStatFunctionSimplify4", true};
|
|
||||||
ScopedFastFlag inferStatFunction{"LuauInferStatFunction", true};
|
|
||||||
|
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t: { f: ((x: number) -> number)? } = {}
|
local t: { f: ((x: number) -> number)? } = {}
|
||||||
|
|
||||||
|
@ -1477,11 +1470,8 @@ TEST_CASE_FIXTURE(Fixture, "inferred_higher_order_functions_are_quantified_at_th
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "function_decl_non_self_unsealed_overwrite")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "function_decl_non_self_unsealed_overwrite")
|
||||||
{
|
{
|
||||||
ScopedFastFlag statFunctionSimplify{"LuauStatFunctionSimplify4", true};
|
|
||||||
ScopedFastFlag inferStatFunction{"LuauInferStatFunction", true};
|
|
||||||
|
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = { f = nil :: ((x: number) -> number)? }
|
local t = { f = nil :: ((x: number) -> number)? }
|
||||||
|
|
||||||
|
@ -1518,8 +1508,6 @@ TEST_CASE_FIXTURE(Fixture, "strict_mode_ok_with_missing_arguments")
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "function_statement_sealed_table_assignment_through_indexer")
|
TEST_CASE_FIXTURE(Fixture, "function_statement_sealed_table_assignment_through_indexer")
|
||||||
{
|
{
|
||||||
ScopedFastFlag statFunctionSimplify{"LuauStatFunctionSimplify4", true};
|
|
||||||
|
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t: {[string]: () -> number} = {}
|
local t: {[string]: () -> number} = {}
|
||||||
|
|
||||||
|
@ -1580,7 +1568,7 @@ wrapper(test)
|
||||||
CHECK(acm->isVariadic);
|
CHECK(acm->isVariadic);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "too_few_arguments_variadic_generic2")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "too_few_arguments_variadic_generic2")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
function test(a: number, b: string, ...)
|
function test(a: number, b: string, ...)
|
||||||
|
|
|
@ -67,7 +67,7 @@ TEST_CASE_FIXTURE(Fixture, "local_vars_can_be_polytypes")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "inferred_local_vars_can_be_polytypes")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "inferred_local_vars_can_be_polytypes")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function id(x) return x end
|
local function id(x) return x end
|
||||||
|
@ -79,7 +79,7 @@ TEST_CASE_FIXTURE(Fixture, "inferred_local_vars_can_be_polytypes")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "local_vars_can_be_instantiated_polytypes")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "local_vars_can_be_instantiated_polytypes")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function id(x) return x end
|
local function id(x) return x end
|
||||||
|
@ -609,7 +609,7 @@ TEST_CASE_FIXTURE(Fixture, "typefuns_sharing_types")
|
||||||
CHECK(requireType("y1") == requireType("y2"));
|
CHECK(requireType("y1") == requireType("y2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "bound_tables_do_not_clone_original_fields")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "bound_tables_do_not_clone_original_fields")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local exports = {}
|
local exports = {}
|
||||||
|
@ -675,7 +675,7 @@ local d: D = c
|
||||||
R"(Type '() -> ()' could not be converted into '<T...>() -> ()'; different number of generic type pack parameters)");
|
R"(Type '() -> ()' could not be converted into '<T...>() -> ()'; different number of generic type pack parameters)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "generic_functions_dont_cache_type_parameters")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "generic_functions_dont_cache_type_parameters")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
-- See https://github.com/Roblox/luau/issues/332
|
-- See https://github.com/Roblox/luau/issues/332
|
||||||
|
@ -1013,7 +1013,7 @@ TEST_CASE_FIXTURE(Fixture, "no_stack_overflow_from_quantifying")
|
||||||
CHECK(it != result.errors.end());
|
CHECK(it != result.errors.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "infer_generic_function_function_argument")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "infer_generic_function_function_argument")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff{"LuauUnsealedTableLiteral", true};
|
ScopedFastFlag sff{"LuauUnsealedTableLiteral", true};
|
||||||
|
|
||||||
|
@ -1078,7 +1078,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_generic_function_function_argument_overloaded"
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "infer_generic_lib_function_function_argument")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "infer_generic_lib_function_function_argument")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a = {{x=4}, {x=7}, {x=1}}
|
local a = {{x=4}, {x=7}, {x=1}}
|
||||||
|
|
|
@ -316,8 +316,6 @@ TEST_CASE_FIXTURE(Fixture, "table_intersection_write_sealed")
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_intersection_write_sealed_indirect")
|
TEST_CASE_FIXTURE(Fixture, "table_intersection_write_sealed_indirect")
|
||||||
{
|
{
|
||||||
ScopedFastFlag statFunctionSimplify{"LuauStatFunctionSimplify4", true};
|
|
||||||
|
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
type X = { x: (number) -> number }
|
type X = { x: (number) -> number }
|
||||||
type Y = { y: (string) -> string }
|
type Y = { y: (string) -> string }
|
||||||
|
@ -351,8 +349,6 @@ caused by:
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_write_sealed_indirect")
|
TEST_CASE_FIXTURE(Fixture, "table_write_sealed_indirect")
|
||||||
{
|
{
|
||||||
ScopedFastFlag statFunctionSimplify{"LuauStatFunctionSimplify4", true};
|
|
||||||
|
|
||||||
// After normalization, previous 'table_intersection_write_sealed_indirect' is identical to this one
|
// After normalization, previous 'table_intersection_write_sealed_indirect' is identical to this one
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
type XY = { x: (number) -> number, y: (string) -> string }
|
type XY = { x: (number) -> number, y: (string) -> string }
|
||||||
|
@ -375,7 +371,7 @@ caused by:
|
||||||
CHECK_EQ(toString(result.errors[3]), "Cannot add property 'w' to table 'XY'");
|
CHECK_EQ(toString(result.errors[3]), "Cannot add property 'w' to table 'XY'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_intersection_setmetatable")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_intersection_setmetatable")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t: {} & {}
|
local t: {} & {}
|
||||||
|
|
|
@ -29,7 +29,7 @@ TEST_CASE_FIXTURE(Fixture, "for_loop")
|
||||||
CHECK_EQ(*typeChecker.numberType, *requireType("q"));
|
CHECK_EQ(*typeChecker.numberType, *requireType("q"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "for_in_loop")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_loop")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local n
|
local n
|
||||||
|
@ -46,7 +46,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop")
|
||||||
CHECK_EQ(*typeChecker.stringType, *requireType("s"));
|
CHECK_EQ(*typeChecker.stringType, *requireType("s"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "for_in_loop_with_next")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_loop_with_next")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local n
|
local n
|
||||||
|
@ -90,7 +90,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_should_fail_with_non_function_iterator")
|
||||||
CHECK_EQ("Cannot call non-function string", toString(result.errors[0]));
|
CHECK_EQ("Cannot call non-function string", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "for_in_with_just_one_iterator_is_ok")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_with_just_one_iterator_is_ok")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function keys(dictionary)
|
local function keys(dictionary)
|
||||||
|
@ -109,7 +109,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_with_just_one_iterator_is_ok")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "for_in_with_a_custom_iterator_should_type_check")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_with_a_custom_iterator_should_type_check")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function range(l, h): () -> number
|
local function range(l, h): () -> number
|
||||||
|
@ -161,7 +161,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_on_non_function")
|
||||||
REQUIRE(get<CannotCallNonFunction>(result.errors[0]));
|
REQUIRE(get<CannotCallNonFunction>(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "for_in_loop_error_on_factory_not_returning_the_right_amount_of_values")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_loop_error_on_factory_not_returning_the_right_amount_of_values")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function hasDivisors(value: number, table)
|
local function hasDivisors(value: number, table)
|
||||||
|
@ -210,7 +210,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_error_on_factory_not_returning_the_right
|
||||||
CHECK_EQ(typeChecker.stringType, tm->givenType);
|
CHECK_EQ(typeChecker.stringType, tm->givenType);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "for_in_loop_error_on_iterator_requiring_args_but_none_given")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_loop_error_on_iterator_requiring_args_but_none_given")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
function prime_iter(state, index)
|
function prime_iter(state, index)
|
||||||
|
@ -288,7 +288,7 @@ TEST_CASE_FIXTURE(Fixture, "repeat_loop_condition_binds_to_its_block")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "symbols_in_repeat_block_should_not_be_visible_beyond_until_condition")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "symbols_in_repeat_block_should_not_be_visible_beyond_until_condition")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
repeat
|
repeat
|
||||||
|
@ -301,7 +301,7 @@ TEST_CASE_FIXTURE(Fixture, "symbols_in_repeat_block_should_not_be_visible_beyond
|
||||||
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "varlist_declared_by_for_in_loop_should_be_free")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "varlist_declared_by_for_in_loop_should_be_free")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local T = {}
|
local T = {}
|
||||||
|
@ -316,7 +316,7 @@ TEST_CASE_FIXTURE(Fixture, "varlist_declared_by_for_in_loop_should_be_free")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "properly_infer_iteratee_is_a_free_table")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "properly_infer_iteratee_is_a_free_table")
|
||||||
{
|
{
|
||||||
// In this case, we cannot know the element type of the table {}. It could be anything.
|
// In this case, we cannot know the element type of the table {}. It could be anything.
|
||||||
// We therefore must initially ascribe a free typevar to iter.
|
// We therefore must initially ascribe a free typevar to iter.
|
||||||
|
@ -329,7 +329,7 @@ TEST_CASE_FIXTURE(Fixture, "properly_infer_iteratee_is_a_free_table")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "correctly_scope_locals_while")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "correctly_scope_locals_while")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
while true do
|
while true do
|
||||||
|
@ -346,7 +346,7 @@ TEST_CASE_FIXTURE(Fixture, "correctly_scope_locals_while")
|
||||||
CHECK_EQ(us->name, "a");
|
CHECK_EQ(us->name, "a");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "ipairs_produces_integral_indices")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "ipairs_produces_integral_indices")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local key
|
local key
|
||||||
|
@ -378,7 +378,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_where_iteratee_is_free")
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "unreachable_code_after_infinite_loop")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "unreachable_code_after_infinite_loop")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
|
@ -460,7 +460,7 @@ TEST_CASE_FIXTURE(Fixture, "unreachable_code_after_infinite_loop")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "loop_typecheck_crash_on_empty_optional")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "loop_typecheck_crash_on_empty_optional")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = {}
|
local t = {}
|
||||||
|
@ -541,7 +541,7 @@ TEST_CASE_FIXTURE(Fixture, "loop_iter_no_indexer")
|
||||||
CHECK_EQ("Cannot iterate over a table without indexer", ge->message);
|
CHECK_EQ("Cannot iterate over a table without indexer", ge->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "loop_iter_iter_metamethod")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "loop_iter_iter_metamethod")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff{"LuauTypecheckIter", true};
|
ScopedFastFlag sff{"LuauTypecheckIter", true};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ LUAU_FASTFLAG(LuauTableSubtypingVariance2)
|
||||||
|
|
||||||
TEST_SUITE_BEGIN("TypeInferModules");
|
TEST_SUITE_BEGIN("TypeInferModules");
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "require")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "require")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
local function hooty(x: number): string
|
local function hooty(x: number): string
|
||||||
|
@ -54,7 +54,7 @@ TEST_CASE_FIXTURE(Fixture, "require")
|
||||||
REQUIRE_EQ("number", toString(*hType));
|
REQUIRE_EQ("number", toString(*hType));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "require_types")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "require_types")
|
||||||
{
|
{
|
||||||
fileResolver.source["workspace/A"] = R"(
|
fileResolver.source["workspace/A"] = R"(
|
||||||
export type Point = {x: number, y: number}
|
export type Point = {x: number, y: number}
|
||||||
|
@ -69,7 +69,7 @@ TEST_CASE_FIXTURE(Fixture, "require_types")
|
||||||
)";
|
)";
|
||||||
|
|
||||||
CheckResult bResult = frontend.check("workspace/B");
|
CheckResult bResult = frontend.check("workspace/B");
|
||||||
dumpErrors(bResult);
|
LUAU_REQUIRE_NO_ERRORS(bResult);
|
||||||
|
|
||||||
ModulePtr b = frontend.moduleResolver.modules["workspace/B"];
|
ModulePtr b = frontend.moduleResolver.modules["workspace/B"];
|
||||||
REQUIRE(b != nullptr);
|
REQUIRE(b != nullptr);
|
||||||
|
@ -78,7 +78,7 @@ TEST_CASE_FIXTURE(Fixture, "require_types")
|
||||||
REQUIRE_MESSAGE(bool(get<TableTypeVar>(hType)), "Expected table but got " << toString(hType));
|
REQUIRE_MESSAGE(bool(get<TableTypeVar>(hType)), "Expected table but got " << toString(hType));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "require_a_variadic_function")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "require_a_variadic_function")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
local T = {}
|
local T = {}
|
||||||
|
@ -121,7 +121,7 @@ TEST_CASE_FIXTURE(Fixture, "type_error_of_unknown_qualified_type")
|
||||||
REQUIRE_EQ(result.errors[0], (TypeError{Location{{1, 17}, {1, 40}}, UnknownSymbol{"SomeModule.DoesNotExist"}}));
|
REQUIRE_EQ(result.errors[0], (TypeError{Location{{1, 17}, {1, 40}}, UnknownSymbol{"SomeModule.DoesNotExist"}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "require_module_that_does_not_export")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "require_module_that_does_not_export")
|
||||||
{
|
{
|
||||||
const std::string sourceA = R"(
|
const std::string sourceA = R"(
|
||||||
)";
|
)";
|
||||||
|
@ -148,7 +148,7 @@ TEST_CASE_FIXTURE(Fixture, "require_module_that_does_not_export")
|
||||||
CHECK_EQ("*unknown*", toString(hootyType));
|
CHECK_EQ("*unknown*", toString(hootyType));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "warn_if_you_try_to_require_a_non_modulescript")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "warn_if_you_try_to_require_a_non_modulescript")
|
||||||
{
|
{
|
||||||
fileResolver.source["Modules/A"] = "";
|
fileResolver.source["Modules/A"] = "";
|
||||||
fileResolver.sourceTypes["Modules/A"] = SourceCode::Local;
|
fileResolver.sourceTypes["Modules/A"] = SourceCode::Local;
|
||||||
|
@ -164,7 +164,7 @@ TEST_CASE_FIXTURE(Fixture, "warn_if_you_try_to_require_a_non_modulescript")
|
||||||
CHECK(get<IllegalRequire>(result.errors[0]));
|
CHECK(get<IllegalRequire>(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "general_require_call_expression")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "general_require_call_expression")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -183,7 +183,7 @@ a = tbl.abc.def
|
||||||
CHECK_EQ("Type 'number' could not be converted into 'string'", toString(result.errors[0]));
|
CHECK_EQ("Type 'number' could not be converted into 'string'", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "general_require_type_mismatch")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "general_require_type_mismatch")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
return { def = 4 }
|
return { def = 4 }
|
||||||
|
@ -219,7 +219,7 @@ return m
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "custom_require_global")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "custom_require_global")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
|
@ -231,7 +231,7 @@ local crash = require(game.A)
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "require_failed_module")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "require_failed_module")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
return unfortunately()
|
return unfortunately()
|
||||||
|
@ -267,7 +267,7 @@ function x:Destroy(): () end
|
||||||
LUAU_REQUIRE_ERRORS(result);
|
LUAU_REQUIRE_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "do_not_modify_imported_types_2")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "do_not_modify_imported_types_2")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
export type Type = { x: { a: number } }
|
export type Type = { x: { a: number } }
|
||||||
|
@ -285,7 +285,7 @@ type Rename = typeof(x.x)
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "do_not_modify_imported_types_3")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "do_not_modify_imported_types_3")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
local y = setmetatable({}, {})
|
local y = setmetatable({}, {})
|
||||||
|
@ -304,7 +304,7 @@ type Rename = typeof(x.x)
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "module_type_conflict")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "module_type_conflict")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
export type T = { x: number }
|
export type T = { x: number }
|
||||||
|
@ -338,7 +338,7 @@ caused by:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "module_type_conflict_instantiated")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "module_type_conflict_instantiated")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
export type Wrap<T> = { x: T }
|
export type Wrap<T> = { x: T }
|
||||||
|
|
|
@ -142,7 +142,7 @@ TEST_CASE_FIXTURE(Fixture, "inferring_hundreds_of_self_calls_should_not_suffocat
|
||||||
CHECK_GE(50, module->internalTypes.typeVars.size());
|
CHECK_GE(50, module->internalTypes.typeVars.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "object_constructor_can_refer_to_method_of_self")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "object_constructor_can_refer_to_method_of_self")
|
||||||
{
|
{
|
||||||
// CLI-30902
|
// CLI-30902
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
|
@ -243,7 +243,7 @@ TEST_CASE_FIXTURE(Fixture, "inferred_methods_of_free_tables_have_the_same_level_
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_oop")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_oop")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
|
|
@ -77,7 +77,7 @@ TEST_CASE_FIXTURE(Fixture, "and_or_ternary")
|
||||||
CHECK_EQ(toString(*requireType("s")), "number | string");
|
CHECK_EQ(toString(*requireType("s")), "number | string");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "primitive_arith_no_metatable")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "primitive_arith_no_metatable")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
function add(a: number, b: string)
|
function add(a: number, b: string)
|
||||||
|
@ -140,7 +140,7 @@ TEST_CASE_FIXTURE(Fixture, "some_primitive_binary_ops")
|
||||||
CHECK_EQ("number", toString(requireType("c")));
|
CHECK_EQ("number", toString(requireType("c")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "typecheck_overloaded_multiply_that_is_an_intersection")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_overloaded_multiply_that_is_an_intersection")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -174,7 +174,7 @@ TEST_CASE_FIXTURE(Fixture, "typecheck_overloaded_multiply_that_is_an_intersectio
|
||||||
CHECK_EQ("Vec3", toString(requireType("e")));
|
CHECK_EQ("Vec3", toString(requireType("e")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "typecheck_overloaded_multiply_that_is_an_intersection_on_rhs")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_overloaded_multiply_that_is_an_intersection_on_rhs")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -245,7 +245,7 @@ TEST_CASE_FIXTURE(Fixture, "cannot_indirectly_compare_types_that_do_not_have_a_m
|
||||||
REQUIRE_EQ(gen->message, "Type a cannot be compared with < because it has no metatable");
|
REQUIRE_EQ(gen->message, "Type a cannot be compared with < because it has no metatable");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "cannot_indirectly_compare_types_that_do_not_offer_overloaded_ordering_operators")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "cannot_indirectly_compare_types_that_do_not_offer_overloaded_ordering_operators")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local M = {}
|
local M = {}
|
||||||
|
@ -266,7 +266,7 @@ TEST_CASE_FIXTURE(Fixture, "cannot_indirectly_compare_types_that_do_not_offer_ov
|
||||||
REQUIRE_EQ(gen->message, "Table M does not offer metamethod __lt");
|
REQUIRE_EQ(gen->message, "Table M does not offer metamethod __lt");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "cannot_compare_tables_that_do_not_have_the_same_metatable")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "cannot_compare_tables_that_do_not_have_the_same_metatable")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -289,7 +289,7 @@ TEST_CASE_FIXTURE(Fixture, "cannot_compare_tables_that_do_not_have_the_same_meta
|
||||||
REQUIRE_EQ((Location{{11, 18}, {11, 23}}), result.errors[1].location);
|
REQUIRE_EQ((Location{{11, 18}, {11, 23}}), result.errors[1].location);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "produce_the_correct_error_message_when_comparing_a_table_with_a_metatable_with_one_that_does_not")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "produce_the_correct_error_message_when_comparing_a_table_with_a_metatable_with_one_that_does_not")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -361,7 +361,7 @@ TEST_CASE_FIXTURE(Fixture, "compound_assign_mismatch_result")
|
||||||
CHECK_EQ(result.errors[1], (TypeError{Location{{2, 8}, {2, 15}}, TypeMismatch{typeChecker.stringType, typeChecker.numberType}}));
|
CHECK_EQ(result.errors[1], (TypeError{Location{{2, 8}, {2, 15}}, TypeMismatch{typeChecker.stringType, typeChecker.numberType}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "compound_assign_metatable")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "compound_assign_metatable")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -381,7 +381,7 @@ TEST_CASE_FIXTURE(Fixture, "compound_assign_metatable")
|
||||||
CHECK_EQ(0, result.errors.size());
|
CHECK_EQ(0, result.errors.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "compound_assign_mismatch_metatable")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "compound_assign_mismatch_metatable")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -428,7 +428,7 @@ local x = false
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "typecheck_unary_minus")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_unary_minus")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -461,7 +461,7 @@ TEST_CASE_FIXTURE(Fixture, "typecheck_unary_minus")
|
||||||
REQUIRE_EQ(gen->message, "Unary operator '-' not supported by type 'bar'");
|
REQUIRE_EQ(gen->message, "Unary operator '-' not supported by type 'bar'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "unary_not_is_boolean")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "unary_not_is_boolean")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local b = not "string"
|
local b = not "string"
|
||||||
|
@ -473,7 +473,7 @@ TEST_CASE_FIXTURE(Fixture, "unary_not_is_boolean")
|
||||||
REQUIRE_EQ("boolean", toString(requireType("c")));
|
REQUIRE_EQ("boolean", toString(requireType("c")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "disallow_string_and_types_without_metatables_from_arithmetic_binary_ops")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "disallow_string_and_types_without_metatables_from_arithmetic_binary_ops")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -573,7 +573,7 @@ TEST_CASE_FIXTURE(Fixture, "strict_binary_op_where_lhs_unknown")
|
||||||
CHECK_EQ("Unknown type used in + operation; consider adding a type annotation to 'a'", toString(result.errors[0]));
|
CHECK_EQ("Unknown type used in + operation; consider adding a type annotation to 'a'", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "and_binexps_dont_unify")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "and_binexps_dont_unify")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -628,7 +628,7 @@ TEST_CASE_FIXTURE(Fixture, "cli_38355_recursive_union")
|
||||||
CHECK_EQ("Type contains a self-recursive construct that cannot be resolved", toString(result.errors[0]));
|
CHECK_EQ("Type contains a self-recursive construct that cannot be resolved", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "UnknownGlobalCompoundAssign")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "UnknownGlobalCompoundAssign")
|
||||||
{
|
{
|
||||||
// In non-strict mode, global definition is still allowed
|
// In non-strict mode, global definition is still allowed
|
||||||
{
|
{
|
||||||
|
@ -755,8 +755,6 @@ TEST_CASE_FIXTURE(Fixture, "refine_and_or")
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "infer_any_in_all_modes_when_lhs_is_unknown")
|
TEST_CASE_FIXTURE(Fixture, "infer_any_in_all_modes_when_lhs_is_unknown")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff{"LuauDecoupleOperatorInferenceFromUnifiedTypeInference", true};
|
|
||||||
|
|
||||||
CheckResult result = check(Mode::Strict, R"(
|
CheckResult result = check(Mode::Strict, R"(
|
||||||
local function f(x, y)
|
local function f(x, y)
|
||||||
return x + y
|
return x + y
|
||||||
|
@ -779,4 +777,47 @@ TEST_CASE_FIXTURE(Fixture, "infer_any_in_all_modes_when_lhs_is_unknown")
|
||||||
// the case right now, though.
|
// the case right now, though.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE_FIXTURE(BuiltinsFixture, "equality_operations_succeed_if_any_union_branch_succeeds")
|
||||||
|
{
|
||||||
|
ScopedFastFlag sff("LuauSuccessTypingForEqualityOperations", true);
|
||||||
|
|
||||||
|
CheckResult result = check(R"(
|
||||||
|
local mm = {}
|
||||||
|
type Foo = typeof(setmetatable({}, mm))
|
||||||
|
local x: Foo
|
||||||
|
local y: Foo?
|
||||||
|
|
||||||
|
local v1 = x == y
|
||||||
|
local v2 = y == x
|
||||||
|
local v3 = x ~= y
|
||||||
|
local v4 = y ~= x
|
||||||
|
)");
|
||||||
|
|
||||||
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
|
|
||||||
|
CheckResult result2 = check(R"(
|
||||||
|
local mm1 = {
|
||||||
|
x = "foo",
|
||||||
|
}
|
||||||
|
|
||||||
|
local mm2 = {
|
||||||
|
y = "bar",
|
||||||
|
}
|
||||||
|
|
||||||
|
type Foo = typeof(setmetatable({}, mm1))
|
||||||
|
type Bar = typeof(setmetatable({}, mm2))
|
||||||
|
|
||||||
|
local x1: Foo
|
||||||
|
local x2: Foo?
|
||||||
|
local y1: Bar
|
||||||
|
local y2: Bar?
|
||||||
|
|
||||||
|
local v1 = x1 == y1
|
||||||
|
local v2 = x2 == y2
|
||||||
|
)");
|
||||||
|
|
||||||
|
LUAU_REQUIRE_ERROR_COUNT(1, result2);
|
||||||
|
CHECK(toString(result2.errors[0]) == "Types Foo and Bar cannot be compared with == because they do not have the same metatable");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_SUITE_END();
|
TEST_SUITE_END();
|
||||||
|
|
|
@ -53,7 +53,7 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_inference_incomplete")
|
||||||
CHECK_EQ(expected, decorateWithTypes(code));
|
CHECK_EQ(expected, decorateWithTypes(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "xpcall_returns_what_f_returns")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "xpcall_returns_what_f_returns")
|
||||||
{
|
{
|
||||||
const std::string code = R"(
|
const std::string code = R"(
|
||||||
local a, b, c = xpcall(function() return 1, "foo" end, function() return "foo", 1 end)
|
local a, b, c = xpcall(function() return 1, "foo" end, function() return "foo", 1 end)
|
||||||
|
@ -105,7 +105,7 @@ TEST_CASE_FIXTURE(Fixture, "it_should_be_agnostic_of_actual_size")
|
||||||
|
|
||||||
// Ideally setmetatable's second argument would be an optional free table.
|
// Ideally setmetatable's second argument would be an optional free table.
|
||||||
// For now, infer it as just a free table.
|
// For now, infer it as just a free table.
|
||||||
TEST_CASE_FIXTURE(Fixture, "setmetatable_constrains_free_type_into_free_table")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "setmetatable_constrains_free_type_into_free_table")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a = {}
|
local a = {}
|
||||||
|
@ -146,7 +146,7 @@ TEST_CASE_FIXTURE(Fixture, "while_body_are_also_refined")
|
||||||
// Originally from TypeInfer.test.cpp.
|
// Originally from TypeInfer.test.cpp.
|
||||||
// I dont think type checking the metamethod at every site of == is the correct thing to do.
|
// I dont think type checking the metamethod at every site of == is the correct thing to do.
|
||||||
// We should be type checking the metamethod at the call site of setmetatable.
|
// We should be type checking the metamethod at the call site of setmetatable.
|
||||||
TEST_CASE_FIXTURE(Fixture, "error_on_eq_metamethod_returning_a_type_other_than_boolean")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "error_on_eq_metamethod_returning_a_type_other_than_boolean")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local tab = {a = 1}
|
local tab = {a = 1}
|
||||||
|
@ -428,7 +428,7 @@ TEST_CASE_FIXTURE(Fixture, "pcall_returns_at_least_two_value_but_function_return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Belongs in TypeInfer.builtins.test.cpp.
|
// Belongs in TypeInfer.builtins.test.cpp.
|
||||||
TEST_CASE_FIXTURE(Fixture, "choose_the_right_overload_for_pcall")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "choose_the_right_overload_for_pcall")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function f(): number
|
local function f(): number
|
||||||
|
@ -449,7 +449,7 @@ TEST_CASE_FIXTURE(Fixture, "choose_the_right_overload_for_pcall")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Belongs in TypeInfer.builtins.test.cpp.
|
// Belongs in TypeInfer.builtins.test.cpp.
|
||||||
TEST_CASE_FIXTURE(Fixture, "function_returns_many_things_but_first_of_it_is_forgotten")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "function_returns_many_things_but_first_of_it_is_forgotten")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function f(): (number, string, boolean)
|
local function f(): (number, string, boolean)
|
||||||
|
|
|
@ -240,7 +240,7 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_in_if_condition_position")
|
||||||
CHECK_EQ("number", toString(requireTypeAtPosition({3, 26})));
|
CHECK_EQ("number", toString(requireTypeAtPosition({3, 26})));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "typeguard_in_assert_position")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "typeguard_in_assert_position")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a
|
local a
|
||||||
|
@ -300,7 +300,7 @@ TEST_CASE_FIXTURE(Fixture, "call_a_more_specific_function_using_typeguard")
|
||||||
CHECK_EQ("Type 'string' could not be converted into 'number'", toString(result.errors[0]));
|
CHECK_EQ("Type 'string' could not be converted into 'number'", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "impossible_type_narrow_is_not_an_error")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "impossible_type_narrow_is_not_an_error")
|
||||||
{
|
{
|
||||||
// This unit test serves as a reminder to not implement this warning until Luau is intelligent enough.
|
// This unit test serves as a reminder to not implement this warning until Luau is intelligent enough.
|
||||||
// For instance, getting a value out of the indexer and checking whether the value exists is not an error.
|
// For instance, getting a value out of the indexer and checking whether the value exists is not an error.
|
||||||
|
@ -333,7 +333,7 @@ TEST_CASE_FIXTURE(Fixture, "truthy_constraint_on_properties")
|
||||||
CHECK_EQ("number?", toString(requireType("bar")));
|
CHECK_EQ("number?", toString(requireType("bar")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "index_on_a_refined_property")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "index_on_a_refined_property")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t: {x: {y: string}?} = {x = {y = "hello!"}}
|
local t: {x: {y: string}?} = {x = {y = "hello!"}}
|
||||||
|
@ -346,7 +346,7 @@ TEST_CASE_FIXTURE(Fixture, "index_on_a_refined_property")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "assert_non_binary_expressions_actually_resolve_constraints")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "assert_non_binary_expressions_actually_resolve_constraints")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local foo: string? = "hello"
|
local foo: string? = "hello"
|
||||||
|
@ -730,7 +730,7 @@ TEST_CASE_FIXTURE(Fixture, "type_guard_can_filter_for_overloaded_function")
|
||||||
CHECK_EQ("nil", toString(requireTypeAtPosition({6, 28})));
|
CHECK_EQ("nil", toString(requireTypeAtPosition({6, 28})));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "type_guard_warns_on_no_overlapping_types_only_when_sense_is_true")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "type_guard_warns_on_no_overlapping_types_only_when_sense_is_true")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function f(t: {x: number})
|
local function f(t: {x: number})
|
||||||
|
@ -846,7 +846,7 @@ TEST_CASE_FIXTURE(Fixture, "not_t_or_some_prop_of_t")
|
||||||
CHECK_EQ("{| x: boolean |}?", toString(requireTypeAtPosition({3, 28})));
|
CHECK_EQ("{| x: boolean |}?", toString(requireTypeAtPosition({3, 28})));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "assert_a_to_be_truthy_then_assert_a_to_be_number")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "assert_a_to_be_truthy_then_assert_a_to_be_number")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a: (number | string)?
|
local a: (number | string)?
|
||||||
|
@ -862,7 +862,7 @@ TEST_CASE_FIXTURE(Fixture, "assert_a_to_be_truthy_then_assert_a_to_be_number")
|
||||||
CHECK_EQ("number", toString(requireTypeAtPosition({5, 18})));
|
CHECK_EQ("number", toString(requireTypeAtPosition({5, 18})));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "merge_should_be_fully_agnostic_of_hashmap_ordering")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "merge_should_be_fully_agnostic_of_hashmap_ordering")
|
||||||
{
|
{
|
||||||
// This bug came up because there was a mistake in Luau::merge where zipping on two maps would produce the wrong merged result.
|
// This bug came up because there was a mistake in Luau::merge where zipping on two maps would produce the wrong merged result.
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
|
@ -899,7 +899,7 @@ TEST_CASE_FIXTURE(Fixture, "refine_the_correct_types_opposite_of_when_a_is_not_n
|
||||||
CHECK_EQ("number | string", toString(requireTypeAtPosition({5, 28})));
|
CHECK_EQ("number | string", toString(requireTypeAtPosition({5, 28})));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "is_truthy_constraint_ifelse_expression")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "is_truthy_constraint_ifelse_expression")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
function f(v:string?)
|
function f(v:string?)
|
||||||
|
@ -913,7 +913,7 @@ TEST_CASE_FIXTURE(Fixture, "is_truthy_constraint_ifelse_expression")
|
||||||
CHECK_EQ("nil", toString(requireTypeAtPosition({2, 45})));
|
CHECK_EQ("nil", toString(requireTypeAtPosition({2, 45})));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "invert_is_truthy_constraint_ifelse_expression")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "invert_is_truthy_constraint_ifelse_expression")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
function f(v:string?)
|
function f(v:string?)
|
||||||
|
@ -945,7 +945,7 @@ TEST_CASE_FIXTURE(Fixture, "type_comparison_ifelse_expression")
|
||||||
CHECK_EQ("any", toString(requireTypeAtPosition({6, 66})));
|
CHECK_EQ("any", toString(requireTypeAtPosition({6, 66})));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "correctly_lookup_a_shadowed_local_that_which_was_previously_refined")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "correctly_lookup_a_shadowed_local_that_which_was_previously_refined")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local foo: string? = "hi"
|
local foo: string? = "hi"
|
||||||
|
|
|
@ -415,7 +415,7 @@ TEST_CASE_FIXTURE(Fixture, "widening_happens_almost_everywhere_except_for_tables
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_insert_with_a_singleton_argument")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_with_a_singleton_argument")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff[]{
|
ScopedFastFlag sff[]{
|
||||||
{"LuauWidenIfSupertypeIsFree2", true},
|
{"LuauWidenIfSupertypeIsFree2", true},
|
||||||
|
|
|
@ -201,7 +201,7 @@ TEST_CASE_FIXTURE(Fixture, "used_dot_instead_of_colon")
|
||||||
REQUIRE(it != result.errors.end());
|
REQUIRE(it != result.errors.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "used_colon_correctly")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "used_colon_correctly")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
|
@ -883,7 +883,7 @@ TEST_CASE_FIXTURE(Fixture, "assigning_to_an_unsealed_table_with_string_literal_s
|
||||||
CHECK_EQ(*typeChecker.stringType, *propertyA);
|
CHECK_EQ(*typeChecker.stringType, *propertyA);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "oop_indexer_works")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "oop_indexer_works")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local clazz = {}
|
local clazz = {}
|
||||||
|
@ -906,7 +906,7 @@ TEST_CASE_FIXTURE(Fixture, "oop_indexer_works")
|
||||||
CHECK_EQ(*typeChecker.stringType, *requireType("words"));
|
CHECK_EQ(*typeChecker.stringType, *requireType("words"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "indexer_table")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "indexer_table")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local clazz = {a="hello"}
|
local clazz = {a="hello"}
|
||||||
|
@ -919,7 +919,7 @@ TEST_CASE_FIXTURE(Fixture, "indexer_table")
|
||||||
CHECK_EQ(*typeChecker.stringType, *requireType("b"));
|
CHECK_EQ(*typeChecker.stringType, *requireType("b"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "indexer_fn")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "indexer_fn")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local instanace = setmetatable({}, {__index=function() return 10 end})
|
local instanace = setmetatable({}, {__index=function() return 10 end})
|
||||||
|
@ -930,7 +930,7 @@ TEST_CASE_FIXTURE(Fixture, "indexer_fn")
|
||||||
CHECK_EQ(*typeChecker.numberType, *requireType("b"));
|
CHECK_EQ(*typeChecker.numberType, *requireType("b"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "meta_add")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "meta_add")
|
||||||
{
|
{
|
||||||
// Note: meta_add_inferred and this unit test are currently the same exact thing.
|
// Note: meta_add_inferred and this unit test are currently the same exact thing.
|
||||||
// We'll want to change this one in particular when we add real syntax for metatables.
|
// We'll want to change this one in particular when we add real syntax for metatables.
|
||||||
|
@ -947,7 +947,7 @@ TEST_CASE_FIXTURE(Fixture, "meta_add")
|
||||||
CHECK_EQ(follow(requireType("a")), follow(requireType("c")));
|
CHECK_EQ(follow(requireType("a")), follow(requireType("c")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "meta_add_inferred")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "meta_add_inferred")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a = {}
|
local a = {}
|
||||||
|
@ -960,7 +960,7 @@ TEST_CASE_FIXTURE(Fixture, "meta_add_inferred")
|
||||||
CHECK_EQ(*requireType("a"), *requireType("c"));
|
CHECK_EQ(*requireType("a"), *requireType("c"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "meta_add_both_ways")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "meta_add_both_ways")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
type VectorMt = { __add: (Vector, number) -> Vector }
|
type VectorMt = { __add: (Vector, number) -> Vector }
|
||||||
|
@ -980,7 +980,7 @@ TEST_CASE_FIXTURE(Fixture, "meta_add_both_ways")
|
||||||
|
|
||||||
// This test exposed a bug where we let go of the "seen" stack while unifying table types
|
// This test exposed a bug where we let go of the "seen" stack while unifying table types
|
||||||
// As a result, type inference crashed with a stack overflow.
|
// As a result, type inference crashed with a stack overflow.
|
||||||
TEST_CASE_FIXTURE(Fixture, "unification_of_unions_in_a_self_referential_type")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "unification_of_unions_in_a_self_referential_type")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
type A = {}
|
type A = {}
|
||||||
|
@ -1009,7 +1009,7 @@ TEST_CASE_FIXTURE(Fixture, "unification_of_unions_in_a_self_referential_type")
|
||||||
CHECK_EQ(bmtv->metatable, requireType("bmt"));
|
CHECK_EQ(bmtv->metatable, requireType("bmt"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "oop_polymorphic")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "oop_polymorphic")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local animal = {}
|
local animal = {}
|
||||||
|
@ -1060,7 +1060,7 @@ TEST_CASE_FIXTURE(Fixture, "user_defined_table_types_are_named")
|
||||||
CHECK_EQ("Vector3", toString(requireType("v")));
|
CHECK_EQ("Vector3", toString(requireType("v")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "result_is_always_any_if_lhs_is_any")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "result_is_always_any_if_lhs_is_any")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
type Vector3MT = {
|
type Vector3MT = {
|
||||||
|
@ -1133,7 +1133,7 @@ TEST_CASE_FIXTURE(Fixture, "nice_error_when_trying_to_fetch_property_of_boolean"
|
||||||
CHECK_EQ("Type 'boolean' does not have key 'some_prop'", toString(result.errors[0]));
|
CHECK_EQ("Type 'boolean' does not have key 'some_prop'", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "defining_a_method_for_a_builtin_sealed_table_must_fail")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "defining_a_method_for_a_builtin_sealed_table_must_fail")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
function string.m() end
|
function string.m() end
|
||||||
|
@ -1142,7 +1142,7 @@ TEST_CASE_FIXTURE(Fixture, "defining_a_method_for_a_builtin_sealed_table_must_fa
|
||||||
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "defining_a_self_method_for_a_builtin_sealed_table_must_fail")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "defining_a_self_method_for_a_builtin_sealed_table_must_fail")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
function string:m() end
|
function string:m() end
|
||||||
|
@ -1261,7 +1261,7 @@ TEST_CASE_FIXTURE(Fixture, "found_like_key_in_table_function_call")
|
||||||
CHECK_EQ(toString(te), "Key 'fOo' not found in table 't'. Did you mean 'Foo'?");
|
CHECK_EQ(toString(te), "Key 'fOo' not found in table 't'. Did you mean 'Foo'?");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "found_like_key_in_table_property_access")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "found_like_key_in_table_property_access")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = {X = 1}
|
local t = {X = 1}
|
||||||
|
@ -1286,7 +1286,7 @@ TEST_CASE_FIXTURE(Fixture, "found_like_key_in_table_property_access")
|
||||||
CHECK_EQ(toString(te), "Key 'x' not found in table 't'. Did you mean 'X'?");
|
CHECK_EQ(toString(te), "Key 'x' not found in table 't'. Did you mean 'X'?");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "found_multiple_like_keys")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "found_multiple_like_keys")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = {Foo = 1, foO = 2}
|
local t = {Foo = 1, foO = 2}
|
||||||
|
@ -1312,7 +1312,7 @@ TEST_CASE_FIXTURE(Fixture, "found_multiple_like_keys")
|
||||||
CHECK_EQ(toString(te), "Key 'foo' not found in table 't'. Did you mean one of 'Foo', 'foO'?");
|
CHECK_EQ(toString(te), "Key 'foo' not found in table 't'. Did you mean one of 'Foo', 'foO'?");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "dont_suggest_exact_match_keys")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "dont_suggest_exact_match_keys")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = {}
|
local t = {}
|
||||||
|
@ -1339,7 +1339,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_suggest_exact_match_keys")
|
||||||
CHECK_EQ(toString(te), "Key 'Foo' not found in table 't'. Did you mean 'foO'?");
|
CHECK_EQ(toString(te), "Key 'Foo' not found in table 't'. Did you mean 'foO'?");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "getmetatable_returns_pointer_to_metatable")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "getmetatable_returns_pointer_to_metatable")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = {x = 1}
|
local t = {x = 1}
|
||||||
|
@ -1352,7 +1352,7 @@ TEST_CASE_FIXTURE(Fixture, "getmetatable_returns_pointer_to_metatable")
|
||||||
CHECK_EQ(*requireType("mt"), *requireType("returnedMT"));
|
CHECK_EQ(*requireType("mt"), *requireType("returnedMT"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "metatable_mismatch_should_fail")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "metatable_mismatch_should_fail")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t1 = {x = 1}
|
local t1 = {x = 1}
|
||||||
|
@ -1374,7 +1374,7 @@ TEST_CASE_FIXTURE(Fixture, "metatable_mismatch_should_fail")
|
||||||
CHECK_EQ(*tm->givenType, *requireType("t2"));
|
CHECK_EQ(*tm->givenType, *requireType("t2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "property_lookup_through_tabletypevar_metatable")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "property_lookup_through_tabletypevar_metatable")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = {x = 1}
|
local t = {x = 1}
|
||||||
|
@ -1393,7 +1393,7 @@ TEST_CASE_FIXTURE(Fixture, "property_lookup_through_tabletypevar_metatable")
|
||||||
CHECK_EQ(up->key, "z");
|
CHECK_EQ(up->key, "z");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "missing_metatable_for_sealed_tables_do_not_get_inferred")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "missing_metatable_for_sealed_tables_do_not_get_inferred")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = {x = 1}
|
local t = {x = 1}
|
||||||
|
@ -1742,7 +1742,7 @@ TEST_CASE_FIXTURE(Fixture, "hide_table_error_properties")
|
||||||
CHECK_EQ("Cannot add property 'b' to table '{| x: number |}'", toString(result.errors[1]));
|
CHECK_EQ("Cannot add property 'b' to table '{| x: number |}'", toString(result.errors[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "builtin_table_names")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "builtin_table_names")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
os.h = 2
|
os.h = 2
|
||||||
|
@ -1755,7 +1755,7 @@ TEST_CASE_FIXTURE(Fixture, "builtin_table_names")
|
||||||
CHECK_EQ("Cannot add property 'k' to table 'string'", toString(result.errors[1]));
|
CHECK_EQ("Cannot add property 'k' to table 'string'", toString(result.errors[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "persistent_sealed_table_is_immutable")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "persistent_sealed_table_is_immutable")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
|
@ -1858,7 +1858,7 @@ local foos: {Foo} = {
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "quantifying_a_bound_var_works")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "quantifying_a_bound_var_works")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local clazz = {}
|
local clazz = {}
|
||||||
|
@ -1983,7 +1983,7 @@ TEST_CASE_FIXTURE(Fixture, "invariant_table_properties_means_instantiating_table
|
||||||
LUAU_REQUIRE_ERRORS(result);
|
LUAU_REQUIRE_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_insert_should_cope_with_optional_properties_in_nonstrict")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_should_cope_with_optional_properties_in_nonstrict")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
|
@ -1996,7 +1996,7 @@ TEST_CASE_FIXTURE(Fixture, "table_insert_should_cope_with_optional_properties_in
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_insert_should_cope_with_optional_properties_in_strict")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_should_cope_with_optional_properties_in_strict")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff{"LuauTableSubtypingVariance2", true};
|
ScopedFastFlag sff{"LuauTableSubtypingVariance2", true};
|
||||||
|
|
||||||
|
@ -2052,7 +2052,7 @@ caused by:
|
||||||
Property 'y' is not compatible. Type 'number' could not be converted into 'string')");
|
Property 'y' is not compatible. Type 'number' could not be converted into 'string')");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "error_detailed_metatable_prop")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "error_detailed_metatable_prop")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff[]{
|
ScopedFastFlag sff[]{
|
||||||
{"LuauTableSubtypingVariance2", true},
|
{"LuauTableSubtypingVariance2", true},
|
||||||
|
@ -2183,7 +2183,7 @@ a.p = { x = 9 }
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "recursive_metatable_type_call")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "recursive_metatable_type_call")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff[]{
|
ScopedFastFlag sff[]{
|
||||||
{"LuauUnsealedTableLiteral", true},
|
{"LuauUnsealedTableLiteral", true},
|
||||||
|
@ -2277,7 +2277,7 @@ local y = #x
|
||||||
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "dont_hang_when_trying_to_look_up_in_cyclic_metatable_index")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "dont_hang_when_trying_to_look_up_in_cyclic_metatable_index")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff{"LuauTerminateCyclicMetatableIndexLookup", true};
|
ScopedFastFlag sff{"LuauTerminateCyclicMetatableIndexLookup", true};
|
||||||
|
|
||||||
|
@ -2296,7 +2296,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_hang_when_trying_to_look_up_in_cyclic_metatable
|
||||||
CHECK_EQ("Type 't' does not have key 'p'", toString(result.errors[0]));
|
CHECK_EQ("Type 't' does not have key 'p'", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "give_up_after_one_metatable_index_look_up")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "give_up_after_one_metatable_index_look_up")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local data = { x = 5 }
|
local data = { x = 5 }
|
||||||
|
@ -2478,7 +2478,7 @@ TEST_CASE_FIXTURE(Fixture, "free_rhs_table_can_also_be_bound")
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_unifies_into_map")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_unifies_into_map")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local Instance: any
|
local Instance: any
|
||||||
|
@ -2564,7 +2564,7 @@ TEST_CASE_FIXTURE(Fixture, "generalize_table_argument")
|
||||||
* the generalization process), then it loses the knowledge that its metatable will have an :incr()
|
* the generalization process), then it loses the knowledge that its metatable will have an :incr()
|
||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
TEST_CASE_FIXTURE(Fixture, "dont_quantify_table_that_belongs_to_outer_scope")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "dont_quantify_table_that_belongs_to_outer_scope")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local Counter = {}
|
local Counter = {}
|
||||||
|
@ -2606,7 +2606,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_quantify_table_that_belongs_to_outer_scope")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: CLI-39624
|
// TODO: CLI-39624
|
||||||
TEST_CASE_FIXTURE(Fixture, "instantiate_tables_at_scope_level")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "instantiate_tables_at_scope_level")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
@ -2690,7 +2690,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_crash_when_setmetatable_does_not_produce_a_meta
|
||||||
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
LUAU_REQUIRE_ERROR_COUNT(1, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "instantiate_table_cloning")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "instantiate_table_cloning")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!nonstrict
|
--!nonstrict
|
||||||
|
@ -2711,7 +2711,7 @@ type t0<t32> = any
|
||||||
CHECK(ttv->instantiatedTypeParams.empty());
|
CHECK(ttv->instantiatedTypeParams.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "instantiate_table_cloning_2")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "instantiate_table_cloning_2")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff{"LuauOnlyMutateInstantiatedTables", true};
|
ScopedFastFlag sff{"LuauOnlyMutateInstantiatedTables", true};
|
||||||
|
|
||||||
|
@ -2767,7 +2767,7 @@ local baz = foo[bar]
|
||||||
CHECK_EQ(result.errors[0].location, Location{Position{3, 16}, Position{3, 19}});
|
CHECK_EQ(result.errors[0].location, Location{Position{3, 16}, Position{3, 19}});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_simple_call")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_simple_call")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a = setmetatable({ x = 2 }, {
|
local a = setmetatable({ x = 2 }, {
|
||||||
|
@ -2783,7 +2783,7 @@ local c = a(2) -- too many arguments
|
||||||
CHECK_EQ("Argument count mismatch. Function expects 1 argument, but 2 are specified", toString(result.errors[0]));
|
CHECK_EQ("Argument count mismatch. Function expects 1 argument, but 2 are specified", toString(result.errors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "access_index_metamethod_that_returns_variadic")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "access_index_metamethod_that_returns_variadic")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
type Foo = {x: string}
|
type Foo = {x: string}
|
||||||
|
@ -2878,7 +2878,7 @@ TEST_CASE_FIXTURE(Fixture, "pairs_parameters_are_not_unsealed_tables")
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_function_check_use_after_free")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_function_check_use_after_free")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local t = {}
|
local t = {}
|
||||||
|
@ -2916,7 +2916,7 @@ TEST_CASE_FIXTURE(Fixture, "inferred_properties_of_a_table_should_start_with_the
|
||||||
}
|
}
|
||||||
|
|
||||||
// The real bug here was that we weren't always uncondionally typechecking a trailing return statement last.
|
// The real bug here was that we weren't always uncondionally typechecking a trailing return statement last.
|
||||||
TEST_CASE_FIXTURE(Fixture, "dont_leak_free_table_props")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "dont_leak_free_table_props")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function a(state)
|
local function a(state)
|
||||||
|
|
|
@ -161,7 +161,7 @@ TEST_CASE_FIXTURE(Fixture, "unify_nearly_identical_recursive_types")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "warn_on_lowercase_parent_property")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "warn_on_lowercase_parent_property")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local M = require(script.parent.DoesNotMatter)
|
local M = require(script.parent.DoesNotMatter)
|
||||||
|
@ -175,7 +175,7 @@ TEST_CASE_FIXTURE(Fixture, "warn_on_lowercase_parent_property")
|
||||||
REQUIRE_EQ("parent", ed->symbol);
|
REQUIRE_EQ("parent", ed->symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "weird_case")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "weird_case")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function f() return 4 end
|
local function f() return 4 end
|
||||||
|
@ -419,7 +419,7 @@ TEST_CASE_FIXTURE(Fixture, "globals_everywhere")
|
||||||
CHECK_EQ("any", toString(requireType("bar")));
|
CHECK_EQ("any", toString(requireType("bar")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "correctly_scope_locals_do")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "correctly_scope_locals_do")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
do
|
do
|
||||||
|
@ -534,7 +534,7 @@ TEST_CASE_FIXTURE(Fixture, "tc_after_error_recovery_no_assert")
|
||||||
LUAU_REQUIRE_ERRORS(result);
|
LUAU_REQUIRE_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "tc_after_error_recovery_no_replacement_name_in_error")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "tc_after_error_recovery_no_replacement_name_in_error")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
|
@ -587,7 +587,7 @@ TEST_CASE_FIXTURE(Fixture, "tc_after_error_recovery_no_replacement_name_in_error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "index_expr_should_be_checked")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "index_expr_should_be_checked")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local foo: any
|
local foo: any
|
||||||
|
@ -768,7 +768,7 @@ b, c = {2, "s"}, {"b", 4}
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "infer_assignment_value_types_mutable_lval")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "infer_assignment_value_types_mutable_lval")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local a = {}
|
local a = {}
|
||||||
|
@ -836,7 +836,7 @@ local a: number? = if true then 1 else nil
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "tc_if_else_expressions_expected_type_3")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "tc_if_else_expressions_expected_type_3")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function times<T>(n: any, f: () -> T)
|
local function times<T>(n: any, f: () -> T)
|
||||||
|
@ -907,7 +907,7 @@ TEST_CASE_FIXTURE(Fixture, "fuzzer_found_this")
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "recursive_metatable_crash")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "recursive_metatable_crash")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
local function getIt()
|
local function getIt()
|
||||||
|
@ -1041,7 +1041,6 @@ TEST_CASE_FIXTURE(Fixture, "follow_on_new_types_in_substitution")
|
||||||
TEST_CASE_FIXTURE(Fixture, "do_not_bind_a_free_table_to_a_union_containing_that_table")
|
TEST_CASE_FIXTURE(Fixture, "do_not_bind_a_free_table_to_a_union_containing_that_table")
|
||||||
{
|
{
|
||||||
ScopedFastFlag flag[] = {
|
ScopedFastFlag flag[] = {
|
||||||
{"LuauStatFunctionSimplify4", true},
|
|
||||||
{"LuauLowerBoundsCalculation", true},
|
{"LuauLowerBoundsCalculation", true},
|
||||||
{"LuauDifferentOrderOfUnificationDoesntMatter2", true},
|
{"LuauDifferentOrderOfUnificationDoesntMatter2", true},
|
||||||
};
|
};
|
||||||
|
|
|
@ -196,7 +196,7 @@ TEST_CASE_FIXTURE(TryUnifyFixture, "variadics_should_use_reversed_properly")
|
||||||
CHECK_EQ(toString(tm->wantedType), "string");
|
CHECK_EQ(toString(tm->wantedType), "string");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(TryUnifyFixture, "cli_41095_concat_log_in_sealed_table_unification")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "cli_41095_concat_log_in_sealed_table_unification")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
--!strict
|
--!strict
|
||||||
|
|
|
@ -339,7 +339,7 @@ local c: Packed<string, number, boolean>
|
||||||
CHECK_EQ(toString(ttvC->instantiatedTypePackParams[0], {true}), "number, boolean");
|
CHECK_EQ(toString(ttvC->instantiatedTypePackParams[0], {true}), "number, boolean");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "type_alias_type_packs_import")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "type_alias_type_packs_import")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
export type Packed<T, U...> = { a: T, b: (U...) -> () }
|
export type Packed<T, U...> = { a: T, b: (U...) -> () }
|
||||||
|
@ -369,7 +369,7 @@ local d: { a: typeof(c) }
|
||||||
CHECK_EQ(toString(requireType("d")), "{| a: Packed<string, number, boolean> |}");
|
CHECK_EQ(toString(requireType("d")), "{| a: Packed<string, number, boolean> |}");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "type_pack_type_parameters")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "type_pack_type_parameters")
|
||||||
{
|
{
|
||||||
fileResolver.source["game/A"] = R"(
|
fileResolver.source["game/A"] = R"(
|
||||||
export type Packed<T, U...> = { a: T, b: (U...) -> () }
|
export type Packed<T, U...> = { a: T, b: (U...) -> () }
|
||||||
|
@ -784,7 +784,7 @@ local a: Y<...number>
|
||||||
LUAU_REQUIRE_ERRORS(result);
|
LUAU_REQUIRE_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "type_alias_default_export")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "type_alias_default_export")
|
||||||
{
|
{
|
||||||
fileResolver.source["Module/Types"] = R"(
|
fileResolver.source["Module/Types"] = R"(
|
||||||
export type A<T, U = string> = { a: T, b: U }
|
export type A<T, U = string> = { a: T, b: U }
|
||||||
|
|
|
@ -104,7 +104,7 @@ TEST_CASE_FIXTURE(Fixture, "optional_arguments_table2")
|
||||||
REQUIRE(!result.errors.empty());
|
REQUIRE(!result.errors.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "error_takes_optional_arguments")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "error_takes_optional_arguments")
|
||||||
{
|
{
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
error("message")
|
error("message")
|
||||||
|
@ -517,10 +517,8 @@ TEST_CASE_FIXTURE(Fixture, "dont_allow_cyclic_unions_to_be_inferred")
|
||||||
LUAU_REQUIRE_NO_ERRORS(result);
|
LUAU_REQUIRE_NO_ERRORS(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "table_union_write_indirect")
|
TEST_CASE_FIXTURE(BuiltinsFixture, "table_union_write_indirect")
|
||||||
{
|
{
|
||||||
ScopedFastFlag statFunctionSimplify{"LuauStatFunctionSimplify4", true};
|
|
||||||
|
|
||||||
CheckResult result = check(R"(
|
CheckResult result = check(R"(
|
||||||
type A = { x: number, y: (number) -> string } | { z: number, y: (number) -> string }
|
type A = { x: number, y: (number) -> string } | { z: number, y: (number) -> string }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue