diff --git a/tests/Conformance.test.cpp b/tests/Conformance.test.cpp index 1339fa0c..da41fc35 100644 --- a/tests/Conformance.test.cpp +++ b/tests/Conformance.test.cpp @@ -1,13 +1,13 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #include "lua.h" #include "lualib.h" #include "luacode.h" -#include "Luau/BuiltinDefinitions.h" -#include "Luau/ModuleResolver.h" -#include "Luau/TypeInfer.h" -#include "Luau/StringUtils.h" -#include "Luau/BytecodeBuilder.h" +#include "lluz/BuiltinDefinitions.h" +#include "lluz/ModuleResolver.h" +#include "lluz/TypeInfer.h" +#include "lluz/StringUtils.h" +#include "lluz/BytecodeBuilder.h" #include "doctest.h" #include "ScopedFlags.h" @@ -17,16 +17,6 @@ #include extern bool verbose; -extern int optimizationLevel; - -static lua_CompileOptions defaultOptions() -{ - lua_CompileOptions copts = {}; - copts.optimizationLevel = optimizationLevel; - copts.debugLevel = 1; - - return copts; -} static int lua_collectgarbage(lua_State* L) { @@ -62,8 +52,8 @@ static int lua_loadstring(lua_State* L) lua_setsafeenv(L, LUA_ENVIRONINDEX, false); size_t bytecodeSize = 0; - char* bytecode = luau_compile(s, l, nullptr, &bytecodeSize); - int result = luau_load(L, chunkname, bytecode, bytecodeSize, 0); + char* bytecode = lluz_compile(s, l, nullptr, &bytecodeSize); + int result = lluz_load(L, chunkname, bytecode, bytecodeSize, 0); free(bytecode); if (result == 0) @@ -111,11 +101,11 @@ static int lua_vector_index(lua_State* L) if (strcmp(name, "Dot") == 0) { - lua_pushcfunction(L, lua_vector_dot, "Dot"); + lua_pushcfunction(L, lua_vector_dot, XorStr("Dot")); return 1; } - luaL_error(L, "%s is not a valid member of vector", name); + luaL_error(L, XorStr("%s is not a valid member of vector"), name); } static int lua_vector_namecall(lua_State* L) @@ -126,7 +116,7 @@ static int lua_vector_namecall(lua_State* L) return lua_vector_dot(L); } - luaL_error(L, "%s is not a valid method of vector", luaL_checkstring(L, 1)); + luaL_error(L, XorStr("%s is not a valid method of vector"), luaL_checkstring(L, 1)); } int lua_silence(lua_State* L) @@ -137,7 +127,7 @@ int lua_silence(lua_State* L) using StateRef = std::unique_ptr; static StateRef runConformance(const char* name, void (*setup)(lua_State* L) = nullptr, void (*yield)(lua_State* L) = nullptr, - lua_State* initialLuaState = nullptr, lua_CompileOptions* options = nullptr) + lua_State* initialLuaState = nullptr, lua_CompileOptions* copts = nullptr) { std::string path = __FILE__; path.erase(path.find_last_of("\\/")); @@ -177,9 +167,9 @@ static StateRef runConformance(const char* name, void (*setup)(lua_State* L) = n lua_pop(L, 1); // In some configurations we have a larger C stack consumption which trips some conformance tests -#if defined(LUAU_ENABLE_ASAN) || defined(_NOOPT) || defined(_DEBUG) +#if defined(lluz_ENABLE_ASAN) || defined(_NOOPT) || defined(_DEBUG) lua_pushboolean(L, true); - lua_setglobal(L, "limitedstack"); + lua_setglobal(L, XorStr("limitedstack")); #endif // Extra test-specific setup @@ -195,16 +185,13 @@ static StateRef runConformance(const char* name, void (*setup)(lua_State* L) = n // Lua conformance tests treat _G synonymously with getfenv(); for now cater to them lua_pushvalue(L, LUA_GLOBALSINDEX); lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_setfield(L, -1, "_G"); + lua_setfield(L, -1, XorStr("_G")); std::string chunkname = "=" + std::string(name); - // note: luau_compile supports nullptr options, but we need to customize our defaults to improve test coverage - lua_CompileOptions opts = options ? *options : defaultOptions(); - size_t bytecodeSize = 0; - char* bytecode = luau_compile(source.data(), source.size(), &opts, &bytecodeSize); - int result = luau_load(L, chunkname.c_str(), bytecode, bytecodeSize, 0); + char* bytecode = lluz_compile(source.data(), source.size(), copts, &bytecodeSize); + int result = lluz_load(L, chunkname.c_str(), bytecode, bytecodeSize, 0); free(bytecode); int status = (result == 0) ? lua_resume(L, nullptr, 0) : LUA_ERRSYNTAX; @@ -221,7 +208,7 @@ static StateRef runConformance(const char* name, void (*setup)(lua_State* L) = n if (status == 0) { REQUIRE(lua_isstring(L, -1)); - CHECK(std::string(lua_tostring(L, -1)) == "OK"); + CHECK(std::string(lua_tostring(L, -1)) == XorStr("OK")); } else { @@ -235,28 +222,28 @@ static StateRef runConformance(const char* name, void (*setup)(lua_State* L) = n return globalState; } -TEST_SUITE_BEGIN("Conformance"); +TEST_SUITE_BEGIN(XorStr("Conformance")); TEST_CASE("Assert") { - runConformance("assert.lua"); + runConformance(XorStr("assert.lua")); } TEST_CASE("Basic") { - ScopedFastFlag sff("LuauLenTM", true); + ScopedFastFlag sff(XorStr("LluLenTM"), true); - runConformance("basic.lua"); + runConformance(XorStr("basic.lua")); } TEST_CASE("Math") { - runConformance("math.lua"); + runConformance(XorStr("math.lua")); } -TEST_CASE("Tables") +TEST_CASE("Table") { - runConformance("tables.lua", [](lua_State* L) { + runConformance("nextvar.lua", [](lua_State* L) { lua_pushcfunction( L, [](lua_State* L) { @@ -264,118 +251,117 @@ TEST_CASE("Tables") lua_pushlightuserdata(L, reinterpret_cast(uintptr_t(v))); return 1; }, - "makelud"); - lua_setglobal(L, "makelud"); + XorStr("makelud")); + lua_setglobal(L, XorStr("makelud")); }); } TEST_CASE("PatternMatch") { - runConformance("pm.lua"); + runConformance(XorStr("pm.lua")); } TEST_CASE("Sort") { - runConformance("sort.lua"); + runConformance(XorStr("sort.lua")); } TEST_CASE("Move") { - runConformance("move.lua"); + runConformance(XorStr("move.lua")); } TEST_CASE("Clear") { - runConformance("clear.lua"); + runConformance(XorStr("clear.lua")); } TEST_CASE("Strings") { - runConformance("strings.lua"); + runConformance(XorStr("strings.lua")); } TEST_CASE("VarArg") { - runConformance("vararg.lua"); + runConformance(XorStr("vararg.lua")); } TEST_CASE("Locals") { - runConformance("locals.lua"); + runConformance(XorStr("locals.lua")); } TEST_CASE("Literals") { - runConformance("literals.lua"); + runConformance(XorStr("literals.lua")); } TEST_CASE("Errors") { - runConformance("errors.lua"); + runConformance(XorStr("errors.lua")); } TEST_CASE("Events") { - ScopedFastFlag sff1("LuauLenTM", true); - ScopedFastFlag sff2("LuauBetterNewindex", true); + ScopedFastFlag sff("LluLenTM", true); - runConformance("events.lua"); + runConformance(XorStr("events.lua")); } TEST_CASE("Constructs") { - runConformance("constructs.lua"); + runConformance(XorStr("constructs.lua")); } TEST_CASE("Closure") { - runConformance("closure.lua"); + runConformance(XorStr("closure.lua")); } TEST_CASE("Calls") { - runConformance("calls.lua"); + runConformance(XorStr("calls.lua")); } TEST_CASE("Attrib") { - runConformance("attrib.lua"); + runConformance(XorStr("attrib.lua")); } TEST_CASE("GC") { - runConformance("gc.lua"); + runConformance(XorStr("gc.lua")); } TEST_CASE("Bitwise") { - runConformance("bitwise.lua"); + runConformance(XorStr("bitwise.lua")); } TEST_CASE("UTF8") { - runConformance("utf8.lua"); + runConformance(XorStr("utf8.lua")); } TEST_CASE("Coroutine") { - runConformance("coroutine.lua"); + runConformance(XorStr("coroutine.lua")); } static int cxxthrow(lua_State* L) { #if LUA_USE_LONGJMP - luaL_error(L, "oops"); + luaL_error(L, XorStr("oops")); #else - throw std::runtime_error("oops"); + throw std::runtime_error(XorStr("oops")); #endif } TEST_CASE("PCall") { runConformance("pcall.lua", [](lua_State* L) { - lua_pushcfunction(L, cxxthrow, "cxxthrow"); - lua_setglobal(L, "cxxthrow"); + lua_pushcfunction(L, cxxthrow, XorStr("cxxthrow")); + lua_setglobal(L, XorStr("cxxthrow")); lua_pushcfunction( L, @@ -385,39 +371,41 @@ TEST_CASE("PCall") lua_resumeerror(co, L); return 0; }, - "resumeerror"); - lua_setglobal(L, "resumeerror"); + XorStr("resumeerror")); + lua_setglobal(L, XorStr("resumeerror")); }); } TEST_CASE("Pack") { - runConformance("tpack.lua"); + runConformance(XorStr("tpack.lua")); } TEST_CASE("Vector") { - lua_CompileOptions copts = defaultOptions(); + lua_CompileOptions copts = {}; + copts.optimizationLevel = 1; + copts.debugLevel = 1; copts.vectorCtor = "vector"; runConformance( "vector.lua", [](lua_State* L) { - lua_pushcfunction(L, lua_vector, "vector"); - lua_setglobal(L, "vector"); + lua_pushcfunction(L, lua_vector, XorStr("vector")); + lua_setglobal(L, XorStr("vector")); #if LUA_VECTOR_SIZE == 4 lua_pushvector(L, 0.0f, 0.0f, 0.0f, 0.0f); #else lua_pushvector(L, 0.0f, 0.0f, 0.0f); #endif - luaL_newmetatable(L, "vector"); + luaL_newmetatable(L, XorStr("vector")); - lua_pushstring(L, "__index"); + lua_pushstring(L, XorStr("__index")); lua_pushcfunction(L, lua_vector_index, nullptr); lua_settable(L, -3); - lua_pushstring(L, "__namecall"); + lua_pushstring(L, XorStr("__namecall")); lua_pushcfunction(L, lua_vector_namecall, nullptr); lua_settable(L, -3); @@ -428,37 +416,37 @@ TEST_CASE("Vector") nullptr, nullptr, &copts); } -static void populateRTTI(lua_State* L, Luau::TypeId type) +static void populateRTTI(lua_State* L, lluz::TypeId type) { - if (auto p = Luau::get(type)) + if (auto p = lluz::get(type)) { switch (p->type) { - case Luau::PrimitiveTypeVar::Boolean: - lua_pushstring(L, "boolean"); + case lluz::PrimitiveTypeVar::Boolean: + lua_pushstring(L, XorStr("boolean")); break; - case Luau::PrimitiveTypeVar::NilType: - lua_pushstring(L, "nil"); + case lluz::PrimitiveTypeVar::NilType: + lua_pushstring(L, XorStr("nil")); break; - case Luau::PrimitiveTypeVar::Number: - lua_pushstring(L, "number"); + case lluz::PrimitiveTypeVar::Number: + lua_pushstring(L, XorStr("number")); break; - case Luau::PrimitiveTypeVar::String: - lua_pushstring(L, "string"); + case lluz::PrimitiveTypeVar::String: + lua_pushstring(L, XorStr("string")); break; - case Luau::PrimitiveTypeVar::Thread: - lua_pushstring(L, "thread"); + case lluz::PrimitiveTypeVar::Thread: + lua_pushstring(L, XorStr("thread")); break; default: - LUAU_ASSERT(!"Unknown primitive type"); + lluz_ASSERT(!XorStr("Unknown primitive type")); } } - else if (auto t = Luau::get(type)) + else if (auto t = lluz::get(type)) { lua_newtable(L); @@ -468,36 +456,38 @@ static void populateRTTI(lua_State* L, Luau::TypeId type) lua_setfield(L, -2, name.c_str()); } } - else if (Luau::get(type)) + else if (lluz::get(type)) { - lua_pushstring(L, "function"); + lua_pushstring(L, XorStr("function")); } - else if (Luau::get(type)) + else if (lluz::get(type)) { - lua_pushstring(L, "any"); + lua_pushstring(L, XorStr("any")); } - else if (auto i = Luau::get(type)) + else if (auto i = lluz::get(type)) { for (const auto& part : i->parts) - LUAU_ASSERT(Luau::get(part)); + lluz_ASSERT(lluz::get(part)); - lua_pushstring(L, "function"); + lua_pushstring(L, XorStr("function")); } else { - LUAU_ASSERT(!"Unknown type"); + lluz_ASSERT(!XorStr("Unknown type")); } } TEST_CASE("Types") { - runConformance("types.lua", [](lua_State* L) { - Luau::NullModuleResolver moduleResolver; - Luau::InternalErrorReporter iceHandler; - Luau::TypeChecker env(&moduleResolver, &iceHandler); + ScopedFastFlag sff("lluzCheckLenMT", true); - Luau::registerBuiltinTypes(env); - Luau::freeze(env.globalTypes); + runConformance("types.lua", [](lua_State* L) { + lluz::NullModuleResolver moduleResolver; + lluz::InternalErrorReporter iceHandler; + lluz::TypeChecker env(&moduleResolver, &iceHandler); + + lluz::registerBuiltinTypes(env); + lluz::freeze(env.globalTypes); lua_newtable(L); @@ -507,18 +497,18 @@ TEST_CASE("Types") lua_setfield(L, -2, toString(name).c_str()); } - lua_setglobal(L, "RTTI"); + lua_setglobal(L, XorStr("RTTI")); }); } TEST_CASE("DateTime") { - runConformance("datetime.lua"); + runConformance(XorStr("datetime.lua")); } TEST_CASE("Debug") { - runConformance("debug.lua"); + runConformance(XorStr("debug.lua")); } TEST_CASE("Debugger") @@ -529,7 +519,8 @@ TEST_CASE("Debugger") breakhits = 0; interruptedthread = nullptr; - lua_CompileOptions copts = defaultOptions(); + lua_CompileOptions copts = {}; + copts.optimizationLevel = 1; copts.debugLevel = 2; runConformance( @@ -572,8 +563,8 @@ TEST_CASE("Debugger") lua_breakpoint(L, -1, line, enabled); return 0; }, - "breakpoint"); - lua_setglobal(L, "breakpoint"); + XorStr("breakpoint")); + lua_setglobal(L, XorStr("breakpoint")); }, [](lua_State* L) { CHECK(breakhits % 2 == 1); @@ -665,11 +656,11 @@ TEST_CASE("SameHash") // To keep VM and compiler separate, we duplicate the hash function definition // This test validates that the hash function in question returns the same results on basic inputs // If this is violated, some code may regress in performance due to hash slot misprediction in inline caches - CHECK(luaS_hash("", 0) == Luau::BytecodeBuilder::getStringHash({"", 0})); - CHECK(luaS_hash("lua", 3) == Luau::BytecodeBuilder::getStringHash({"lua", 3})); - CHECK(luaS_hash("luau", 4) == Luau::BytecodeBuilder::getStringHash({"luau", 4})); - CHECK(luaS_hash("luaubytecode", 12) == Luau::BytecodeBuilder::getStringHash({"luaubytecode", 12})); - CHECK(luaS_hash("luaubytecodehash", 16) == Luau::BytecodeBuilder::getStringHash({"luaubytecodehash", 16})); + CHECK(luaS_hash("", 0) == lluz::BytecodeBuilder::getStringHash({"", 0})); + CHECK(luaS_hash("lua", 3) == lluz::BytecodeBuilder::getStringHash({"lua", 3})); + CHECK(luaS_hash("lluz", 4) == lluz::BytecodeBuilder::getStringHash({"lluz", 4})); + CHECK(luaS_hash("lluzbytecode", 12) == lluz::BytecodeBuilder::getStringHash({"lluzbytecode", 12})); + CHECK(luaS_hash("lluzbytecodehash", 16) == lluz::BytecodeBuilder::getStringHash({"lluzbytecodehash", 16})); // Also hash should work on unaligned source data even when hashing long strings char buf[128] = {}; @@ -722,12 +713,12 @@ TEST_CASE("ApiTables") lua_newtable(L); lua_pushnumber(L, 123.0); - lua_setfield(L, -2, "key"); - lua_pushstring(L, "test"); + lua_setfield(L, -2, XorStr("key")); + lua_pushstring(L, XorStr("test")); lua_rawseti(L, -2, 5); // lua_gettable - lua_pushstring(L, "key"); + lua_pushstring(L, XorStr("key")); CHECK(lua_gettable(L, -2) == LUA_TNUMBER); CHECK(lua_tonumber(L, -1) == 123.0); lua_pop(L, 1); @@ -743,7 +734,7 @@ TEST_CASE("ApiTables") lua_pop(L, 1); // lua_rawget - lua_pushstring(L, "key"); + lua_pushstring(L, XorStr("key")); CHECK(lua_rawget(L, -2) == LUA_TNUMBER); CHECK(lua_tonumber(L, -1) == 123.0); lua_pop(L, 1); @@ -758,12 +749,12 @@ TEST_CASE("ApiTables") TEST_CASE("ApiCalls") { - StateRef globalState = runConformance("apicalls.lua"); + StateRef globalState = runConformance(XorStr("apicalls.lua")); lua_State* L = globalState.get(); // lua_call { - lua_getfield(L, LUA_GLOBALSINDEX, "add"); + lua_getfield(L, LUA_GLOBALSINDEX, XorStr("add")); lua_pushnumber(L, 40); lua_pushnumber(L, 2); lua_call(L, 2, 1); @@ -774,7 +765,7 @@ TEST_CASE("ApiCalls") // lua_pcall { - lua_getfield(L, LUA_GLOBALSINDEX, "add"); + lua_getfield(L, LUA_GLOBALSINDEX, XorStr("add")); lua_pushnumber(L, 40); lua_pushnumber(L, 2); lua_pcall(L, 2, 1, 0); @@ -787,11 +778,11 @@ TEST_CASE("ApiCalls") { lua_State* L2 = lua_newthread(L); - lua_getfield(L2, LUA_GLOBALSINDEX, "create_with_tm"); + lua_getfield(L2, LUA_GLOBALSINDEX, XorStr("create_with_tm")); lua_pushnumber(L2, 42); lua_pcall(L2, 1, 1, 0); - lua_getfield(L2, LUA_GLOBALSINDEX, "create_with_tm"); + lua_getfield(L2, LUA_GLOBALSINDEX, XorStr("create_with_tm")); lua_pushnumber(L2, 42); lua_pcall(L2, 1, 1, 0); @@ -808,18 +799,18 @@ TEST_CASE("ApiCalls") // lua_clonefunction + fenv { - lua_getfield(L, LUA_GLOBALSINDEX, "getpi"); + lua_getfield(L, LUA_GLOBALSINDEX, XorStr("getpi")); lua_call(L, 0, 1); CHECK(lua_tonumber(L, -1) == 3.1415926); lua_pop(L, 1); - lua_getfield(L, LUA_GLOBALSINDEX, "getpi"); + lua_getfield(L, LUA_GLOBALSINDEX, XorStr("getpi")); // clone & override env lua_clonefunction(L, -1); lua_newtable(L); lua_pushnumber(L, 42); - lua_setfield(L, -2, "pi"); + lua_setfield(L, -2, XorStr("pi")); lua_setfenv(L, -2); lua_call(L, 0, 1); @@ -834,12 +825,12 @@ TEST_CASE("ApiCalls") // lua_clonefunction + upvalues { - lua_getfield(L, LUA_GLOBALSINDEX, "incuv"); + lua_getfield(L, LUA_GLOBALSINDEX, XorStr("incuv")); lua_call(L, 0, 1); CHECK(lua_tonumber(L, -1) == 1); lua_pop(L, 1); - lua_getfield(L, LUA_GLOBALSINDEX, "incuv"); + lua_getfield(L, LUA_GLOBALSINDEX, XorStr("incuv")); // two clones lua_clonefunction(L, -1); lua_clonefunction(L, -2); @@ -859,41 +850,6 @@ TEST_CASE("ApiCalls") } } -TEST_CASE("ApiAtoms") -{ - StateRef globalState(luaL_newstate(), lua_close); - lua_State* L = globalState.get(); - - lua_callbacks(L)->useratom = [](const char* s, size_t l) -> int16_t { - if (strcmp(s, "string") == 0) - return 0; - if (strcmp(s, "important") == 0) - return 1; - - return -1; - }; - - lua_pushstring(L, "string"); - lua_pushstring(L, "import"); - lua_pushstring(L, "ant"); - lua_concat(L, 2); - lua_pushstring(L, "unimportant"); - - int a1, a2, a3; - const char* s1 = lua_tostringatom(L, -3, &a1); - const char* s2 = lua_tostringatom(L, -2, &a2); - const char* s3 = lua_tostringatom(L, -1, &a3); - - CHECK(strcmp(s1, "string") == 0); - CHECK(a1 == 0); - - CHECK(strcmp(s2, "important") == 0); - CHECK(a2 == 1); - - CHECK(strcmp(s3, "unimportant") == 0); - CHECK(a3 == -1); -} - static bool endsWith(const std::string& str, const std::string& suffix) { if (suffix.length() > str.length()) @@ -924,7 +880,7 @@ TEST_CASE("ExceptionObject") CHECK(e.what() != nullptr); return ExceptionResult{true, e.what()}; } - return ExceptionResult{false, ""}; + return ExceptionResult{false, XorStr("")}; }; auto reallocFunc = [](void* /*ud*/, void* ptr, size_t /*osize*/, size_t nsize) -> void* { @@ -950,34 +906,34 @@ TEST_CASE("ExceptionObject") lua_State* L = globalState.get(); { - ExceptionResult result = captureException(L, "infinite_recursion_error"); + ExceptionResult result = captureException(L, XorStr("infinite_recursion_error")); CHECK(result.exceptionGenerated); } { - ExceptionResult result = captureException(L, "empty_function"); + ExceptionResult result = captureException(L, XorStr("empty_function")); CHECK_FALSE(result.exceptionGenerated); } { - ExceptionResult result = captureException(L, "pass_number_to_error"); + ExceptionResult result = captureException(L, XorStr("pass_number_to_error")); CHECK(result.exceptionGenerated); CHECK(endsWith(result.description, "42")); } { - ExceptionResult result = captureException(L, "pass_string_to_error"); + ExceptionResult result = captureException(L, XorStr("pass_string_to_error")); CHECK(result.exceptionGenerated); CHECK(endsWith(result.description, "string argument")); } { - ExceptionResult result = captureException(L, "pass_table_to_error"); + ExceptionResult result = captureException(L, XorStr("pass_table_to_error")); CHECK(result.exceptionGenerated); } { - ExceptionResult result = captureException(L, "large_allocation_error"); + ExceptionResult result = captureException(L, XorStr("large_allocation_error")); CHECK(result.exceptionGenerated); } } @@ -985,7 +941,7 @@ TEST_CASE("ExceptionObject") TEST_CASE("IfElseExpression") { - runConformance("ifelseexpr.lua"); + runConformance(XorStr("ifelseexpr.lua")); } TEST_CASE("TagMethodError") @@ -1001,8 +957,9 @@ TEST_CASE("TagMethodError") TEST_CASE("Coverage") { - lua_CompileOptions copts = defaultOptions(); - copts.optimizationLevel = 1; // disable inlining to get fixed expected hit results + lua_CompileOptions copts = {}; + copts.optimizationLevel = 1; + copts.debugLevel = 1; copts.coverageLevel = 2; runConformance( @@ -1011,7 +968,7 @@ TEST_CASE("Coverage") lua_pushcfunction( L, [](lua_State* L) -> int { - luaL_argexpected(L, lua_isLfunction(L, 1), 1, "function"); + luaL_argexpected(L, lua_isLfunction(L, 1), 1, XorStr("function")); lua_newtable(L); lua_getcoverage(L, 1, L, [](void* context, const char* function, int linedefined, int depth, const int* hits, size_t size) { @@ -1020,13 +977,13 @@ TEST_CASE("Coverage") lua_newtable(L); lua_pushstring(L, function); - lua_setfield(L, -2, "name"); + lua_setfield(L, -2, XorStr("name")); lua_pushinteger(L, linedefined); - lua_setfield(L, -2, "linedefined"); + lua_setfield(L, -2, XorStr("linedefined")); lua_pushinteger(L, depth); - lua_setfield(L, -2, "depth"); + lua_setfield(L, -2, XorStr("depth")); for (size_t i = 0; i < size; ++i) if (hits[i] != -1) @@ -1040,15 +997,15 @@ TEST_CASE("Coverage") return 1; }, - "getcoverage"); - lua_setglobal(L, "getcoverage"); + XorStr("getcoverage")); + lua_setglobal(L, XorStr("getcoverage")); }, nullptr, nullptr, &copts); } TEST_CASE("StringConversion") { - runConformance("strconv.lua"); + runConformance(XorStr("strconv.lua")); } TEST_CASE("GCDump") @@ -1061,8 +1018,8 @@ TEST_CASE("GCDump") // push various objects on stack to cover different paths lua_createtable(L, 1, 2); - lua_pushstring(L, "value"); - lua_setfield(L, -2, "key"); + lua_pushstring(L, XorStr("value")); + lua_setfield(L, -2, XorStr("key")); lua_pushinteger(L, 42); lua_rawseti(L, -2, 1000); @@ -1082,7 +1039,7 @@ TEST_CASE("GCDump") lua_State* CL = lua_newthread(L); - lua_pushstring(CL, "local x x = {} local function f() x[1] = math.abs(42) end function foo() coroutine.yield() end foo() return f"); + lua_pushstring(CL, XorStr("local x x = {} local function f() x[1] = math.abs(42) end function foo() coroutine.yield() end foo() return f")); lua_loadstring(CL); lua_resume(CL, nullptr, 0); @@ -1092,7 +1049,7 @@ TEST_CASE("GCDump") const char* path = "/dev/null"; #endif - FILE* f = fopen(path, "w"); + FILE* f = fopen(path, XorStr("w")); REQUIRE(f); luaC_dump(L, f, nullptr); @@ -1102,9 +1059,6 @@ TEST_CASE("GCDump") TEST_CASE("Interrupt") { - lua_CompileOptions copts = defaultOptions(); - copts.optimizationLevel = 1; // disable loop unrolling to get fixed expected hit results - static const int expectedhits[] = { 2, 9, @@ -1155,8 +1109,7 @@ TEST_CASE("Interrupt") }, [](lua_State* L) { CHECK(index == 5); // a single yield point - }, - nullptr, &copts); + }); CHECK(index == int(std::size(expectedhits))); } @@ -1199,10 +1152,6 @@ TEST_CASE("UserdataApi") CHECK(lua_touserdatatagged(L, -1, 41) == nullptr); CHECK(lua_userdatatag(L, -1) == 42); - lua_setuserdatatag(L, -1, 43); - CHECK(lua_userdatatag(L, -1) == 43); - lua_setuserdatatag(L, -1, 42); - // user data with inline dtor void* ud3 = lua_newuserdatadtor(L, 4, [](void* data) { dtorhits += *(int*)data; @@ -1222,7 +1171,7 @@ TEST_CASE("UserdataApi") TEST_CASE("Iter") { - runConformance("iter.lua"); + runConformance(XorStr("iter.lua")); } const int kInt64Tag = 1; @@ -1236,7 +1185,7 @@ static int64_t getInt64(lua_State* L, int idx) if (lua_isnumber(L, idx)) return lua_tointeger(L, idx); - luaL_typeerror(L, 1, "int64"); + luaL_typeerror(L, 1, XorStr("int64")); } static void pushInt64(lua_State* L, int64_t value) @@ -1262,7 +1211,7 @@ TEST_CASE("Userdata") [](lua_State* L) { void* p = lua_touserdatatagged(L, 1, kInt64Tag); if (!p) - luaL_typeerror(L, 1, "int64"); + luaL_typeerror(L, 1, XorStr("int64")); const char* name = luaL_checkstring(L, 2); @@ -1272,10 +1221,10 @@ TEST_CASE("Userdata") return 1; } - luaL_error(L, "unknown field %s", name); + luaL_error(L, XorStr("unknown field %s"), name); }, nullptr); - lua_setfield(L, -2, "__index"); + lua_setfield(L, -2, XorStr("__index")); // __newindex lua_pushcfunction( @@ -1283,7 +1232,7 @@ TEST_CASE("Userdata") [](lua_State* L) { void* p = lua_touserdatatagged(L, 1, kInt64Tag); if (!p) - luaL_typeerror(L, 1, "int64"); + luaL_typeerror(L, 1, XorStr("int64")); const char* name = luaL_checkstring(L, 2); @@ -1294,10 +1243,10 @@ TEST_CASE("Userdata") return 0; } - luaL_error(L, "unknown field %s", name); + luaL_error(L, XorStr("unknown field %s"), name); }, nullptr); - lua_setfield(L, -2, "__newindex"); + lua_setfield(L, -2, XorStr("__newindex")); // __eq lua_pushcfunction( @@ -1307,7 +1256,7 @@ TEST_CASE("Userdata") return 1; }, nullptr); - lua_setfield(L, -2, "__eq"); + lua_setfield(L, -2, XorStr("__eq")); // __lt lua_pushcfunction( @@ -1317,7 +1266,7 @@ TEST_CASE("Userdata") return 1; }, nullptr); - lua_setfield(L, -2, "__lt"); + lua_setfield(L, -2, XorStr("__lt")); // __le lua_pushcfunction( @@ -1327,7 +1276,7 @@ TEST_CASE("Userdata") return 1; }, nullptr); - lua_setfield(L, -2, "__le"); + lua_setfield(L, -2, XorStr("__le")); // __add lua_pushcfunction( @@ -1337,7 +1286,7 @@ TEST_CASE("Userdata") return 1; }, nullptr); - lua_setfield(L, -2, "__add"); + lua_setfield(L, -2, XorStr("__add")); // __sub lua_pushcfunction( @@ -1347,7 +1296,7 @@ TEST_CASE("Userdata") return 1; }, nullptr); - lua_setfield(L, -2, "__sub"); + lua_setfield(L, -2, XorStr("__sub")); // __mul lua_pushcfunction( @@ -1357,7 +1306,7 @@ TEST_CASE("Userdata") return 1; }, nullptr); - lua_setfield(L, -2, "__mul"); + lua_setfield(L, -2, XorStr("__mul")); // __div lua_pushcfunction( @@ -1368,7 +1317,7 @@ TEST_CASE("Userdata") return 1; }, nullptr); - lua_setfield(L, -2, "__div"); + lua_setfield(L, -2, XorStr("__div")); // __mod lua_pushcfunction( @@ -1379,7 +1328,7 @@ TEST_CASE("Userdata") return 1; }, nullptr); - lua_setfield(L, -2, "__mod"); + lua_setfield(L, -2, XorStr("__mod")); // __pow lua_pushcfunction( @@ -1389,7 +1338,7 @@ TEST_CASE("Userdata") return 1; }, nullptr); - lua_setfield(L, -2, "__pow"); + lua_setfield(L, -2, XorStr("__pow")); // __unm lua_pushcfunction( @@ -1399,7 +1348,7 @@ TEST_CASE("Userdata") return 1; }, nullptr); - lua_setfield(L, -2, "__unm"); + lua_setfield(L, -2, XorStr("__unm")); // __tostring lua_pushcfunction( @@ -1411,7 +1360,7 @@ TEST_CASE("Userdata") return 1; }, nullptr); - lua_setfield(L, -2, "__tostring"); + lua_setfield(L, -2, XorStr("__tostring")); // ctor lua_pushcfunction( @@ -1421,8 +1370,8 @@ TEST_CASE("Userdata") pushInt64(L, int64_t(v)); return 1; }, - "int64"); - lua_setglobal(L, "int64"); + XorStr("int64")); + lua_setglobal(L, XorStr("int64")); }); } diff --git a/tests/ConstraintGraphBuilder.test.cpp b/tests/ConstraintGraphBuilder.test.cpp index 00c3309c..8443b873 100644 --- a/tests/ConstraintGraphBuilder.test.cpp +++ b/tests/ConstraintGraphBuilder.test.cpp @@ -1,13 +1,13 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #include "Fixture.h" -#include "Luau/ConstraintGraphBuilder.h" +#include "lluz/ConstraintGraphBuilder.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("ConstraintGraphBuilder"); +TEST_SUITE_BEGIN(XorStr("ConstraintGraphBuilder")); TEST_CASE_FIXTURE(ConstraintGraphBuilderFixture, "hello_world") { diff --git a/tests/ConstraintSolver.test.cpp b/tests/ConstraintSolver.test.cpp index e33f6570..59323bcd 100644 --- a/tests/ConstraintSolver.test.cpp +++ b/tests/ConstraintSolver.test.cpp @@ -1,22 +1,22 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #include "Fixture.h" #include "doctest.h" -#include "Luau/ConstraintGraphBuilder.h" -#include "Luau/ConstraintSolver.h" +#include "lluz/ConstraintGraphBuilder.h" +#include "lluz/ConstraintSolver.h" -using namespace Luau; +using namespace lluz; -static TypeId requireBinding(NotNull scope, const char* name) +static TypeId requireBinding(NotNull scope, const char* name) { auto b = linearSearchForBinding(scope, name); - LUAU_ASSERT(b.has_value()); + lluz_ASSERT(b.has_value()); return *b; } -TEST_SUITE_BEGIN("ConstraintSolver"); +TEST_SUITE_BEGIN(XorStr("ConstraintSolver")); TEST_CASE_FIXTURE(ConstraintGraphBuilderFixture, "hello") { @@ -26,13 +26,13 @@ TEST_CASE_FIXTURE(ConstraintGraphBuilderFixture, "hello") )"); cgb.visit(block); - NotNull rootScope = NotNull(cgb.rootScope); + NotNull rootScope = NotNull(cgb.rootScope); ConstraintSolver cs{&arena, rootScope}; cs.run(); - TypeId bType = requireBinding(rootScope, "b"); + TypeId bType = requireBinding(rootScope, XorStr("b")); CHECK("number" == toString(bType)); } @@ -46,13 +46,13 @@ TEST_CASE_FIXTURE(ConstraintGraphBuilderFixture, "generic_function") )"); cgb.visit(block); - NotNull rootScope = NotNull(cgb.rootScope); + NotNull rootScope = NotNull(cgb.rootScope); ConstraintSolver cs{&arena, rootScope}; cs.run(); - TypeId idType = requireBinding(rootScope, "id"); + TypeId idType = requireBinding(rootScope, XorStr("id")); CHECK("(a) -> a" == toString(idType)); } @@ -73,7 +73,7 @@ TEST_CASE_FIXTURE(ConstraintGraphBuilderFixture, "proper_let_generalization") )"); cgb.visit(block); - NotNull rootScope = NotNull(cgb.rootScope); + NotNull rootScope = NotNull(cgb.rootScope); ToStringOptions opts; @@ -81,7 +81,7 @@ TEST_CASE_FIXTURE(ConstraintGraphBuilderFixture, "proper_let_generalization") cs.run(); - TypeId idType = requireBinding(rootScope, "b"); + TypeId idType = requireBinding(rootScope, XorStr("b")); CHECK("(a) -> number" == toString(idType, opts)); } diff --git a/tests/CostModel.test.cpp b/tests/CostModel.test.cpp index eacc718b..67565f69 100644 --- a/tests/CostModel.test.cpp +++ b/tests/CostModel.test.cpp @@ -1,22 +1,22 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Parser.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Parser.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -namespace Luau +namespace lluz { namespace Compile { -uint64_t modelCost(AstNode* root, AstLocal* const* vars, size_t varCount, const DenseHashMap& builtins); +uint64_t modelCost(AstNode* root, AstLocal* const* vars, size_t varCount); int computeCost(uint64_t model, const bool* varsConst, size_t varCount); } // namespace Compile -} // namespace Luau +} // namespace lluz -TEST_SUITE_BEGIN("CostModel"); +TEST_SUITE_BEGIN(XorStr("CostModel")); static uint64_t modelFunction(const char* source) { @@ -29,7 +29,7 @@ static uint64_t modelFunction(const char* source) AstStatFunction* func = result.root->body.data[0]->as(); REQUIRE(func); - return Luau::Compile::modelCost(func->func->body, func->func->args.data, func->func->args.size, {nullptr}); + return lluz::Compile::modelCost(func->func->body, func->func->args.data, func->func->args.size); } TEST_CASE("Expression") @@ -43,8 +43,8 @@ end const bool args1[] = {false, false, false}; const bool args2[] = {false, true, false}; - CHECK_EQ(5, Luau::Compile::computeCost(model, args1, 3)); - CHECK_EQ(2, Luau::Compile::computeCost(model, args2, 3)); + CHECK_EQ(5, lluz::Compile::computeCost(model, args1, 3)); + CHECK_EQ(2, lluz::Compile::computeCost(model, args2, 3)); } TEST_CASE("PropagateVariable") @@ -59,8 +59,8 @@ end const bool args1[] = {false}; const bool args2[] = {true}; - CHECK_EQ(3, Luau::Compile::computeCost(model, args1, 1)); - CHECK_EQ(0, Luau::Compile::computeCost(model, args2, 1)); + CHECK_EQ(3, lluz::Compile::computeCost(model, args1, 1)); + CHECK_EQ(0, lluz::Compile::computeCost(model, args2, 1)); } TEST_CASE("LoopAssign") @@ -77,8 +77,8 @@ end const bool args2[] = {true}; // loop baseline cost is 5 - CHECK_EQ(6, Luau::Compile::computeCost(model, args1, 1)); - CHECK_EQ(6, Luau::Compile::computeCost(model, args2, 1)); + CHECK_EQ(6, lluz::Compile::computeCost(model, args1, 1)); + CHECK_EQ(6, lluz::Compile::computeCost(model, args2, 1)); } TEST_CASE("MutableVariable") @@ -94,8 +94,8 @@ end const bool args1[] = {false}; const bool args2[] = {true}; - CHECK_EQ(3, Luau::Compile::computeCost(model, args1, 1)); - CHECK_EQ(2, Luau::Compile::computeCost(model, args2, 1)); + CHECK_EQ(3, lluz::Compile::computeCost(model, args1, 1)); + CHECK_EQ(2, lluz::Compile::computeCost(model, args2, 1)); } TEST_CASE("ImportCall") @@ -109,8 +109,8 @@ end const bool args1[] = {false}; const bool args2[] = {true}; - CHECK_EQ(6, Luau::Compile::computeCost(model, args1, 1)); - CHECK_EQ(6, Luau::Compile::computeCost(model, args2, 1)); + CHECK_EQ(6, lluz::Compile::computeCost(model, args1, 1)); + CHECK_EQ(6, lluz::Compile::computeCost(model, args2, 1)); } TEST_CASE("FastCall") @@ -125,8 +125,8 @@ end const bool args2[] = {true}; // note: we currently don't treat fast calls differently from cost model perspective - CHECK_EQ(6, Luau::Compile::computeCost(model, args1, 1)); - CHECK_EQ(5, Luau::Compile::computeCost(model, args2, 1)); + CHECK_EQ(6, lluz::Compile::computeCost(model, args1, 1)); + CHECK_EQ(5, lluz::Compile::computeCost(model, args2, 1)); } TEST_CASE("ControlFlow") @@ -154,8 +154,8 @@ end const bool args1[] = {false}; const bool args2[] = {true}; - CHECK_EQ(82, Luau::Compile::computeCost(model, args1, 1)); - CHECK_EQ(79, Luau::Compile::computeCost(model, args2, 1)); + CHECK_EQ(82, lluz::Compile::computeCost(model, args1, 1)); + CHECK_EQ(79, lluz::Compile::computeCost(model, args2, 1)); } TEST_CASE("Conditional") @@ -169,8 +169,8 @@ end const bool args1[] = {false}; const bool args2[] = {true}; - CHECK_EQ(4, Luau::Compile::computeCost(model, args1, 1)); - CHECK_EQ(2, Luau::Compile::computeCost(model, args2, 1)); + CHECK_EQ(4, lluz::Compile::computeCost(model, args1, 1)); + CHECK_EQ(2, lluz::Compile::computeCost(model, args2, 1)); } TEST_CASE("VarArgs") @@ -181,7 +181,7 @@ function test(...) end )"); - CHECK_EQ(8, Luau::Compile::computeCost(model, nullptr, 0)); + CHECK_EQ(8, lluz::Compile::computeCost(model, nullptr, 0)); } TEST_CASE("TablesFunctions") @@ -192,7 +192,7 @@ function test() end )"); - CHECK_EQ(22, Luau::Compile::computeCost(model, nullptr, 0)); + CHECK_EQ(22, lluz::Compile::computeCost(model, nullptr, 0)); } TEST_CASE("CostOverflow") @@ -203,7 +203,7 @@ function test() end )"); - CHECK_EQ(127, Luau::Compile::computeCost(model, nullptr, 0)); + CHECK_EQ(127, lluz::Compile::computeCost(model, nullptr, 0)); } TEST_CASE("TableAssign") @@ -219,8 +219,8 @@ end const bool args1[] = {false}; const bool args2[] = {true}; - CHECK_EQ(7, Luau::Compile::computeCost(model, args1, 1)); - CHECK_EQ(6, Luau::Compile::computeCost(model, args2, 1)); + CHECK_EQ(7, lluz::Compile::computeCost(model, args1, 1)); + CHECK_EQ(6, lluz::Compile::computeCost(model, args2, 1)); } TEST_SUITE_END(); diff --git a/tests/Error.test.cpp b/tests/Error.test.cpp index 5ba5c112..8b31611c 100644 --- a/tests/Error.test.cpp +++ b/tests/Error.test.cpp @@ -1,11 +1,11 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Error.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Error.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("ErrorTests"); +TEST_SUITE_BEGIN(XorStr("ErrorTests")); TEST_CASE("TypeError_code_should_return_nonzero_code") { diff --git a/tests/Fixture.cpp b/tests/Fixture.cpp index 90aa6236..6a1769cf 100644 --- a/tests/Fixture.cpp +++ b/tests/Fixture.cpp @@ -1,13 +1,13 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #include "Fixture.h" -#include "Luau/AstQuery.h" -#include "Luau/Parser.h" -#include "Luau/TypeVar.h" -#include "Luau/TypeAttach.h" -#include "Luau/Transpiler.h" +#include "lluz/AstQuery.h" +#include "lluz/Parser.h" +#include "lluz/TypeVar.h" +#include "lluz/TypeAttach.h" +#include "lluz/Transpiler.h" -#include "Luau/BuiltinDefinitions.h" +#include "lluz/BuiltinDefinitions.h" #include "doctest.h" @@ -17,25 +17,25 @@ static const char* mainModuleName = "MainModule"; -LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution); +lluz_FASTFLAG(DebugLluDeferredConstraintResolution); -namespace Luau +namespace lluz { std::optional TestFileResolver::resolveModule(const ModuleInfo* context, AstExpr* expr) { if (AstExprGlobal* g = expr->as()) { - if (g->name == "game") + if (g->name == XorStr("game")) return ModuleInfo{"game"}; - if (g->name == "workspace") + if (g->name == XorStr("workspace")) return ModuleInfo{"workspace"}; - if (g->name == "script") + if (g->name == XorStr("script")) return context ? std::optional(*context) : std::nullopt; } else if (AstExprIndexName* i = expr->as(); i && context) { - if (i->index == "Parent") + if (i->index == XorStr("Parent")) { std::string_view view = context->name; size_t lastSeparatorIndex = view.find_last_of('/'); @@ -63,7 +63,7 @@ std::optional TestFileResolver::resolveModule(const ModuleInfo* cont { AstName func = call->func->as()->index; - if (func == "GetService" && context->name == "game") + if (func == XorStr("GetService") && context->name == XorStr("game")) return ModuleInfo{"game/" + std::string(index->value.data, index->value.size)}; } } @@ -86,7 +86,7 @@ std::optional TestFileResolver::getEnvironmentForModule(const Modul } Fixture::Fixture(bool freeze, bool prepareAutocomplete) - : sff_DebugLuauFreezeArena("DebugLuauFreezeArena", freeze) + : sff_DebuglluzFreezeArena("DebuglluzFreezeArena", freeze) , frontend(&fileResolver, &configResolver, {/* retainFullTypeGraphs= */ true}) , typeChecker(frontend.typeChecker) { @@ -94,15 +94,15 @@ Fixture::Fixture(bool freeze, bool prepareAutocomplete) configResolver.defaultConfig.enabledLint.warningMask = ~0ull; configResolver.defaultConfig.parseOptions.captureComments = true; - Luau::freeze(frontend.typeChecker.globalTypes); - Luau::freeze(frontend.typeCheckerForAutocomplete.globalTypes); + lluz::freeze(frontend.typeChecker.globalTypes); + lluz::freeze(frontend.typeCheckerForAutocomplete.globalTypes); - Luau::setPrintLine([](auto s) {}); + lluz::setPrintLine([](auto s) {}); } Fixture::~Fixture() { - Luau::resetPrintLine(); + lluz::resetPrintLine(); } AstStatBlock* Fixture::parse(const std::string& source, const ParseOptions& parseOptions) @@ -123,7 +123,7 @@ AstStatBlock* Fixture::parse(const std::string& source, const ParseOptions& pars { frontend.lint(*sourceModule); - typeChecker.check(*sourceModule, sourceModule->mode.value_or(Luau::Mode::Nonstrict)); + typeChecker.check(*sourceModule, sourceModule->mode.value_or(lluz::Mode::Nonstrict)); } throw ParseErrors(result.errors); @@ -195,7 +195,7 @@ ParseResult Fixture::matchParseError(const std::string& source, const std::strin sourceModule.reset(new SourceModule); ParseResult result = Parser::parse(source.c_str(), source.length(), *sourceModule->names, *sourceModule->allocator, options); - CHECK_MESSAGE(!result.errors.empty(), "Expected a parse error in '" << source << "'"); + CHECK_MESSAGE(!result.errors.empty(), XorStr("Expected a parse error in '" << source << "'")); if (!result.errors.empty()) { @@ -216,7 +216,7 @@ ParseResult Fixture::matchParseErrorPrefix(const std::string& source, const std: sourceModule.reset(new SourceModule); ParseResult result = Parser::parse(source.c_str(), source.length(), *sourceModule->names, *sourceModule->allocator, options); - CHECK_MESSAGE(!result.errors.empty(), "Expected a parse error in '" << source << "'"); + CHECK_MESSAGE(!result.errors.empty(), XorStr("Expected a parse error in '" << source << "'")); if (!result.errors.empty()) { @@ -257,8 +257,8 @@ std::optional Fixture::getType(const std::string& name) ModulePtr module = getMainModule(); REQUIRE(module); - if (FFlag::DebugLuauDeferredConstraintResolution) - return linearSearchForBinding(module->getModuleScope().get(), name.c_str()); + if (FFlag::DebugLluDeferredConstraintResolution) + return linearSearchForBinding(module->getModuleScope2(), name.c_str()); else return lookupName(module->getModuleScope(), name); } @@ -266,7 +266,7 @@ std::optional Fixture::getType(const std::string& name) TypeId Fixture::requireType(const std::string& name) { std::optional ty = getType(name); - REQUIRE_MESSAGE(bool(ty), "Unable to requireType \"" << name << "\""); + REQUIRE_MESSAGE(bool(ty), XorStr("Unable to requireType \"" << name << "\"")); return follow(*ty); } @@ -285,7 +285,7 @@ TypeId Fixture::requireType(const ModulePtr& module, const std::string& name) TypeId Fixture::requireType(const ScopePtr& scope, const std::string& name) { std::optional ty = lookupName(scope, name); - REQUIRE_MESSAGE(ty, "requireType: No type \"" << name << "\""); + REQUIRE_MESSAGE(ty, XorStr("requireType: No type \"" << name << "\"")); return *ty; } @@ -293,14 +293,14 @@ std::optional Fixture::findTypeAtPosition(Position position) { ModulePtr module = getMainModule(); SourceModule* sourceModule = getMainSourceModule(); - return Luau::findTypeAtPosition(*module, *sourceModule, position); + return lluz::findTypeAtPosition(*module, *sourceModule, position); } std::optional Fixture::findExpectedTypeAtPosition(Position position) { ModulePtr module = getMainModule(); SourceModule* sourceModule = getMainSourceModule(); - return Luau::findExpectedTypeAtPosition(*module, *sourceModule, position); + return lluz::findExpectedTypeAtPosition(*module, *sourceModule, position); } TypeId Fixture::requireTypeAtPosition(Position position) @@ -330,7 +330,7 @@ std::string Fixture::decorateWithTypes(const std::string& code) { fileResolver.source[mainModuleName] = code; - Luau::CheckResult typeInfo = frontend.check(mainModuleName); + lluz::CheckResult typeInfo = frontend.check(mainModuleName); SourceModule* sourceModule = frontend.getSourceModule(mainModuleName); attachTypeData(*sourceModule, *frontend.moduleResolver.getModule(mainModuleName)); @@ -346,7 +346,7 @@ void Fixture::dumpErrors(std::ostream& os, const std::vector& errors) os << "Error: " << error << std::endl; std::string_view source = fileResolver.source[error.moduleName]; - std::vector lines = Luau::split(source, '\n'); + std::vector lines = lluz::split(source, '\n'); if (error.location.begin.line >= lines.size()) { @@ -365,9 +365,9 @@ void Fixture::dumpErrors(std::ostream& os, const std::vector& errors) void Fixture::registerTestTypes() { - addGlobalBinding(typeChecker, "game", typeChecker.anyType, "@luau"); - addGlobalBinding(typeChecker, "workspace", typeChecker.anyType, "@luau"); - addGlobalBinding(typeChecker, "script", typeChecker.anyType, "@luau"); + addGlobalBinding(typeChecker, XorStr("game", typeChecker.anyType, "@lluz")); + addGlobalBinding(typeChecker, XorStr("workspace", typeChecker.anyType, "@lluz")); + addGlobalBinding(typeChecker, XorStr("script", typeChecker.anyType, "@lluz")); } void Fixture::dumpErrors(const CheckResult& cr) @@ -392,13 +392,13 @@ std::string Fixture::getErrors(const CheckResult& cr) return ss.str(); } -void Fixture::validateErrors(const std::vector& errors) +void Fixture::validateErrors(const std::vector& errors) { std::ostringstream oss; // This helps us validate that error stringification doesn't crash, using both user-facing and internal test-only representation // Also we exercise error comparison to make sure it's at least able to compare the error equal to itself - for (const Luau::TypeError& e : errors) + for (const lluz::TypeError& e : errors) { oss.clear(); oss << e; @@ -410,32 +410,32 @@ void Fixture::validateErrors(const std::vector& errors) LoadDefinitionFileResult Fixture::loadDefinition(const std::string& source) { unfreeze(typeChecker.globalTypes); - LoadDefinitionFileResult result = loadDefinitionFile(typeChecker, typeChecker.globalScope, source, "@test"); + LoadDefinitionFileResult result = loadDefinitionFile(typeChecker, typeChecker.globalScope, source, XorStr("@test")); freeze(typeChecker.globalTypes); - REQUIRE_MESSAGE(result.success, "loadDefinition: unable to load definition file"); + REQUIRE_MESSAGE(result.success, XorStr("loadDefinition: unable to load definition file")); return result; } BuiltinsFixture::BuiltinsFixture(bool freeze, bool prepareAutocomplete) : Fixture(freeze, prepareAutocomplete) { - Luau::unfreeze(frontend.typeChecker.globalTypes); - Luau::unfreeze(frontend.typeCheckerForAutocomplete.globalTypes); + lluz::unfreeze(frontend.typeChecker.globalTypes); + lluz::unfreeze(frontend.typeCheckerForAutocomplete.globalTypes); registerBuiltinTypes(frontend.typeChecker); if (prepareAutocomplete) registerBuiltinTypes(frontend.typeCheckerForAutocomplete); registerTestTypes(); - Luau::freeze(frontend.typeChecker.globalTypes); - Luau::freeze(frontend.typeCheckerForAutocomplete.globalTypes); + lluz::freeze(frontend.typeChecker.globalTypes); + lluz::freeze(frontend.typeCheckerForAutocomplete.globalTypes); } ConstraintGraphBuilderFixture::ConstraintGraphBuilderFixture() : Fixture() - , cgb(mainModuleName, &arena, NotNull(&ice), frontend.getGlobalScope()) - , forceTheFlag{"DebugLuauDeferredConstraintResolution", true} + , cgb(mainModuleName, &arena, NotNull(&ice), frontend.getGlobalScope2()) + , forceTheFlag{"DebuglluzDeferredConstraintResolution", true} { BlockedTypeVar::nextIndex = 0; } @@ -479,17 +479,17 @@ std::optional lookupName(ScopePtr scope, const std::string& name) return std::nullopt; } -std::optional linearSearchForBinding(Scope* scope, const char* name) +std::optional linearSearchForBinding(Scope2* scope, const char* name) { while (scope) { for (const auto& [n, ty] : scope->bindings) { if (n.astName() == name) - return ty.typeId; + return ty; } - scope = scope->parent.get(); + scope = scope->parent; } return std::nullopt; @@ -502,4 +502,4 @@ void dump(const std::vector& constraints) printf("%s\n", toString(c, opts).c_str()); } -} // namespace Luau +} // namespace lluz diff --git a/tests/Fixture.h b/tests/Fixture.h index a716fe9b..48626fa5 100644 --- a/tests/Fixture.h +++ b/tests/Fixture.h @@ -1,17 +1,17 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #pragma once -#include "Luau/Config.h" -#include "Luau/FileResolver.h" -#include "Luau/Frontend.h" -#include "Luau/IostreamHelpers.h" -#include "Luau/Linter.h" -#include "Luau/Location.h" -#include "Luau/ModuleResolver.h" -#include "Luau/Scope.h" -#include "Luau/ToString.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +#include "lluz/Config.h" +#include "lluz/FileResolver.h" +#include "lluz/Frontend.h" +#include "lluz/IostreamHelpers.h" +#include "lluz/Linter.h" +#include "lluz/Location.h" +#include "lluz/ModuleResolver.h" +#include "lluz/Scope.h" +#include "lluz/ToString.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "IostreamOptional.h" #include "ScopedFlags.h" @@ -22,7 +22,7 @@ #include -namespace Luau +namespace lluz { struct TestFileResolver @@ -39,7 +39,7 @@ struct TestFileResolver const ModulePtr getModule(const ModuleName& moduleName) const override { - LUAU_ASSERT(false); + lluz_ASSERT(false); return nullptr; } @@ -95,7 +95,7 @@ struct Fixture explicit Fixture(bool freeze = true, bool prepareAutocomplete = false); ~Fixture(); - // Throws Luau::ParseErrors if the parse fails. + // Throws lluz::ParseErrors if the parse fails. AstStatBlock* parse(const std::string& source, const ParseOptions& parseOptions = {}); CheckResult check(Mode mode, std::string source); CheckResult check(const std::string& source); @@ -127,8 +127,7 @@ struct Fixture std::optional lookupType(const std::string& name); std::optional lookupImportedType(const std::string& moduleAlias, const std::string& name); - ScopedFastFlag sff_DebugLuauFreezeArena; - ScopedFastFlag sff_UnknownNever{"LuauUnknownAndNeverType", true}; + ScopedFastFlag sff_DebuglluzFreezeArena; TestFileResolver fileResolver; TestConfigResolver configResolver; @@ -192,11 +191,11 @@ void dump(const std::vector& constraints); std::optional lookupName(ScopePtr scope, const std::string& name); // Warning: This function runs in O(n**2) -std::optional linearSearchForBinding(Scope* scope, const char* name); +std::optional linearSearchForBinding(Scope2* scope, const char* name); -} // namespace Luau +} // namespace lluz -#define LUAU_REQUIRE_ERRORS(result) \ +#define lluz_REQUIRE_ERRORS(result) \ do \ { \ auto&& r = (result); \ @@ -204,7 +203,7 @@ std::optional linearSearchForBinding(Scope* scope, const char* name); REQUIRE(!r.errors.empty()); \ } while (false) -#define LUAU_REQUIRE_ERROR_COUNT(count, result) \ +#define lluz_REQUIRE_ERROR_COUNT(count, result) \ do \ { \ auto&& r = (result); \ @@ -212,4 +211,4 @@ std::optional linearSearchForBinding(Scope* scope, const char* name); REQUIRE_MESSAGE(count == r.errors.size(), getErrors(r)); \ } while (false) -#define LUAU_REQUIRE_NO_ERRORS(result) LUAU_REQUIRE_ERROR_COUNT(0, result) +#define lluz_REQUIRE_NO_ERRORS(result) lluz_REQUIRE_ERROR_COUNT(0, result) diff --git a/tests/Frontend.test.cpp b/tests/Frontend.test.cpp index 0382f227..6805dc8b 100644 --- a/tests/Frontend.test.cpp +++ b/tests/Frontend.test.cpp @@ -1,8 +1,8 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/AstQuery.h" -#include "Luau/BuiltinDefinitions.h" -#include "Luau/Frontend.h" -#include "Luau/RequireTracer.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/AstQuery.h" +#include "lluz/BuiltinDefinitions.h" +#include "lluz/Frontend.h" +#include "lluz/RequireTracer.h" #include "Fixture.h" @@ -10,7 +10,7 @@ #include -using namespace Luau; +using namespace lluz; namespace { @@ -49,10 +49,10 @@ struct NaiveFileResolver : NullFileResolver { if (AstExprGlobal* g = expr->as()) { - if (g->name == "Modules") + if (g->name == XorStr("Modules")) return ModuleInfo{"Modules"}; - if (g->name == "game") + if (g->name == XorStr("game")) return ModuleInfo{"game"}; } else if (AstExprIndexName* i = expr->as()) @@ -66,7 +66,7 @@ struct NaiveFileResolver : NullFileResolver { AstName func = call->func->as()->index; - if (func == "GetService" && context->name == "game") + if (func == XorStr("GetService") && context->name == XorStr("game")) return ModuleInfo{"game/" + std::string(index->value.data, index->value.size)}; } } @@ -81,12 +81,12 @@ struct FrontendFixture : BuiltinsFixture { FrontendFixture() { - addGlobalBinding(typeChecker, "game", frontend.typeChecker.anyType, "@test"); - addGlobalBinding(typeChecker, "script", frontend.typeChecker.anyType, "@test"); + addGlobalBinding(typeChecker, XorStr("game", frontend.typeChecker.anyType, "@test")); + addGlobalBinding(typeChecker, XorStr("script", frontend.typeChecker.anyType, "@test")); } }; -TEST_SUITE_BEGIN("FrontendTest"); +TEST_SUITE_BEGIN(XorStr("FrontendTest")); TEST_CASE_FIXTURE(FrontendFixture, "find_a_require") { @@ -96,9 +96,9 @@ TEST_CASE_FIXTURE(FrontendFixture, "find_a_require") NaiveFileResolver naiveFileResolver; - auto res = traceRequires(&naiveFileResolver, program, ""); + auto res = traceRequires(&naiveFileResolver, program, XorStr("")); CHECK_EQ(1, res.requireList.size()); - CHECK_EQ(res.requireList[0].first, "Modules/Foo/Bar"); + CHECK_EQ(res.requireList[0].first, XorStr("Modules/Foo/Bar")); } // It could be argued that this should not work. @@ -112,7 +112,7 @@ TEST_CASE_FIXTURE(FrontendFixture, "find_a_require_inside_a_function") NaiveFileResolver naiveFileResolver; - auto res = traceRequires(&naiveFileResolver, program, ""); + auto res = traceRequires(&naiveFileResolver, program, XorStr("")); CHECK_EQ(1, res.requireList.size()); } @@ -137,7 +137,7 @@ TEST_CASE_FIXTURE(FrontendFixture, "real_source") NaiveFileResolver naiveFileResolver; - auto res = traceRequires(&naiveFileResolver, program, ""); + auto res = traceRequires(&naiveFileResolver, program, XorStr("")); CHECK_EQ(8, res.requireList.size()); } @@ -150,12 +150,12 @@ TEST_CASE_FIXTURE(FrontendFixture, "automatically_check_dependent_scripts") return {b_value = A.hello} )"; - frontend.check("game/Gui/Modules/B"); + frontend.check(XorStr("game/Gui/Modules/B")); ModulePtr bModule = frontend.moduleResolver.modules["game/Gui/Modules/B"]; REQUIRE(bModule != nullptr); CHECK(bModule->errors.empty()); - Luau::dumpErrors(bModule); + lluz::dumpErrors(bModule); auto bExports = first(bModule->getModuleScope()->returnType); REQUIRE(!!bExports); @@ -188,8 +188,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "automatically_check_cyclically_dependent_scr return {} )"; - CheckResult result1 = frontend.check("game/Gui/Modules/B"); - LUAU_REQUIRE_ERROR_COUNT(4, result1); + CheckResult result1 = frontend.check(XorStr("game/Gui/Modules/B")); + lluz_REQUIRE_ERROR_COUNT(4, result1); CHECK_MESSAGE(get(result1.errors[0]), "Should have been a ModuleHasCyclicDependency: " << toString(result1.errors[0])); @@ -197,8 +197,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "automatically_check_cyclically_dependent_scr CHECK_MESSAGE(get(result1.errors[2]), "Should have been a ModuleHasCyclicDependency: " << toString(result1.errors[2])); - CheckResult result2 = frontend.check("game/Gui/Modules/D"); - LUAU_REQUIRE_ERROR_COUNT(0, result2); + CheckResult result2 = frontend.check(XorStr("game/Gui/Modules/D")); + lluz_REQUIRE_ERROR_COUNT(0, result2); } TEST_CASE_FIXTURE(FrontendFixture, "any_annotation_breaks_cycle") @@ -214,8 +214,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "any_annotation_breaks_cycle") return {hello = A.hello} )"; - CheckResult result = frontend.check("game/Gui/Modules/A"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = frontend.check(XorStr("game/Gui/Modules/A")); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(FrontendFixture, "nocheck_modules_are_typed") @@ -237,8 +237,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "nocheck_modules_are_typed") local five : A.Foo = 5 )"; - CheckResult result = frontend.check("game/Gui/Modules/C"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = frontend.check(XorStr("game/Gui/Modules/C")); + lluz_REQUIRE_NO_ERRORS(result); ModulePtr aModule = frontend.moduleResolver.modules["game/Gui/Modules/A"]; REQUIRE(bool(aModule)); @@ -269,8 +269,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "cycle_detection_between_check_and_nocheck") return {hello = A.hello} )"; - CheckResult result = frontend.check("game/Gui/Modules/A"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = frontend.check(XorStr("game/Gui/Modules/A")); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(FrontendFixture, "nocheck_cycle_used_by_checked") @@ -294,8 +294,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "nocheck_cycle_used_by_checked") return {a=A, b=B} )"; - CheckResult result = frontend.check("game/Gui/Modules/C"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = frontend.check(XorStr("game/Gui/Modules/C")); + lluz_REQUIRE_NO_ERRORS(result); ModulePtr cModule = frontend.moduleResolver.modules["game/Gui/Modules/C"]; REQUIRE(bool(cModule)); @@ -320,8 +320,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "cycle_detection_disabled_in_nocheck") return {hello = A.hello} )"; - CheckResult result = frontend.check("game/Gui/Modules/A"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = frontend.check(XorStr("game/Gui/Modules/A")); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(FrontendFixture, "cycle_errors_can_be_fixed") @@ -337,8 +337,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "cycle_errors_can_be_fixed") return {hello = A.hello} )"; - CheckResult result1 = frontend.check("game/Gui/Modules/A"); - LUAU_REQUIRE_ERROR_COUNT(2, result1); + CheckResult result1 = frontend.check(XorStr("game/Gui/Modules/A")); + lluz_REQUIRE_ERROR_COUNT(2, result1); CHECK_MESSAGE(get(result1.errors[0]), "Should have been a ModuleHasCyclicDependency: " << toString(result1.errors[0])); @@ -347,10 +347,10 @@ TEST_CASE_FIXTURE(FrontendFixture, "cycle_errors_can_be_fixed") fileResolver.source["game/Gui/Modules/B"] = R"( return {hello = 42} )"; - frontend.markDirty("game/Gui/Modules/B"); + frontend.markDirty(XorStr("game/Gui/Modules/B")); - CheckResult result2 = frontend.check("game/Gui/Modules/A"); - LUAU_REQUIRE_NO_ERRORS(result2); + CheckResult result2 = frontend.check(XorStr("game/Gui/Modules/A")); + lluz_REQUIRE_NO_ERRORS(result2); } TEST_CASE_FIXTURE(FrontendFixture, "cycle_error_paths") @@ -366,22 +366,22 @@ TEST_CASE_FIXTURE(FrontendFixture, "cycle_error_paths") return {hello = A.hello} )"; - CheckResult result = frontend.check("game/Gui/Modules/A"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + CheckResult result = frontend.check(XorStr("game/Gui/Modules/A")); + lluz_REQUIRE_ERROR_COUNT(2, result); auto ce1 = get(result.errors[0]); REQUIRE(ce1); - CHECK_EQ(result.errors[0].moduleName, "game/Gui/Modules/B"); + CHECK_EQ(result.errors[0].moduleName, XorStr("game/Gui/Modules/B")); REQUIRE_EQ(ce1->cycle.size(), 2); - CHECK_EQ(ce1->cycle[0], "game/Gui/Modules/A"); - CHECK_EQ(ce1->cycle[1], "game/Gui/Modules/B"); + CHECK_EQ(ce1->cycle[0], XorStr("game/Gui/Modules/A")); + CHECK_EQ(ce1->cycle[1], XorStr("game/Gui/Modules/B")); auto ce2 = get(result.errors[1]); REQUIRE(ce2); - CHECK_EQ(result.errors[1].moduleName, "game/Gui/Modules/A"); + CHECK_EQ(result.errors[1].moduleName, XorStr("game/Gui/Modules/A")); REQUIRE_EQ(ce2->cycle.size(), 2); - CHECK_EQ(ce2->cycle[0], "game/Gui/Modules/B"); - CHECK_EQ(ce2->cycle[1], "game/Gui/Modules/A"); + CHECK_EQ(ce2->cycle[0], XorStr("game/Gui/Modules/B")); + CHECK_EQ(ce2->cycle[1], XorStr("game/Gui/Modules/A")); } TEST_CASE_FIXTURE(FrontendFixture, "cycle_incremental_type_surface") @@ -390,20 +390,20 @@ TEST_CASE_FIXTURE(FrontendFixture, "cycle_incremental_type_surface") return {hello = 2} )"; - CheckResult result = frontend.check("game/A"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = frontend.check(XorStr("game/A")); + lluz_REQUIRE_NO_ERRORS(result); fileResolver.source["game/A"] = R"( local me = require(game.A) return {hello = 2} )"; - frontend.markDirty("game/A"); + frontend.markDirty(XorStr("game/A")); - result = frontend.check("game/A"); - LUAU_REQUIRE_ERRORS(result); + result = frontend.check(XorStr("game/A")); + lluz_REQUIRE_ERRORS(result); - auto ty = requireType("game/A", "me"); - CHECK_EQ(toString(ty), "any"); + auto ty = requireType(XorStr("game/A", "me")); + CHECK_EQ(toString(ty), XorStr("any")); } TEST_CASE_FIXTURE(FrontendFixture, "cycle_incremental_type_surface_longer") @@ -412,36 +412,36 @@ TEST_CASE_FIXTURE(FrontendFixture, "cycle_incremental_type_surface_longer") return {mod_a = 2} )"; - CheckResult result = frontend.check("game/A"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = frontend.check(XorStr("game/A")); + lluz_REQUIRE_NO_ERRORS(result); fileResolver.source["game/B"] = R"( local me = require(game.A) return {mod_b = 4} )"; - result = frontend.check("game/B"); - LUAU_REQUIRE_NO_ERRORS(result); + result = frontend.check(XorStr("game/B")); + lluz_REQUIRE_NO_ERRORS(result); fileResolver.source["game/A"] = R"( local me = require(game.B) return {mod_a_prime = 3} )"; - frontend.markDirty("game/A"); - frontend.markDirty("game/B"); + frontend.markDirty(XorStr("game/A")); + frontend.markDirty(XorStr("game/B")); - result = frontend.check("game/A"); - LUAU_REQUIRE_ERRORS(result); + result = frontend.check(XorStr("game/A")); + lluz_REQUIRE_ERRORS(result); - TypeId tyA = requireType("game/A", "me"); - CHECK_EQ(toString(tyA), "any"); + TypeId tyA = requireType(XorStr("game/A", "me")); + CHECK_EQ(toString(tyA), XorStr("any")); - result = frontend.check("game/B"); - LUAU_REQUIRE_ERRORS(result); + result = frontend.check(XorStr("game/B")); + lluz_REQUIRE_ERRORS(result); - TypeId tyB = requireType("game/B", "me"); - CHECK_EQ(toString(tyB), "any"); + TypeId tyB = requireType(XorStr("game/B", "me")); + CHECK_EQ(toString(tyB), XorStr("any")); } TEST_CASE_FIXTURE(FrontendFixture, "dont_reparse_clean_file_when_linting") @@ -456,7 +456,7 @@ TEST_CASE_FIXTURE(FrontendFixture, "dont_reparse_clean_file_when_linting") end )"; - frontend.check("Modules/A"); + frontend.check(XorStr("Modules/A")); fileResolver.source["Modules/A"] = R"( -- We have fixed the lint error, but we did not tell the Frontend that the file is changed! @@ -465,7 +465,7 @@ TEST_CASE_FIXTURE(FrontendFixture, "dont_reparse_clean_file_when_linting") configResolver.defaultConfig.enabledLint.enableWarning(LintWarning::Code_ForRange); - LintResult lintResult = frontend.lint("Modules/A"); + LintResult lintResult = frontend.lint(XorStr("Modules/A")); CHECK_EQ(1, lintResult.warnings.size()); } @@ -479,16 +479,16 @@ TEST_CASE_FIXTURE(FrontendFixture, "dont_recheck_script_that_hasnt_been_marked_d return {b_value = A.hello} )"; - frontend.check("game/Gui/Modules/B"); + frontend.check(XorStr("game/Gui/Modules/B")); fileResolver.source["game/Gui/Modules/A"] = "Massively incorrect syntax haha oops! However! The frontend doesn't know that this file needs reparsing!"; - frontend.check("game/Gui/Modules/B"); + frontend.check(XorStr("game/Gui/Modules/B")); ModulePtr bModule = frontend.moduleResolver.modules["game/Gui/Modules/B"]; CHECK(bModule->errors.empty()); - Luau::dumpErrors(bModule); + lluz::dumpErrors(bModule); } TEST_CASE_FIXTURE(FrontendFixture, "recheck_if_dependent_script_is_dirty") @@ -500,16 +500,16 @@ TEST_CASE_FIXTURE(FrontendFixture, "recheck_if_dependent_script_is_dirty") return {b_value = A.hello} )"; - frontend.check("game/Gui/Modules/B"); + frontend.check(XorStr("game/Gui/Modules/B")); fileResolver.source["game/Gui/Modules/A"] = "return {hello='hi!'}"; - frontend.markDirty("game/Gui/Modules/A"); + frontend.markDirty(XorStr("game/Gui/Modules/A")); - frontend.check("game/Gui/Modules/B"); + frontend.check(XorStr("game/Gui/Modules/B")); ModulePtr bModule = frontend.moduleResolver.modules["game/Gui/Modules/B"]; CHECK(bModule->errors.empty()); - Luau::dumpErrors(bModule); + lluz::dumpErrors(bModule); auto bExports = first(bModule->getModuleScope()->returnType); REQUIRE(!!bExports); @@ -528,12 +528,12 @@ TEST_CASE_FIXTURE(FrontendFixture, "recheck_if_dependent_script_has_a_parse_erro return {} )"; - CheckResult result = frontend.check("Modules/B"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = frontend.check(XorStr("Modules/B")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Modules/A", result.errors[0].moduleName); - CheckResult result2 = frontend.check("Modules/B"); - LUAU_REQUIRE_ERROR_COUNT(1, result2); + CheckResult result2 = frontend.check(XorStr("Modules/B")); + lluz_REQUIRE_ERROR_COUNT(1, result2); CHECK_EQ(result2.errors[0], result.errors[0]); } #endif @@ -542,8 +542,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "produce_errors_for_unchanged_file_with_a_syn { fileResolver.source["Modules/A"] = "oh no a blatant syntax error!!"; - CheckResult one = frontend.check("Modules/A"); - CheckResult two = frontend.check("Modules/A"); + CheckResult one = frontend.check(XorStr("Modules/A")); + CheckResult two = frontend.check(XorStr("Modules/A")); CHECK(!one.errors.empty()); CHECK(!two.errors.empty()); @@ -553,10 +553,10 @@ TEST_CASE_FIXTURE(FrontendFixture, "produce_errors_for_unchanged_file_with_error { fileResolver.source["Modules/A"] = "local p: number = 'oh no a type error'"; - frontend.check("Modules/A"); + frontend.check(XorStr("Modules/A")); fileResolver.source["Modules/A"] = "local p = 4 -- We have fixed the problem, but we didn't tell the frontend, so it will not recheck this file!"; - CheckResult secondResult = frontend.check("Modules/A"); + CheckResult secondResult = frontend.check(XorStr("Modules/A")); CHECK_EQ(1, secondResult.errors.size()); } @@ -574,8 +574,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "reports_errors_from_multiple_sources") local b: number = 'another one! This is quite distressing!' )"; - CheckResult result = frontend.check("game/Gui/Modules/B"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + CheckResult result = frontend.check(XorStr("game/Gui/Modules/B")); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ("game/Gui/Modules/A", result.errors[0].moduleName); CHECK_EQ("game/Gui/Modules/B", result.errors[1].moduleName); @@ -588,8 +588,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "report_require_to_nonexistent_file") local B = require(Modules.B) )"; - CheckResult result = frontend.check("Modules/A"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = frontend.check(XorStr("Modules/A")); + lluz_REQUIRE_ERROR_COUNT(1, result); std::string s = toString(result.errors[0]); CHECK_MESSAGE(get(result.errors[0]), "Should have been an UnknownRequire: " << toString(result.errors[0])); @@ -602,8 +602,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "ignore_require_to_nonexistent_file") local B = require(Modules.B) :: any )"; - CheckResult result = frontend.check("Modules/A"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = frontend.check(XorStr("Modules/A")); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(FrontendFixture, "report_syntax_error_in_required_file") @@ -614,8 +614,8 @@ TEST_CASE_FIXTURE(FrontendFixture, "report_syntax_error_in_required_file") local A = require(Modules.A) )"; - CheckResult result = frontend.check("Modules/B"); - LUAU_REQUIRE_ERRORS(result); + CheckResult result = frontend.check(XorStr("Modules/B")); + lluz_REQUIRE_ERRORS(result); CHECK_EQ("Modules/A", result.errors[0].moduleName); @@ -624,7 +624,7 @@ TEST_CASE_FIXTURE(FrontendFixture, "report_syntax_error_in_required_file") }); if (!b) { - CHECK_MESSAGE(false, "Expected a syntax error!"); + CHECK_MESSAGE(false, XorStr("Expected a syntax error!")); dumpErrors(result); } } @@ -642,11 +642,11 @@ TEST_CASE_FIXTURE(FrontendFixture, "re_report_type_error_in_required_file") print(A.n) )"; - CheckResult result = frontend.check("Modules/B"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = frontend.check(XorStr("Modules/B")); + lluz_REQUIRE_ERROR_COUNT(1, result); - CheckResult result2 = frontend.check("Modules/B"); - LUAU_REQUIRE_ERROR_COUNT(1, result2); + CheckResult result2 = frontend.check(XorStr("Modules/B")); + lluz_REQUIRE_ERROR_COUNT(1, result2); CHECK_EQ("Modules/A", result.errors[0].moduleName); } @@ -665,16 +665,16 @@ TEST_CASE_FIXTURE(FrontendFixture, "accumulate_cached_errors") print(A, b) )"; - CheckResult result1 = frontend.check("Modules/B"); + CheckResult result1 = frontend.check(XorStr("Modules/B")); - LUAU_REQUIRE_ERROR_COUNT(2, result1); + lluz_REQUIRE_ERROR_COUNT(2, result1); CHECK_EQ("Modules/A", result1.errors[0].moduleName); CHECK_EQ("Modules/B", result1.errors[1].moduleName); - CheckResult result2 = frontend.check("Modules/B"); + CheckResult result2 = frontend.check(XorStr("Modules/B")); - LUAU_REQUIRE_ERROR_COUNT(2, result2); + lluz_REQUIRE_ERROR_COUNT(2, result2); CHECK_EQ("Modules/A", result2.errors[0].moduleName); CHECK_EQ("Modules/B", result2.errors[1].moduleName); @@ -695,9 +695,9 @@ TEST_CASE_FIXTURE(FrontendFixture, "accumulate_cached_errors_in_consistent_order return {} )"; - CheckResult result1 = frontend.check("Modules/A"); + CheckResult result1 = frontend.check(XorStr("Modules/A")); - LUAU_REQUIRE_ERROR_COUNT(4, result1); + lluz_REQUIRE_ERROR_COUNT(4, result1); CHECK_EQ("Modules/A", result1.errors[2].moduleName); CHECK_EQ("Modules/A", result1.errors[3].moduleName); @@ -705,7 +705,7 @@ TEST_CASE_FIXTURE(FrontendFixture, "accumulate_cached_errors_in_consistent_order CHECK_EQ("Modules/B", result1.errors[0].moduleName); CHECK_EQ("Modules/B", result1.errors[1].moduleName); - CheckResult result2 = frontend.check("Modules/A"); + CheckResult result2 = frontend.check(XorStr("Modules/A")); CHECK_EQ(4, result2.errors.size()); for (size_t i = 0; i < result1.errors.size(); ++i) @@ -737,12 +737,12 @@ TEST_CASE_FIXTURE(FrontendFixture, "test_lint_uses_correct_config") configResolver.configFiles["Module/A"].enabledLint.enableWarning(LintWarning::Code_ForRange); - auto result = frontend.lint("Module/A"); + auto result = frontend.lint(XorStr("Module/A")); CHECK_EQ(1, result.warnings.size()); configResolver.configFiles["Module/A"].enabledLint.disableWarning(LintWarning::Code_ForRange); - auto result2 = frontend.lint("Module/A"); + auto result2 = frontend.lint(XorStr("Module/A")); CHECK_EQ(0, result2.warnings.size()); LintOptions overrideOptions; @@ -756,6 +756,26 @@ TEST_CASE_FIXTURE(FrontendFixture, "test_lint_uses_correct_config") CHECK_EQ(0, result4.warnings.size()); } +TEST_CASE_FIXTURE(FrontendFixture, "lintFragment") +{ + LintOptions lintOptions; + lintOptions.enableWarning(LintWarning::Code_ForRange); + + auto [_sourceModule, result] = frontend.lintFragment(R"( + local t = {} + + for i=#t,1 do + end + + for i=#t,1,-1 do + end + )", + lintOptions); + + CHECK_EQ(1, result.warnings.size()); + CHECK_EQ(0, result.errors.size()); +} + TEST_CASE_FIXTURE(FrontendFixture, "discard_type_graphs") { Frontend fe{&fileResolver, &configResolver, {false}}; @@ -764,9 +784,9 @@ TEST_CASE_FIXTURE(FrontendFixture, "discard_type_graphs") local a = {1,2,3,4,5} )"; - CheckResult result = fe.check("Module/A"); + CheckResult result = fe.check(XorStr("Module/A")); - ModulePtr module = fe.moduleResolver.getModule("Module/A"); + ModulePtr module = fe.moduleResolver.getModule(XorStr("Module/A")); CHECK_EQ(0, module->internalTypes.typeVars.size()); CHECK_EQ(0, module->internalTypes.typePacks.size()); @@ -784,7 +804,7 @@ TEST_CASE_FIXTURE(FrontendFixture, "it_should_be_safe_to_stringify_errors_when_f local a: {Count: number} = {count='five'} )"; - CheckResult result = fe.check("Module/A"); + CheckResult result = fe.check(XorStr("Module/A")); REQUIRE_EQ(1, result.errors.size()); @@ -817,9 +837,9 @@ TEST_CASE_FIXTURE(FrontendFixture, "trace_requires_in_nonstrict_mode") print(A.f(5)) -- OK )"; - CheckResult result = frontend.check("Module/B"); + CheckResult result = frontend.check(XorStr("Module/B")); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ(4, result.errors[0].location.begin.line); CHECK_EQ(5, result.errors[1].location.begin.line); @@ -827,13 +847,13 @@ TEST_CASE_FIXTURE(FrontendFixture, "trace_requires_in_nonstrict_mode") TEST_CASE_FIXTURE(FrontendFixture, "environments") { - ScopePtr testScope = frontend.addEnvironment("test"); + ScopePtr testScope = frontend.addEnvironment(XorStr("test")); unfreeze(typeChecker.globalTypes); loadDefinitionFile(typeChecker, testScope, R"( export type Foo = number | string )", - "@test"); + XorStr("@test")); freeze(typeChecker.globalTypes); fileResolver.source["A"] = R"( @@ -848,11 +868,11 @@ TEST_CASE_FIXTURE(FrontendFixture, "environments") fileResolver.environments["A"] = "test"; - CheckResult resultA = frontend.check("A"); - LUAU_REQUIRE_NO_ERRORS(resultA); + CheckResult resultA = frontend.check(XorStr("A")); + lluz_REQUIRE_NO_ERRORS(resultA); - CheckResult resultB = frontend.check("B"); - LUAU_REQUIRE_ERROR_COUNT(1, resultB); + CheckResult resultB = frontend.check(XorStr("B")); + lluz_REQUIRE_ERROR_COUNT(1, resultB); } TEST_CASE_FIXTURE(FrontendFixture, "ast_node_at_position") @@ -890,17 +910,17 @@ TEST_CASE_FIXTURE(FrontendFixture, "stats_are_not_reset_between_checks") return {foo = 1} )"; - CheckResult r1 = frontend.check("Module/A"); - LUAU_REQUIRE_NO_ERRORS(r1); + CheckResult r1 = frontend.check(XorStr("Module/A")); + lluz_REQUIRE_NO_ERRORS(r1); Frontend::Stats stats1 = frontend.stats; CHECK_EQ(2, stats1.files); - frontend.markDirty("Module/A"); - frontend.markDirty("Module/B"); + frontend.markDirty(XorStr("Module/A")); + frontend.markDirty(XorStr("Module/B")); - CheckResult r2 = frontend.check("Module/A"); - LUAU_REQUIRE_NO_ERRORS(r2); + CheckResult r2 = frontend.check(XorStr("Module/A")); + lluz_REQUIRE_NO_ERRORS(r2); Frontend::Stats stats2 = frontend.stats; CHECK_EQ(4, stats2.files); @@ -919,18 +939,18 @@ TEST_CASE_FIXTURE(FrontendFixture, "clearStats") return {foo = 1} )"; - CheckResult r1 = frontend.check("Module/A"); - LUAU_REQUIRE_NO_ERRORS(r1); + CheckResult r1 = frontend.check(XorStr("Module/A")); + lluz_REQUIRE_NO_ERRORS(r1); Frontend::Stats stats1 = frontend.stats; CHECK_EQ(2, stats1.files); - frontend.markDirty("Module/A"); - frontend.markDirty("Module/B"); + frontend.markDirty(XorStr("Module/A")); + frontend.markDirty(XorStr("Module/B")); frontend.clearStats(); - CheckResult r2 = frontend.check("Module/A"); - LUAU_REQUIRE_NO_ERRORS(r2); + CheckResult r2 = frontend.check(XorStr("Module/A")); + lluz_REQUIRE_NO_ERRORS(r2); Frontend::Stats stats2 = frontend.stats; CHECK_EQ(2, stats2.files); @@ -942,13 +962,13 @@ TEST_CASE_FIXTURE(FrontendFixture, "typecheck_twice_for_ast_types") local a = 1 )"; - CheckResult result = frontend.check("Module/A"); + CheckResult result = frontend.check(XorStr("Module/A")); - ModulePtr module = frontend.moduleResolver.getModule("Module/A"); + ModulePtr module = frontend.moduleResolver.getModule(XorStr("Module/A")); REQUIRE_EQ(module->astTypes.size(), 1); auto it = module->astTypes.begin(); - CHECK_EQ(toString(it->second), "number"); + CHECK_EQ(toString(it->second), XorStr("number")); } TEST_CASE_FIXTURE(FrontendFixture, "imported_table_modification_2") @@ -977,14 +997,14 @@ local b = require(script.Parent.B) a:b() -- this should error, since A doesn't define a:b() )"; - CheckResult resultA = frontend.check("Module/A"); - LUAU_REQUIRE_NO_ERRORS(resultA); + CheckResult resultA = frontend.check(XorStr("Module/A")); + lluz_REQUIRE_NO_ERRORS(resultA); - CheckResult resultB = frontend.check("Module/B"); - LUAU_REQUIRE_ERRORS(resultB); + CheckResult resultB = frontend.check(XorStr("Module/B")); + lluz_REQUIRE_ERRORS(resultB); - CheckResult resultC = frontend.check("Module/C"); - LUAU_REQUIRE_ERRORS(resultC); + CheckResult resultC = frontend.check(XorStr("Module/C")); + lluz_REQUIRE_ERRORS(resultC); } // This test does not use TEST_CASE_FIXTURE because we need to set a flag before @@ -992,7 +1012,7 @@ a:b() -- this should error, since A doesn't define a:b() TEST_CASE("no_use_after_free_with_type_fun_instantiation") { // This flag forces this test to crash if there's a UAF in this code. - ScopedFastFlag sff_DebugLuauFreezeArena("DebugLuauFreezeArena", true); + ScopedFastFlag sff_DebuglluzFreezeArena("DebuglluzFreezeArena", true); FrontendFixture fix; @@ -1008,7 +1028,7 @@ return false; )"; // We don't care about the result. That we haven't crashed is enough. - fix.frontend.check("Module/B"); + fix.frontend.check(XorStr("Module/B")); } TEST_CASE("check_without_builtin_next") @@ -1021,77 +1041,8 @@ TEST_CASE("check_without_builtin_next") fileResolver.source["Module/B"] = "return next"; // We don't care about the result. That we haven't crashed is enough. - frontend.check("Module/A"); - frontend.check("Module/B"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "reexport_cyclic_type") -{ - ScopedFastFlag sff[] = { - {"LuauForceExportSurfacesToBeNormal", true}, - {"LuauLowerBoundsCalculation", true}, - {"LuauNormalizeFlagIsConservative", true}, - }; - - fileResolver.source["Module/A"] = R"( - type F = (set: G) -> () - - export type G = { - forEach: (a: F) -> (), - } - - function X(a: F): () - end - - return X - )"; - - fileResolver.source["Module/B"] = R"( - --!strict - local A = require(script.Parent.A) - - export type G = A.G - - return { - A = A, - } - )"; - - CheckResult result = frontend.check("Module/B"); - - LUAU_REQUIRE_NO_ERRORS(result); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "reexport_type_alias") -{ - ScopedFastFlag sff[] = { - {"LuauForceExportSurfacesToBeNormal", true}, - {"LuauLowerBoundsCalculation", true}, - {"LuauNormalizeFlagIsConservative", true}, - }; - - fileResolver.source["Module/A"] = R"( - type KeyOfTestEvents = "test-file-start" | "test-file-success" | "test-file-failure" | "test-case-result" - type unknown = any - - export type TestFileEvent = ( - eventName: T, - args: any --[[ ROBLOX TODO: Unhandled node for type: TSIndexedAccessType ]] --[[ TestEvents[T] ]] - ) -> unknown - - return {} - )"; - - fileResolver.source["Module/B"] = R"( - --!strict - local A = require(script.Parent.A) - - export type TestFileEvent = A.TestFileEvent - )"; - - CheckResult result = frontend.check("Module/B"); - - LUAU_REQUIRE_NO_ERRORS(result); + frontend.check(XorStr("Module/A")); + frontend.check(XorStr("Module/B")); } TEST_SUITE_END(); diff --git a/tests/IostreamOptional.h b/tests/IostreamOptional.h index e0756bad..be6d24a8 100644 --- a/tests/IostreamOptional.h +++ b/tests/IostreamOptional.h @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #pragma once #include diff --git a/tests/JsonEncoder.test.cpp b/tests/JsonEncoder.test.cpp index b16ad3e2..24e59ee9 100644 --- a/tests/JsonEncoder.test.cpp +++ b/tests/JsonEncoder.test.cpp @@ -1,13 +1,13 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Ast.h" -#include "Luau/JsonEncoder.h" -#include "Luau/Parser.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Ast.h" +#include "lluz/JsonEncoder.h" +#include "lluz/Parser.h" #include "doctest.h" #include -using namespace Luau; +using namespace lluz; struct JsonEncoderFixture { @@ -49,26 +49,17 @@ struct JsonEncoderFixture } }; -TEST_SUITE_BEGIN("JsonEncoderTests"); +TEST_SUITE_BEGIN(XorStr("JsonEncoderTests")); TEST_CASE("encode_constants") { AstExprConstantNil nil{Location()}; AstExprConstantBool b{Location(), true}; AstExprConstantNumber n{Location(), 8.2}; - AstExprConstantNumber bigNum{Location(), 0.1677721600000003}; - - AstArray charString; - charString.data = const_cast("a\x1d\0\\\"b"); - charString.size = 6; - - AstExprConstantString needsEscaping{Location(), charString}; CHECK_EQ(R"({"type":"AstExprConstantNil","location":"0,0 - 0,0"})", toJson(&nil)); CHECK_EQ(R"({"type":"AstExprConstantBool","location":"0,0 - 0,0","value":true})", toJson(&b)); - CHECK_EQ(R"({"type":"AstExprConstantNumber","location":"0,0 - 0,0","value":8.1999999999999993})", toJson(&n)); - CHECK_EQ(R"({"type":"AstExprConstantNumber","location":"0,0 - 0,0","value":0.16777216000000031})", toJson(&bigNum)); - CHECK_EQ("{\"type\":\"AstExprConstantString\",\"location\":\"0,0 - 0,0\",\"value\":\"a\\u001d\\u0000\\\\\\\"b\"}", toJson(&needsEscaping)); + CHECK_EQ(R"({"type":"AstExprConstantNumber","location":"0,0 - 0,0","value":8.2})", toJson(&n)); } TEST_CASE("basic_escaping") @@ -96,7 +87,7 @@ TEST_CASE("encode_AstStatBlock") AstStatBlock block{Location(), bodyArray}; CHECK_EQ( - (R"({"type":"AstStatBlock","location":"0,0 - 0,0","body":[{"type":"AstStatLocal","location":"0,0 - 0,0","vars":[{"luauType":null,"name":"a_local","type":"AstLocal","location":"0,0 - 0,0"}],"values":[]}]})"), + (R"({"type":"AstStatBlock","location":"0,0 - 0,0","body":[{"type":"AstStatLocal","location":"0,0 - 0,0","vars":[{"type":null,"name":"a_local","location":"0,0 - 0,0"}],"values":[]}]})"), toJson(&block)); } @@ -115,31 +106,7 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_tables") CHECK( json == - R"({"type":"AstStatBlock","location":"0,0 - 6,4","body":[{"type":"AstStatLocal","location":"1,8 - 5,9","vars":[{"luauType":{"type":"AstTypeTable","location":"1,17 - 3,9","props":[{"name":"foo","type":"AstTableProp","location":"2,12 - 2,15","propType":{"type":"AstTypeReference","location":"2,17 - 2,23","name":"number","parameters":[]}}],"indexer":null},"name":"x","type":"AstLocal","location":"1,14 - 1,15"}],"values":[{"type":"AstExprTable","location":"3,12 - 5,9","items":[{"type":"AstExprTableItem","kind":"record","key":{"type":"AstExprConstantString","location":"4,12 - 4,15","value":"foo"},"value":{"type":"AstExprConstantNumber","location":"4,18 - 4,21","value":123}}]}]}]})"); -} - -TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_table_array") -{ - std::string src = R"(type X = {string})"; - - AstStatBlock* root = expectParse(src); - std::string json = toJson(root); - - CHECK( - json == - R"({"type":"AstStatBlock","location":"0,0 - 0,17","body":[{"type":"AstStatTypeAlias","location":"0,0 - 0,17","name":"X","generics":[],"genericPacks":[],"type":{"type":"AstTypeTable","location":"0,9 - 0,17","props":[],"indexer":{"location":"0,10 - 0,16","indexType":{"type":"AstTypeReference","location":"0,10 - 0,16","name":"number","parameters":[]},"resultType":{"type":"AstTypeReference","location":"0,10 - 0,16","name":"string","parameters":[]}}},"exported":false}]})"); -} - -TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_table_indexer") -{ - std::string src = R"(type X = {string})"; - - AstStatBlock* root = expectParse(src); - std::string json = toJson(root); - - CHECK( - json == - R"({"type":"AstStatBlock","location":"0,0 - 0,17","body":[{"type":"AstStatTypeAlias","location":"0,0 - 0,17","name":"X","generics":[],"genericPacks":[],"type":{"type":"AstTypeTable","location":"0,9 - 0,17","props":[],"indexer":{"location":"0,10 - 0,16","indexType":{"type":"AstTypeReference","location":"0,10 - 0,16","name":"number","parameters":[]},"resultType":{"type":"AstTypeReference","location":"0,10 - 0,16","name":"string","parameters":[]}}},"exported":false}]})"); + RXorStr("({"type":"AstStatBlock","location":"0,0 - 6,4","body":[{"type":"AstStatLocal","location":"1,8 - 5,9","vars":[{"type":{"type":"AstTypeTable","location":"1,17 - 3,9","props":[{"name":"foo","location":"2,12 - 2,15","type":{"type":"AstTypeReference","location":"2,17 - 2,23","name":"number","parameters":[]}}],"indexer":false},"name":"x","location":"1,14 - 1,15"}],"values":[{"type":"AstExprTable","location":"3,12 - 5,9","items":[{"kind":"record","key":{"type":"AstExprConstantString","location":"4,12 - 4,15","value":"foo"},"value":{"type":"AstExprConstantNumber","location":"4,18 - 4,21","value":123}}]}]}]})")); } TEST_CASE("encode_AstExprGroup") @@ -165,35 +132,24 @@ TEST_CASE("encode_AstExprGlobal") CHECK(json == expected); } -TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprIfThen") -{ - AstStat* statement = expectParseStatement("local a = if x then y else z"); - - std::string_view expected = - R"({"type":"AstStatLocal","location":"0,0 - 0,28","vars":[{"luauType":null,"name":"a","type":"AstLocal","location":"0,6 - 0,7"}],"values":[{"type":"AstExprIfElse","location":"0,10 - 0,28","condition":{"type":"AstExprGlobal","location":"0,13 - 0,14","global":"x"},"hasThen":true,"trueExpr":{"type":"AstExprGlobal","location":"0,20 - 0,21","global":"y"},"hasElse":true,"falseExpr":{"type":"AstExprGlobal","location":"0,27 - 0,28","global":"z"}}]})"; - - CHECK(toJson(statement) == expected); -} - - TEST_CASE("encode_AstExprLocal") { AstLocal local{AstName{"foo"}, Location{}, nullptr, 0, 0, nullptr}; AstExprLocal exprLocal{Location{}, &local, false}; - CHECK(toJson(&exprLocal) == R"({"type":"AstExprLocal","location":"0,0 - 0,0","local":{"luauType":null,"name":"foo","type":"AstLocal","location":"0,0 - 0,0"}})"); + CHECK(toJson(&exprLocal) == RXorStr("({"type":"AstExprLocal","location":"0,0 - 0,0","local":{"type":null,"name":"foo","location":"0,0 - 0,0"}})")); } TEST_CASE("encode_AstExprVarargs") { AstExprVarargs varargs{Location{}}; - CHECK(toJson(&varargs) == R"({"type":"AstExprVarargs","location":"0,0 - 0,0"})"); + CHECK(toJson(&varargs) == RXorStr("({"type":"AstExprVarargs","location":"0,0 - 0,0"})")); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprCall") { - AstExpr* expr = expectParseExpr("foo(1, 2, 3)"); + AstExpr* expr = expectParseExpr(XorStr("foo(1, 2, 3)")); std::string_view expected = R"({"type":"AstExprCall","location":"0,4 - 0,16","func":{"type":"AstExprGlobal","location":"0,4 - 0,7","global":"foo"},"args":[{"type":"AstExprConstantNumber","location":"0,8 - 0,9","value":1},{"type":"AstExprConstantNumber","location":"0,11 - 0,12","value":2},{"type":"AstExprConstantNumber","location":"0,14 - 0,15","value":3}],"self":false,"argLocation":"0,8 - 0,16"})"; @@ -202,7 +158,7 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprCall") TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprIndexName") { - AstExpr* expr = expectParseExpr("foo.bar"); + AstExpr* expr = expectParseExpr(XorStr("foo.bar")); std::string_view expected = R"({"type":"AstExprIndexName","location":"0,4 - 0,11","expr":{"type":"AstExprGlobal","location":"0,4 - 0,7","global":"foo"},"index":"bar","indexLocation":"0,8 - 0,11","op":"."})"; @@ -212,7 +168,7 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprIndexName") TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprIndexExpr") { - AstExpr* expr = expectParseExpr("foo['bar']"); + AstExpr* expr = expectParseExpr(XorStr("foo['bar']")); std::string_view expected = R"({"type":"AstExprIndexExpr","location":"0,4 - 0,14","expr":{"type":"AstExprGlobal","location":"0,4 - 0,7","global":"foo"},"index":{"type":"AstExprConstantString","location":"0,8 - 0,13","value":"bar"}})"; @@ -222,37 +178,37 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprIndexExpr") TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprFunction") { - AstExpr* expr = expectParseExpr("function (a) return a end"); + AstExpr* expr = expectParseExpr(XorStr("function (a) return a end")); std::string_view expected = - R"({"type":"AstExprFunction","location":"0,4 - 0,29","generics":[],"genericPacks":[],"args":[{"luauType":null,"name":"a","type":"AstLocal","location":"0,14 - 0,15"}],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"0,16 - 0,26","body":[{"type":"AstStatReturn","location":"0,17 - 0,25","list":[{"type":"AstExprLocal","location":"0,24 - 0,25","local":{"luauType":null,"name":"a","type":"AstLocal","location":"0,14 - 0,15"}}]}]},"functionDepth":1,"debugname":"","hasEnd":true})"; + R"({"type":"AstExprFunction","location":"0,4 - 0,29","generics":[],"genericPacks":[],"args":[{"type":null,"name":"a","location":"0,14 - 0,15"}],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"0,16 - 0,26","body":[{"type":"AstStatReturn","location":"0,17 - 0,25","list":[{"type":"AstExprLocal","location":"0,24 - 0,25","local":{"type":null,"name":"a","location":"0,14 - 0,15"}}]}]},"functionDepth":1,"debugname":"","hasEnd":true})"; CHECK(toJson(expr) == expected); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprTable") { - AstExpr* expr = expectParseExpr("{true, key=true, [key2]=true}"); + AstExpr* expr = expectParseExpr(XorStr("{true, key=true, [key2]=true}")); std::string_view expected = - R"({"type":"AstExprTable","location":"0,4 - 0,33","items":[{"type":"AstExprTableItem","kind":"item","value":{"type":"AstExprConstantBool","location":"0,5 - 0,9","value":true}},{"type":"AstExprTableItem","kind":"record","key":{"type":"AstExprConstantString","location":"0,11 - 0,14","value":"key"},"value":{"type":"AstExprConstantBool","location":"0,15 - 0,19","value":true}},{"type":"AstExprTableItem","kind":"general","key":{"type":"AstExprGlobal","location":"0,22 - 0,26","global":"key2"},"value":{"type":"AstExprConstantBool","location":"0,28 - 0,32","value":true}}]})"; + R"({"type":"AstExprTable","location":"0,4 - 0,33","items":[{"kind":"item","value":{"type":"AstExprConstantBool","location":"0,5 - 0,9","value":true}},{"kind":"record","key":{"type":"AstExprConstantString","location":"0,11 - 0,14","value":"key"},"value":{"type":"AstExprConstantBool","location":"0,15 - 0,19","value":true}},{"kind":"general","key":{"type":"AstExprGlobal","location":"0,22 - 0,26","global":"key2"},"value":{"type":"AstExprConstantBool","location":"0,28 - 0,32","value":true}}]})"; CHECK(toJson(expr) == expected); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprUnary") { - AstExpr* expr = expectParseExpr("-b"); + AstExpr* expr = expectParseExpr(XorStr("-b")); std::string_view expected = - R"({"type":"AstExprUnary","location":"0,4 - 0,6","op":"Minus","expr":{"type":"AstExprGlobal","location":"0,5 - 0,6","global":"b"}})"; + R"({"type":"AstExprUnary","location":"0,4 - 0,6","op":"minus","expr":{"type":"AstExprGlobal","location":"0,5 - 0,6","global":"b"}})"; CHECK(toJson(expr) == expected); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprBinary") { - AstExpr* expr = expectParseExpr("b + c"); + AstExpr* expr = expectParseExpr(XorStr("b + c")); std::string_view expected = R"({"type":"AstExprBinary","location":"0,4 - 0,9","op":"Add","left":{"type":"AstExprGlobal","location":"0,4 - 0,5","global":"b"},"right":{"type":"AstExprGlobal","location":"0,8 - 0,9","global":"c"}})"; @@ -262,7 +218,7 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprBinary") TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprTypeAssertion") { - AstExpr* expr = expectParseExpr("b :: any"); + AstExpr* expr = expectParseExpr(XorStr("b :: any")); std::string_view expected = R"({"type":"AstExprTypeAssertion","location":"0,4 - 0,12","expr":{"type":"AstExprGlobal","location":"0,4 - 0,5","global":"b"},"annotation":{"type":"AstTypeReference","location":"0,9 - 0,12","name":"any","parameters":[]}})"; @@ -290,7 +246,7 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprError") TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatIf") { - AstStat* statement = expectParseStatement("if true then else end"); + AstStat* statement = expectParseStatement(XorStr("if true then else end")); std::string_view expected = R"({"type":"AstStatIf","location":"0,0 - 0,21","condition":{"type":"AstExprConstantBool","location":"0,3 - 0,7","value":true},"thenbody":{"type":"AstStatBlock","location":"0,12 - 0,13","body":[]},"elsebody":{"type":"AstStatBlock","location":"0,17 - 0,18","body":[]},"hasThen":true,"hasEnd":true})"; @@ -300,17 +256,17 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatIf") TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatWhile") { - AstStat* statement = expectParseStatement("while true do end"); + AstStat* statement = expectParseStatement(XorStr("while true do end")); std::string_view expected = - R"({"type":"AstStatWhile","location":"0,0 - 0,17","condition":{"type":"AstExprConstantBool","location":"0,6 - 0,10","value":true},"body":{"type":"AstStatBlock","location":"0,13 - 0,14","body":[]},"hasDo":true,"hasEnd":true})"; + R"({"type":"AtStatWhile","location":"0,0 - 0,17","condition":{"type":"AstExprConstantBool","location":"0,6 - 0,10","value":true},"body":{"type":"AstStatBlock","location":"0,13 - 0,14","body":[]},"hasDo":true,"hasEnd":true})"; CHECK(toJson(statement) == expected); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatRepeat") { - AstStat* statement = expectParseStatement("repeat until true"); + AstStat* statement = expectParseStatement(XorStr("repeat until true")); std::string_view expected = R"({"type":"AstStatRepeat","location":"0,0 - 0,17","condition":{"type":"AstExprConstantBool","location":"0,13 - 0,17","value":true},"body":{"type":"AstStatBlock","location":"0,6 - 0,7","body":[]},"hasUntil":true})"; @@ -320,47 +276,47 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatRepeat") TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatBreak") { - AstStat* statement = expectParseStatement("while true do break end"); + AstStat* statement = expectParseStatement(XorStr("while true do break end")); std::string_view expected = - R"({"type":"AstStatWhile","location":"0,0 - 0,23","condition":{"type":"AstExprConstantBool","location":"0,6 - 0,10","value":true},"body":{"type":"AstStatBlock","location":"0,13 - 0,20","body":[{"type":"AstStatBreak","location":"0,14 - 0,19"}]},"hasDo":true,"hasEnd":true})"; + R"({"type":"AtStatWhile","location":"0,0 - 0,23","condition":{"type":"AstExprConstantBool","location":"0,6 - 0,10","value":true},"body":{"type":"AstStatBlock","location":"0,13 - 0,20","body":[{"type":"AstStatBreak","location":"0,14 - 0,19"}]},"hasDo":true,"hasEnd":true})"; CHECK(toJson(statement) == expected); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatContinue") { - AstStat* statement = expectParseStatement("while true do continue end"); + AstStat* statement = expectParseStatement(XorStr("while true do continue end")); std::string_view expected = - R"({"type":"AstStatWhile","location":"0,0 - 0,26","condition":{"type":"AstExprConstantBool","location":"0,6 - 0,10","value":true},"body":{"type":"AstStatBlock","location":"0,13 - 0,23","body":[{"type":"AstStatContinue","location":"0,14 - 0,22"}]},"hasDo":true,"hasEnd":true})"; + R"({"type":"AtStatWhile","location":"0,0 - 0,26","condition":{"type":"AstExprConstantBool","location":"0,6 - 0,10","value":true},"body":{"type":"AstStatBlock","location":"0,13 - 0,23","body":[{"type":"AstStatContinue","location":"0,14 - 0,22"}]},"hasDo":true,"hasEnd":true})"; CHECK(toJson(statement) == expected); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatFor") { - AstStat* statement = expectParseStatement("for a=0,1 do end"); + AstStat* statement = expectParseStatement(XorStr("for a=0,1 do end")); std::string_view expected = - R"({"type":"AstStatFor","location":"0,0 - 0,16","var":{"luauType":null,"name":"a","type":"AstLocal","location":"0,4 - 0,5"},"from":{"type":"AstExprConstantNumber","location":"0,6 - 0,7","value":0},"to":{"type":"AstExprConstantNumber","location":"0,8 - 0,9","value":1},"body":{"type":"AstStatBlock","location":"0,12 - 0,13","body":[]},"hasDo":true,"hasEnd":true})"; + R"({"type":"AstStatFor","location":"0,0 - 0,16","var":{"type":null,"name":"a","location":"0,4 - 0,5"},"from":{"type":"AstExprConstantNumber","location":"0,6 - 0,7","value":0},"to":{"type":"AstExprConstantNumber","location":"0,8 - 0,9","value":1},"body":{"type":"AstStatBlock","location":"0,12 - 0,13","body":[]},"hasDo":true,"hasEnd":true})"; CHECK(toJson(statement) == expected); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatForIn") { - AstStat* statement = expectParseStatement("for a in b do end"); + AstStat* statement = expectParseStatement(XorStr("for a in b do end")); std::string_view expected = - R"({"type":"AstStatForIn","location":"0,0 - 0,17","vars":[{"luauType":null,"name":"a","type":"AstLocal","location":"0,4 - 0,5"}],"values":[{"type":"AstExprGlobal","location":"0,9 - 0,10","global":"b"}],"body":{"type":"AstStatBlock","location":"0,13 - 0,14","body":[]},"hasIn":true,"hasDo":true,"hasEnd":true})"; + R"({"type":"AstStatForIn","location":"0,0 - 0,17","vars":[{"type":null,"name":"a","location":"0,4 - 0,5"}],"values":[{"type":"AstExprGlobal","location":"0,9 - 0,10","global":"b"}],"body":{"type":"AstStatBlock","location":"0,13 - 0,14","body":[]},"hasIn":true,"hasDo":true,"hasEnd":true})"; CHECK(toJson(statement) == expected); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatCompoundAssign") { - AstStat* statement = expectParseStatement("a += b"); + AstStat* statement = expectParseStatement(XorStr("a += b")); std::string_view expected = R"({"type":"AstStatCompoundAssign","location":"0,0 - 0,6","op":"Add","var":{"type":"AstExprGlobal","location":"0,0 - 0,1","global":"a"},"value":{"type":"AstExprGlobal","location":"0,5 - 0,6","global":"b"}})"; @@ -370,17 +326,17 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatCompoundAssign") TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatLocalFunction") { - AstStat* statement = expectParseStatement("local function a(b) return end"); + AstStat* statement = expectParseStatement(XorStr("local function a(b) return end")); std::string_view expected = - R"({"type":"AstStatLocalFunction","location":"0,0 - 0,30","name":{"luauType":null,"name":"a","type":"AstLocal","location":"0,15 - 0,16"},"func":{"type":"AstExprFunction","location":"0,0 - 0,30","generics":[],"genericPacks":[],"args":[{"luauType":null,"name":"b","type":"AstLocal","location":"0,17 - 0,18"}],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"0,19 - 0,27","body":[{"type":"AstStatReturn","location":"0,20 - 0,26","list":[]}]},"functionDepth":1,"debugname":"a","hasEnd":true}})"; + R"({"type":"AstStatLocalFunction","location":"0,0 - 0,30","name":{"type":null,"name":"a","location":"0,15 - 0,16"},"func":{"type":"AstExprFunction","location":"0,0 - 0,30","generics":[],"genericPacks":[],"args":[{"type":null,"name":"b","location":"0,17 - 0,18"}],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"0,19 - 0,27","body":[{"type":"AstStatReturn","location":"0,20 - 0,26","list":[]}]},"functionDepth":1,"debugname":"a","hasEnd":true}})"; CHECK(toJson(statement) == expected); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatTypeAlias") { - AstStat* statement = expectParseStatement("type A = B"); + AstStat* statement = expectParseStatement(XorStr("type A = B")); std::string_view expected = R"({"type":"AstStatTypeAlias","location":"0,0 - 0,10","name":"A","generics":[],"genericPacks":[],"type":{"type":"AstTypeReference","location":"0,9 - 0,10","name":"B","parameters":[]},"exported":false})"; @@ -390,10 +346,10 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatTypeAlias") TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatDeclareFunction") { - AstStat* statement = expectParseStatement("declare function foo(x: number): string"); + AstStat* statement = expectParseStatement(XorStr("declare function foo(x: number): string")); std::string_view expected = - R"({"type":"AstStatDeclareFunction","location":"0,0 - 0,39","name":"foo","params":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"0,24 - 0,30","name":"number","parameters":[]}]},"retTypes":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"0,33 - 0,39","name":"string","parameters":[]}]},"generics":[],"genericPacks":[]})"; + R"({"type":"AstStatDeclareFunction","location":"0,0 - 0,39","name":"foo","params":{"types":[{"type":"AstTypeReference","location":"0,24 - 0,30","name":"number","parameters":[]}]},"retTypes":{"types":[{"type":"AstTypeReference","location":"0,33 - 0,39","name":"string","parameters":[]}]},"generics":[],"genericPacks":[]})"; CHECK(toJson(statement) == expected); } @@ -414,27 +370,27 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatDeclareClass") REQUIRE(2 == root->body.size); std::string_view expected1 = - R"({"type":"AstStatDeclareClass","location":"1,22 - 4,11","name":"Foo","props":[{"name":"prop","type":"AstDeclaredClassProp","luauType":{"type":"AstTypeReference","location":"2,18 - 2,24","name":"number","parameters":[]}},{"name":"method","type":"AstDeclaredClassProp","luauType":{"type":"AstTypeFunction","location":"3,21 - 4,11","generics":[],"genericPacks":[],"argTypes":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"3,39 - 3,45","name":"number","parameters":[]}]},"returnTypes":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"3,48 - 3,54","name":"string","parameters":[]}]}}}]})"; + R"({"type":"AstStatDeclareClass","location":"1,22 - 4,11","name":"Foo","props":[{"name":"prop","type":{"type":"AstTypeReference","location":"2,18 - 2,24","name":"number","parameters":[]}},{"name":"method","type":{"type":"AstTypeFunction","location":"3,21 - 4,11","generics":[],"genericPacks":[],"argTypes":{"types":[{"type":"AstTypeReference","location":"3,39 - 3,45","name":"number","parameters":[]}]},"returnTypes":{"types":[{"type":"AstTypeReference","location":"3,48 - 3,54","name":"string","parameters":[]}]}}}]})"; CHECK(toJson(root->body.data[0]) == expected1); std::string_view expected2 = - R"({"type":"AstStatDeclareClass","location":"6,22 - 8,11","name":"Bar","superName":"Foo","props":[{"name":"prop2","type":"AstDeclaredClassProp","luauType":{"type":"AstTypeReference","location":"7,19 - 7,25","name":"string","parameters":[]}}]})"; + R"({"type":"AstStatDeclareClass","location":"6,22 - 8,11","name":"Bar","superName":"Foo","props":[{"name":"prop2","type":{"type":"AstTypeReference","location":"7,19 - 7,25","name":"string","parameters":[]}}]})"; CHECK(toJson(root->body.data[1]) == expected2); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_annotation") { - AstStat* statement = expectParseStatement("type T = ((number) -> (string | nil)) & ((string) -> ())"); + AstStat* statement = expectParseStatement(XorStr("type T = ((number) -> (string | nil)) & ((string) -> ())")); std::string_view expected = - R"({"type":"AstStatTypeAlias","location":"0,0 - 0,55","name":"T","generics":[],"genericPacks":[],"type":{"type":"AstTypeIntersection","location":"0,9 - 0,55","types":[{"type":"AstTypeFunction","location":"0,10 - 0,35","generics":[],"genericPacks":[],"argTypes":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"0,11 - 0,17","name":"number","parameters":[]}]},"returnTypes":{"type":"AstTypeList","types":[{"type":"AstTypeUnion","location":"0,23 - 0,35","types":[{"type":"AstTypeReference","location":"0,23 - 0,29","name":"string","parameters":[]},{"type":"AstTypeReference","location":"0,32 - 0,35","name":"nil","parameters":[]}]}]}},{"type":"AstTypeFunction","location":"0,41 - 0,55","generics":[],"genericPacks":[],"argTypes":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"0,42 - 0,48","name":"string","parameters":[]}]},"returnTypes":{"type":"AstTypeList","types":[]}}]},"exported":false})"; + R"({"type":"AstStatTypeAlias","location":"0,0 - 0,55","name":"T","generics":[],"genericPacks":[],"type":{"type":"AstTypeIntersection","location":"0,9 - 0,55","types":[{"type":"AstTypeFunction","location":"0,10 - 0,35","generics":[],"genericPacks":[],"argTypes":{"types":[{"type":"AstTypeReference","location":"0,11 - 0,17","name":"number","parameters":[]}]},"returnTypes":{"types":[{"type":"AstTypeUnion","location":"0,23 - 0,35","types":[{"type":"AstTypeReference","location":"0,23 - 0,29","name":"string","parameters":[]},{"type":"AstTypeReference","location":"0,32 - 0,35","name":"nil","parameters":[]}]}]}},{"type":"AstTypeFunction","location":"0,41 - 0,55","generics":[],"genericPacks":[],"argTypes":{"types":[{"type":"AstTypeReference","location":"0,42 - 0,48","name":"string","parameters":[]}]},"returnTypes":{"types":[]}}]},"exported":false})"; CHECK(toJson(statement) == expected); } TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstTypeError") { - ParseResult parseResult = parse("type T = "); + ParseResult parseResult = parse(XorStr("type T = ")); REQUIRE(1 == parseResult.root->body.size); AstStat* statement = parseResult.root->body.data[0]; @@ -455,7 +411,7 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstTypePackExplicit") CHECK(2 == root->body.size); std::string_view expected = - R"({"type":"AstStatLocal","location":"2,8 - 2,36","vars":[{"luauType":{"type":"AstTypeReference","location":"2,17 - 2,36","name":"A","parameters":[{"type":"AstTypePackExplicit","location":"2,19 - 2,20","typeList":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"2,20 - 2,26","name":"number","parameters":[]},{"type":"AstTypeReference","location":"2,28 - 2,34","name":"string","parameters":[]}]}}]},"name":"a","type":"AstLocal","location":"2,14 - 2,15"}],"values":[]})"; + R"({"type":"AstStatLocal","location":"2,8 - 2,36","vars":[{"type":{"type":"AstTypeReference","location":"2,17 - 2,36","name":"A","parameters":[{"type":"AstTypePackExplicit","location":"2,19 - 2,20","typeList":{"types":[{"type":"AstTypeReference","location":"2,20 - 2,26","name":"number","parameters":[]},{"type":"AstTypeReference","location":"2,28 - 2,34","name":"string","parameters":[]}]}}]},"name":"a","location":"2,14 - 2,15"}],"values":[]})"; CHECK(toJson(root->body.data[1]) == expected); } diff --git a/tests/LValue.test.cpp b/tests/LValue.test.cpp index 606f6de3..e9adcce5 100644 --- a/tests/LValue.test.cpp +++ b/tests/LValue.test.cpp @@ -1,16 +1,16 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/TypeInfer.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/TypeInfer.h" #include "Fixture.h" #include "ScopedFlags.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; static void merge(TypeArena& arena, RefinementMap& l, const RefinementMap& r) { - Luau::merge(l, r, [&arena](TypeId a, TypeId b) -> TypeId { + lluz::merge(l, r, [&arena](TypeId a, TypeId b) -> TypeId { // TODO: normalize here also. std::unordered_set s; @@ -34,9 +34,9 @@ static LValue mkSymbol(const std::string& s) return Symbol{AstName{s.data()}}; } -TEST_SUITE_BEGIN("LValue"); +TEST_SUITE_BEGIN(XorStr("LValue")); -TEST_CASE("Luau_merge_hashmap_order") +TEST_CASE("lluz_merge_hashmap_order") { std::string a = "a"; std::string b = "b"; @@ -66,7 +66,7 @@ TEST_CASE("Luau_merge_hashmap_order") CHECK_EQ("boolean | number", toString(m[mkSymbol(c)])); } -TEST_CASE("Luau_merge_hashmap_order2") +TEST_CASE("lluz_merge_hashmap_order2") { std::string a = "a"; std::string b = "b"; diff --git a/tests/Linter.test.cpp b/tests/Linter.test.cpp index 488ade9f..ab368d2b 100644 --- a/tests/Linter.test.cpp +++ b/tests/Linter.test.cpp @@ -1,15 +1,15 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Linter.h" -#include "Luau/BuiltinDefinitions.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Linter.h" +#include "lluz/BuiltinDefinitions.h" #include "Fixture.h" #include "ScopedFlags.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("Linter"); +TEST_SUITE_BEGIN(XorStr("Linter")); TEST_CASE_FIXTURE(Fixture, "CleanCode") { @@ -26,10 +26,10 @@ return math.max(fib(5), 1) TEST_CASE_FIXTURE(Fixture, "UnknownGlobal") { - LintResult result = lint("--!nocheck\nreturn foo"); + LintResult result = lint(XorStr("--!nocheck\nreturn foo")); REQUIRE_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Unknown global 'foo'"); + CHECK_EQ(result.warnings[0].text, XorStr("Unknown global 'foo'")); } TEST_CASE_FIXTURE(Fixture, "DeprecatedGlobal") @@ -37,10 +37,10 @@ TEST_CASE_FIXTURE(Fixture, "DeprecatedGlobal") // Normally this would be defined externally, so hack it in for testing addGlobalBinding(typeChecker, "Wait", Binding{typeChecker.anyType, {}, true, "wait", "@test/global/Wait"}); - LintResult result = lintTyped("Wait(5)"); + LintResult result = lintTyped(XorStr("Wait(5)")); REQUIRE_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Global 'Wait' is deprecated, use 'wait' instead"); + CHECK_EQ(result.warnings[0].text, XorStr("Global 'Wait' is deprecated, use 'wait' instead")); } TEST_CASE_FIXTURE(Fixture, "PlaceholderRead") @@ -51,7 +51,7 @@ return _ )"); CHECK_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Placeholder value '_' is read here; consider using a named variable"); + CHECK_EQ(result.warnings[0].text, XorStr("Placeholder value '_' is read here; consider using a named variable")); } TEST_CASE_FIXTURE(Fixture, "PlaceholderReadGlobal") @@ -62,7 +62,7 @@ print(_) )"); CHECK_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Placeholder value '_' is read here; consider using a named variable"); + CHECK_EQ(result.warnings[0].text, XorStr("Placeholder value '_' is read here; consider using a named variable")); } TEST_CASE_FIXTURE(Fixture, "PlaceholderWrite") @@ -87,8 +87,8 @@ assert(5) )"); CHECK_EQ(result.warnings.size(), 2); - CHECK_EQ(result.warnings[0].text, "Built-in global 'math' is overwritten here; consider using a local or changing the name"); - CHECK_EQ(result.warnings[1].text, "Built-in global 'assert' is overwritten here; consider using a local or changing the name"); + CHECK_EQ(result.warnings[0].text, XorStr("Built-in global 'math' is overwritten here; consider using a local or changing the name")); + CHECK_EQ(result.warnings[1].text, XorStr("Built-in global 'assert' is overwritten here; consider using a local or changing the name")); } TEST_CASE_FIXTURE(Fixture, "MultilineBlock") @@ -98,7 +98,7 @@ if true then print(1) print(2) print(3) end )"); CHECK_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "A new statement is on the same line; add semi-colon on previous statement to silence"); + CHECK_EQ(result.warnings[0].text, XorStr("A new statement is on the same line; add semi-colon on previous statement to silence")); } TEST_CASE_FIXTURE(Fixture, "MultilineBlockSemicolonsWhitelisted") @@ -117,7 +117,7 @@ print(1); print(2) print(3) )"); CHECK_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "A new statement is on the same line; add semi-colon on previous statement to silence"); + CHECK_EQ(result.warnings[0].text, XorStr("A new statement is on the same line; add semi-colon on previous statement to silence")); } TEST_CASE_FIXTURE(Fixture, "MultilineBlockLocalDo") @@ -139,7 +139,7 @@ print(math.max(1, )"); CHECK_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Statement spans multiple lines; use indentation to silence"); + CHECK_EQ(result.warnings[0].text, XorStr("Statement spans multiple lines; use indentation to silence")); } TEST_CASE_FIXTURE(Fixture, "GlobalAsLocal") @@ -154,12 +154,12 @@ return bar() )"); CHECK_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Global 'foo' is only used in the enclosing function 'bar'; consider changing it to local"); + CHECK_EQ(result.warnings[0].text, XorStr("Global 'foo' is only used in the enclosing function 'bar'; consider changing it to local")); } TEST_CASE_FIXTURE(Fixture, "GlobalAsLocalMultiFx") { - ScopedFastFlag sff{"LuauLintGlobalNeverReadBeforeWritten", true}; + ScopedFastFlag sff{"lluzLintGlobalNeverReadBeforeWritten", true}; LintResult result = lint(R"( function bar() foo = 6 @@ -175,12 +175,12 @@ return bar() + baz() )"); REQUIRE_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Global 'foo' is never read before being written. Consider changing it to local"); + CHECK_EQ(result.warnings[0].text, XorStr("Global 'foo' is never read before being written. Consider changing it to local")); } TEST_CASE_FIXTURE(Fixture, "GlobalAsLocalMultiFxWithRead") { - ScopedFastFlag sff{"LuauLintGlobalNeverReadBeforeWritten", true}; + ScopedFastFlag sff{"lluzLintGlobalNeverReadBeforeWritten", true}; LintResult result = lint(R"( function bar() foo = 6 @@ -204,7 +204,7 @@ return bar() + baz() + read() TEST_CASE_FIXTURE(Fixture, "GlobalAsLocalWithConditional") { - ScopedFastFlag sff{"LuauLintGlobalNeverReadBeforeWritten", true}; + ScopedFastFlag sff{"lluzLintGlobalNeverReadBeforeWritten", true}; LintResult result = lint(R"( function bar() if true then foo = 6 end @@ -224,7 +224,7 @@ return bar() + baz() TEST_CASE_FIXTURE(Fixture, "GlobalAsLocal3WithConditionalRead") { - ScopedFastFlag sff{"LuauLintGlobalNeverReadBeforeWritten", true}; + ScopedFastFlag sff{"lluzLintGlobalNeverReadBeforeWritten", true}; LintResult result = lint(R"( function bar() foo = 6 @@ -248,7 +248,7 @@ return bar() + baz() + read() TEST_CASE_FIXTURE(Fixture, "GlobalAsLocalInnerRead") { - ScopedFastFlag sff{"LuauLintGlobalNeverReadBeforeWritten", true}; + ScopedFastFlag sff{"lluzLintGlobalNeverReadBeforeWritten", true}; LintResult result = lint(R"( function foo() local f = function() return bar end @@ -292,7 +292,7 @@ fnB() -- prints "false", "nil" CHECK_EQ(result.warnings.size(), 1); CHECK_EQ(result.warnings[0].text, - "Global 'moreInternalLogic' is only used in the enclosing function defined at line 2; consider changing it to local"); + XorStr("Global 'moreInternalLogic' is only used in the enclosing function defined at line 2; consider changing it to local")); } TEST_CASE_FIXTURE(Fixture, "LocalShadowLocal") @@ -306,7 +306,7 @@ print(arg) )"); CHECK_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Variable 'arg' shadows previous declaration at line 2"); + CHECK_EQ(result.warnings[0].text, XorStr("Variable 'arg' shadows previous declaration at line 2")); } TEST_CASE_FIXTURE(BuiltinsFixture, "LocalShadowGlobal") @@ -324,7 +324,7 @@ return bar() )"); CHECK_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Variable 'global' shadows a global variable used at line 3"); + CHECK_EQ(result.warnings[0].text, XorStr("Variable 'global' shadows a global variable used at line 3")); } TEST_CASE_FIXTURE(Fixture, "LocalShadowArgument") @@ -339,7 +339,7 @@ return bar() )"); CHECK_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Variable 'a' shadows previous declaration at line 2"); + CHECK_EQ(result.warnings[0].text, XorStr("Variable 'a' shadows previous declaration at line 2")); } TEST_CASE_FIXTURE(Fixture, "LocalUnused") @@ -359,14 +359,14 @@ return bar() )"); CHECK_EQ(result.warnings.size(), 2); - CHECK_EQ(result.warnings[0].text, "Variable 'arg' is never used; prefix with '_' to silence"); - CHECK_EQ(result.warnings[1].text, "Variable 'blarg' is never used; prefix with '_' to silence"); + CHECK_EQ(result.warnings[0].text, XorStr("Variable 'arg' is never used; prefix with '_' to silence")); + CHECK_EQ(result.warnings[1].text, XorStr("Variable 'blarg' is never used; prefix with '_' to silence")); } TEST_CASE_FIXTURE(Fixture, "ImportUnused") { // Normally this would be defined externally, so hack it in for testing - addGlobalBinding(typeChecker, "game", typeChecker.anyType, "@test"); + addGlobalBinding(typeChecker, XorStr("game", typeChecker.anyType, "@test")); LintResult result = lint(R"( local Roact = require(game.Packages.Roact) @@ -374,7 +374,7 @@ local _Roact = require(game.Packages.Roact) )"); CHECK_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Import 'Roact' is never used; prefix with '_' to silence"); + CHECK_EQ(result.warnings[0].text, XorStr("Import 'Roact' is never used; prefix with '_' to silence")); } TEST_CASE_FIXTURE(Fixture, "FunctionUnused") @@ -399,8 +399,8 @@ return foo() )"); CHECK_EQ(result.warnings.size(), 2); - CHECK_EQ(result.warnings[0].text, "Function 'bar' is never used; prefix with '_' to silence"); - CHECK_EQ(result.warnings[1].text, "Function 'qux' is never used; prefix with '_' to silence"); + CHECK_EQ(result.warnings[0].text, XorStr("Function 'bar' is never used; prefix with '_' to silence")); + CHECK_EQ(result.warnings[1].text, XorStr("Function 'qux' is never used; prefix with '_' to silence")); } TEST_CASE_FIXTURE(Fixture, "UnreachableCodeBasic") @@ -415,7 +415,7 @@ print("hi!") CHECK_EQ(result.warnings.size(), 1); CHECK_EQ(result.warnings[0].location.begin.line, 5); - CHECK_EQ(result.warnings[0].text, "Unreachable code (previous statement always returns)"); + CHECK_EQ(result.warnings[0].text, XorStr("Unreachable code (previous statement always returns)")); } TEST_CASE_FIXTURE(Fixture, "UnreachableCodeLoopBreak") @@ -431,7 +431,7 @@ print("hi!") CHECK_EQ(result.warnings.size(), 1); CHECK_EQ(result.warnings[0].location.begin.line, 3); - CHECK_EQ(result.warnings[0].text, "Unreachable code (previous statement always breaks)"); + CHECK_EQ(result.warnings[0].text, XorStr("Unreachable code (previous statement always breaks)")); } TEST_CASE_FIXTURE(Fixture, "UnreachableCodeLoopContinue") @@ -447,7 +447,7 @@ print("hi!") CHECK_EQ(result.warnings.size(), 1); CHECK_EQ(result.warnings[0].location.begin.line, 3); - CHECK_EQ(result.warnings[0].text, "Unreachable code (previous statement always continues)"); + CHECK_EQ(result.warnings[0].text, XorStr("Unreachable code (previous statement always continues)")); } TEST_CASE_FIXTURE(Fixture, "UnreachableCodeIfMerge") @@ -483,7 +483,7 @@ return { foo1, foo2, foo3 } CHECK_EQ(result.warnings.size(), 1); CHECK_EQ(result.warnings[0].location.begin.line, 7); - CHECK_EQ(result.warnings[0].text, "Unreachable code (previous statement always returns)"); + CHECK_EQ(result.warnings[0].text, XorStr("Unreachable code (previous statement always returns)")); } TEST_CASE_FIXTURE(Fixture, "UnreachableCodeErrorReturnSilent") @@ -538,7 +538,7 @@ return foo1 CHECK_EQ(result.warnings.size(), 1); CHECK_EQ(result.warnings[0].location.begin.line, 7); - CHECK_EQ(result.warnings[0].text, "Unreachable code (previous statement always errors)"); + CHECK_EQ(result.warnings[0].text, XorStr("Unreachable code (previous statement always errors)")); } TEST_CASE_FIXTURE(Fixture, "UnreachableCodeErrorReturnPropagate") @@ -559,7 +559,7 @@ return foo1 CHECK_EQ(result.warnings.size(), 1); CHECK_EQ(result.warnings[0].location.begin.line, 8); - CHECK_EQ(result.warnings[0].text, "Unreachable code (previous statement always errors)"); + CHECK_EQ(result.warnings[0].text, XorStr("Unreachable code (previous statement always errors)")); } TEST_CASE_FIXTURE(Fixture, "UnreachableCodeLoopWhile") @@ -602,7 +602,7 @@ TEST_CASE_FIXTURE(Fixture, "UnknownType") {"ClassName", {typeChecker.anyType}}, }; - TableTypeVar instanceTable{instanceProps, std::nullopt, typeChecker.globalScope->level, Luau::TableState::Sealed}; + TableTypeVar instanceTable{instanceProps, std::nullopt, typeChecker.globalScope->level, lluz::TableState::Sealed}; TypeId instanceType = typeChecker.globalTypes.addType(instanceTable); TypeFun instanceTypeFun{{}, instanceType}; @@ -610,22 +610,22 @@ TEST_CASE_FIXTURE(Fixture, "UnknownType") LintResult result = lint(R"( local game = ... -local _e01 = type(game) == "Part" -local _e02 = typeof(game) == "Bar" -local _e03 = typeof(game) == "vector" +local _e01 = type(game) == XorStr("Part") +local _e02 = typeof(game) == XorStr("Bar") +local _e03 = typeof(game) == XorStr("vector") -local _o01 = type(game) == "number" -local _o02 = type(game) == "vector" -local _o03 = typeof(game) == "Part" +local _o01 = type(game) == XorStr("number") +local _o02 = type(game) == XorStr("vector") +local _o03 = typeof(game) == XorStr("Part") )"); REQUIRE_EQ(result.warnings.size(), 3); CHECK_EQ(result.warnings[0].location.begin.line, 2); - CHECK_EQ(result.warnings[0].text, "Unknown type 'Part' (expected primitive type)"); + CHECK_EQ(result.warnings[0].text, XorStr("Unknown type 'Part' (expected primitive type)")); CHECK_EQ(result.warnings[1].location.begin.line, 3); - CHECK_EQ(result.warnings[1].text, "Unknown type 'Bar'"); + CHECK_EQ(result.warnings[1].text, XorStr("Unknown type 'Bar'")); CHECK_EQ(result.warnings[2].location.begin.line, 4); - CHECK_EQ(result.warnings[2].text, "Unknown type 'vector' (expected primitive or userdata type)"); + CHECK_EQ(result.warnings[2].text, XorStr("Unknown type 'vector' (expected primitive or userdata type)")); } TEST_CASE_FIXTURE(Fixture, "ForRangeTable") @@ -642,7 +642,7 @@ end CHECK_EQ(result.warnings.size(), 1); CHECK_EQ(result.warnings[0].location.begin.line, 3); - CHECK_EQ(result.warnings[0].text, "For loop should iterate backwards; did you forget to specify -1 as step?"); + CHECK_EQ(result.warnings[0].text, XorStr("For loop should iterate backwards; did you forget to specify -1 as step?")); } TEST_CASE_FIXTURE(Fixture, "ForRangeBackwards") @@ -657,7 +657,7 @@ end CHECK_EQ(result.warnings.size(), 1); CHECK_EQ(result.warnings[0].location.begin.line, 1); - CHECK_EQ(result.warnings[0].text, "For loop should iterate backwards; did you forget to specify -1 as step?"); + CHECK_EQ(result.warnings[0].text, XorStr("For loop should iterate backwards; did you forget to specify -1 as step?")); } TEST_CASE_FIXTURE(Fixture, "ForRangeImprecise") @@ -672,7 +672,7 @@ end CHECK_EQ(result.warnings.size(), 1); CHECK_EQ(result.warnings[0].location.begin.line, 1); - CHECK_EQ(result.warnings[0].text, "For loop ends at 7.3 instead of 7.5; did you forget to specify step?"); + CHECK_EQ(result.warnings[0].text, XorStr("For loop ends at 7.3 instead of 7.5; did you forget to specify step?")); } TEST_CASE_FIXTURE(Fixture, "ForRangeZero") @@ -690,10 +690,10 @@ end CHECK_EQ(result.warnings.size(), 2); CHECK_EQ(result.warnings[0].location.begin.line, 1); - CHECK_EQ(result.warnings[0].text, "For loop starts at 0, but arrays start at 1"); + CHECK_EQ(result.warnings[0].text, XorStr("For loop starts at 0, but arrays start at 1")); CHECK_EQ(result.warnings[1].location.begin.line, 7); CHECK_EQ(result.warnings[1].text, - "For loop should iterate backwards; did you forget to specify -1 as step? Also consider changing 0 to 1 since arrays start at 1"); + XorStr("For loop should iterate backwards; did you forget to specify -1 as step? Also consider changing 0 to 1 since arrays start at 1")); } TEST_CASE_FIXTURE(Fixture, "UnbalancedAssignment") @@ -718,9 +718,9 @@ end CHECK_EQ(result.warnings.size(), 2); CHECK_EQ(result.warnings[0].location.begin.line, 5); - CHECK_EQ(result.warnings[0].text, "Assigning 2 values to 3 variables initializes extra variables with nil; add 'nil' to value list to silence"); + CHECK_EQ(result.warnings[0].text, XorStr("Assigning 2 values to 3 variables initializes extra variables with nil; add 'nil' to value list to silence")); CHECK_EQ(result.warnings[1].location.begin.line, 11); - CHECK_EQ(result.warnings[1].text, "Assigning 4 values to 3 variables leaves some values unused"); + CHECK_EQ(result.warnings[1].text, XorStr("Assigning 4 values to 3 variables leaves some values unused")); } TEST_CASE_FIXTURE(Fixture, "ImplicitReturn") @@ -784,13 +784,13 @@ return f1,f2,f3,f4,f5,f6,f7 CHECK_EQ(result.warnings.size(), 3); CHECK_EQ(result.warnings[0].location.begin.line, 4); CHECK_EQ(result.warnings[0].text, - "Function 'f1' can implicitly return no values even though there's an explicit return at line 4; add explicit return to silence"); + XorStr("Function 'f1' can implicitly return no values even though there's an explicit return at line 4; add explicit return to silence")); CHECK_EQ(result.warnings[1].location.begin.line, 28); CHECK_EQ(result.warnings[1].text, - "Function 'f4' can implicitly return no values even though there's an explicit return at line 25; add explicit return to silence"); + XorStr("Function 'f4' can implicitly return no values even though there's an explicit return at line 25; add explicit return to silence")); CHECK_EQ(result.warnings[2].location.begin.line, 44); CHECK_EQ(result.warnings[2].text, - "Function can implicitly return no values even though there's an explicit return at line 44; add explicit return to silence"); + XorStr("Function can implicitly return no values even though there's an explicit return at line 44; add explicit return to silence")); } TEST_CASE_FIXTURE(Fixture, "ImplicitReturnInfiniteLoop") @@ -840,10 +840,10 @@ return f1,f2,f3,f4 CHECK_EQ(result.warnings.size(), 2); CHECK_EQ(result.warnings[0].location.begin.line, 25); CHECK_EQ(result.warnings[0].text, - "Function 'f3' can implicitly return no values even though there's an explicit return at line 21; add explicit return to silence"); + XorStr("Function 'f3' can implicitly return no values even though there's an explicit return at line 21; add explicit return to silence")); CHECK_EQ(result.warnings[1].location.begin.line, 36); CHECK_EQ(result.warnings[1].text, - "Function 'f4' can implicitly return no values even though there's an explicit return at line 32; add explicit return to silence"); + XorStr("Function 'f4' can implicitly return no values even though there's an explicit return at line 32; add explicit return to silence")); } TEST_CASE_FIXTURE(Fixture, "TypeAnnotationsShouldNotProduceWarnings") @@ -901,29 +901,29 @@ return foo )"); CHECK_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Variable 'x' is never used; prefix with '_' to silence"); + CHECK_EQ(result.warnings[0].text, XorStr("Variable 'x' is never used; prefix with '_' to silence")); } TEST_CASE_FIXTURE(Fixture, "FormatStringFormat") { LintResult result = lint(R"( -- incorrect format strings -string.format("%") -string.format("%??d") -string.format("%Y") +string.format(XorStr("%")) +string.format(XorStr("%??d")) +string.format(XorStr("%Y")) -- incorrect format strings, self call local _ = ("%"):format() -- correct format strings, just to uh make sure -string.format("hello %+10d %.02f %%", 4, 5) +string.format(XorStr("hello %+10d %.02f %%"), 4, 5) )"); CHECK_EQ(result.warnings.size(), 4); - CHECK_EQ(result.warnings[0].text, "Invalid format string: unfinished format specifier"); - CHECK_EQ(result.warnings[1].text, "Invalid format string: invalid format specifier: must be a string format specifier or %"); - CHECK_EQ(result.warnings[2].text, "Invalid format string: invalid format specifier: must be a string format specifier or %"); - CHECK_EQ(result.warnings[3].text, "Invalid format string: unfinished format specifier"); + CHECK_EQ(result.warnings[0].text, XorStr("Invalid format string: unfinished format specifier")); + CHECK_EQ(result.warnings[1].text, XorStr("Invalid format string: invalid format specifier: must be a string format specifier or %")); + CHECK_EQ(result.warnings[2].text, XorStr("Invalid format string: invalid format specifier: must be a string format specifier or %")); + CHECK_EQ(result.warnings[3].text, XorStr("Invalid format string: unfinished format specifier")); } TEST_CASE_FIXTURE(Fixture, "FormatStringPack") @@ -960,17 +960,17 @@ string.packsize("=!1bbbI3c42") )"); CHECK_EQ(result.warnings.size(), 11); - CHECK_EQ(result.warnings[0].text, "Invalid pack format: unexpected character; must be a pack specifier or space"); - CHECK_EQ(result.warnings[1].text, "Invalid pack format: unexpected character; must be a pack specifier or space"); - CHECK_EQ(result.warnings[2].text, "Invalid pack format: unexpected character; must be a pack specifier or space"); - CHECK_EQ(result.warnings[3].text, "Invalid pack format: fixed-sized string format must specify the size"); - CHECK_EQ(result.warnings[4].text, "Invalid pack format: X must be followed by a size specifier"); - CHECK_EQ(result.warnings[5].text, "Invalid pack format: X must be followed by a size specifier"); - CHECK_EQ(result.warnings[6].text, "Invalid pack format: pack specifier must be fixed-size"); - CHECK_EQ(result.warnings[7].text, "Invalid pack format: integer size must be in range [1,16]"); - CHECK_EQ(result.warnings[8].text, "Invalid pack format: integer size must be in range [1,16]"); - CHECK_EQ(result.warnings[9].text, "Invalid pack format: size specifier is too large"); - CHECK_EQ(result.warnings[10].text, "Invalid pack format: size specifier is too large"); + CHECK_EQ(result.warnings[0].text, XorStr("Invalid pack format: unexpected character; must be a pack specifier or space")); + CHECK_EQ(result.warnings[1].text, XorStr("Invalid pack format: unexpected character; must be a pack specifier or space")); + CHECK_EQ(result.warnings[2].text, XorStr("Invalid pack format: unexpected character; must be a pack specifier or space")); + CHECK_EQ(result.warnings[3].text, XorStr("Invalid pack format: fixed-sized string format must specify the size")); + CHECK_EQ(result.warnings[4].text, XorStr("Invalid pack format: X must be followed by a size specifier")); + CHECK_EQ(result.warnings[5].text, XorStr("Invalid pack format: X must be followed by a size specifier")); + CHECK_EQ(result.warnings[6].text, XorStr("Invalid pack format: pack specifier must be fixed-size")); + CHECK_EQ(result.warnings[7].text, XorStr("Invalid pack format: integer size must be in range [1,16]")); + CHECK_EQ(result.warnings[8].text, XorStr("Invalid pack format: integer size must be in range [1,16]")); + CHECK_EQ(result.warnings[9].text, XorStr("Invalid pack format: size specifier is too large")); + CHECK_EQ(result.warnings[10].text, XorStr("Invalid pack format: size specifier is too large")); } TEST_CASE_FIXTURE(Fixture, "FormatStringMatch") @@ -1004,20 +1004,20 @@ string.match(s, "[A-Z]+(%d)%1") )"); CHECK_EQ(result.warnings.size(), 14); - CHECK_EQ(result.warnings[0].text, "Invalid match pattern: invalid character class, must refer to a defined class or its inverse"); - CHECK_EQ(result.warnings[1].text, "Invalid match pattern: invalid character class, must refer to a defined class or its inverse"); - CHECK_EQ(result.warnings[2].text, "Invalid match pattern: invalid character class, must refer to a defined class or its inverse"); - CHECK_EQ(result.warnings[3].text, "Invalid match pattern: invalid character class, must refer to a defined class or its inverse"); - CHECK_EQ(result.warnings[4].text, "Invalid match pattern: unfinished character class"); - CHECK_EQ(result.warnings[5].text, "Invalid match pattern: sets can not contain capture references"); - CHECK_EQ(result.warnings[6].text, "Invalid match pattern: invalid capture reference, must be 1-9"); - CHECK_EQ(result.warnings[7].text, "Invalid match pattern: invalid capture reference, must refer to a valid capture"); - CHECK_EQ(result.warnings[8].text, "Invalid match pattern: missing brace characters for balanced match"); - CHECK_EQ(result.warnings[9].text, "Invalid match pattern: missing set after a frontier pattern"); - CHECK_EQ(result.warnings[10].text, "Invalid match pattern: unexpected ) without a matching ("); - CHECK_EQ(result.warnings[11].text, "Invalid match pattern: expected ) at the end of the string to close a capture"); - CHECK_EQ(result.warnings[12].text, "Invalid match pattern: expected ] at the end of the string to close a set"); - CHECK_EQ(result.warnings[13].text, "Invalid match pattern: expected a magic character after %"); + CHECK_EQ(result.warnings[0].text, XorStr("Invalid match pattern: invalid character class, must refer to a defined class or its inverse")); + CHECK_EQ(result.warnings[1].text, XorStr("Invalid match pattern: invalid character class, must refer to a defined class or its inverse")); + CHECK_EQ(result.warnings[2].text, XorStr("Invalid match pattern: invalid character class, must refer to a defined class or its inverse")); + CHECK_EQ(result.warnings[3].text, XorStr("Invalid match pattern: invalid character class, must refer to a defined class or its inverse")); + CHECK_EQ(result.warnings[4].text, XorStr("Invalid match pattern: unfinished character class")); + CHECK_EQ(result.warnings[5].text, XorStr("Invalid match pattern: sets can not contain capture references")); + CHECK_EQ(result.warnings[6].text, XorStr("Invalid match pattern: invalid capture reference, must be 1-9")); + CHECK_EQ(result.warnings[7].text, XorStr("Invalid match pattern: invalid capture reference, must refer to a valid capture")); + CHECK_EQ(result.warnings[8].text, XorStr("Invalid match pattern: missing brace characters for balanced match")); + CHECK_EQ(result.warnings[9].text, XorStr("Invalid match pattern: missing set after a frontier pattern")); + CHECK_EQ(result.warnings[10].text, XorStr("Invalid match pattern: unexpected ) without a matching (")); + CHECK_EQ(result.warnings[11].text, XorStr("Invalid match pattern: expected ) at the end of the string to close a capture")); + CHECK_EQ(result.warnings[12].text, XorStr("Invalid match pattern: expected ] at the end of the string to close a set")); + CHECK_EQ(result.warnings[13].text, XorStr("Invalid match pattern: expected a magic character after %")); } TEST_CASE_FIXTURE(Fixture, "FormatStringMatchNested") @@ -1036,9 +1036,9 @@ string.match(s, "((a)%3)") )~"); CHECK_EQ(result.warnings.size(), 2); - CHECK_EQ(result.warnings[0].text, "Invalid match pattern: invalid capture reference, must refer to a closed capture"); + CHECK_EQ(result.warnings[0].text, XorStr("Invalid match pattern: invalid capture reference, must refer to a closed capture")); CHECK_EQ(result.warnings[0].location.begin.line, 7); - CHECK_EQ(result.warnings[1].text, "Invalid match pattern: invalid capture reference, must refer to a valid capture"); + CHECK_EQ(result.warnings[1].text, XorStr("Invalid match pattern: invalid capture reference, must refer to a valid capture")); CHECK_EQ(result.warnings[1].location.begin.line, 10); } @@ -1074,13 +1074,13 @@ string.match(s, "[^]|'[]") )~"); CHECK_EQ(result.warnings.size(), 7); - CHECK_EQ(result.warnings[0].text, "Invalid match pattern: expected ] at the end of the string to close a set"); - CHECK_EQ(result.warnings[1].text, "Invalid match pattern: expected ] at the end of the string to close a set"); - CHECK_EQ(result.warnings[2].text, "Invalid match pattern: character range can't include character sets"); - CHECK_EQ(result.warnings[3].text, "Invalid match pattern: character range can't include character sets"); - CHECK_EQ(result.warnings[4].text, "Invalid match pattern: invalid character class, must refer to a defined class or its inverse"); - CHECK_EQ(result.warnings[5].text, "Invalid match pattern: expected a magic character after %"); - CHECK_EQ(result.warnings[6].text, "Invalid match pattern: sets can not contain capture references"); + CHECK_EQ(result.warnings[0].text, XorStr("Invalid match pattern: expected ] at the end of the string to close a set")); + CHECK_EQ(result.warnings[1].text, XorStr("Invalid match pattern: expected ] at the end of the string to close a set")); + CHECK_EQ(result.warnings[2].text, XorStr("Invalid match pattern: character range can't include character sets")); + CHECK_EQ(result.warnings[3].text, XorStr("Invalid match pattern: character range can't include character sets")); + CHECK_EQ(result.warnings[4].text, XorStr("Invalid match pattern: invalid character class, must refer to a defined class or its inverse")); + CHECK_EQ(result.warnings[5].text, XorStr("Invalid match pattern: expected a magic character after %")); + CHECK_EQ(result.warnings[6].text, XorStr("Invalid match pattern: sets can not contain capture references")); } TEST_CASE_FIXTURE(Fixture, "FormatStringFindArgs") @@ -1100,14 +1100,14 @@ string.find(s, "%q", 1, false) -- missing arguments string.find() -string.find("foo"); +string.find(XorStr("foo")); ("foo"):find() )"); CHECK_EQ(result.warnings.size(), 2); - CHECK_EQ(result.warnings[0].text, "Invalid match pattern: invalid character class, must refer to a defined class or its inverse"); + CHECK_EQ(result.warnings[0].text, XorStr("Invalid match pattern: invalid character class, must refer to a defined class or its inverse")); CHECK_EQ(result.warnings[0].location.begin.line, 4); - CHECK_EQ(result.warnings[1].text, "Invalid match pattern: invalid character class, must refer to a defined class or its inverse"); + CHECK_EQ(result.warnings[1].text, XorStr("Invalid match pattern: invalid character class, must refer to a defined class or its inverse")); CHECK_EQ(result.warnings[1].location.begin.line, 11); } @@ -1128,10 +1128,10 @@ string.gsub(s, 'foo', "%0") )"); CHECK_EQ(result.warnings.size(), 4); - CHECK_EQ(result.warnings[0].text, "Invalid match replacement: unfinished replacement"); - CHECK_EQ(result.warnings[1].text, "Invalid match replacement: unexpected replacement character; must be a digit or %"); - CHECK_EQ(result.warnings[2].text, "Invalid match replacement: invalid capture index, must refer to pattern capture"); - CHECK_EQ(result.warnings[3].text, "Invalid match replacement: invalid capture index, must refer to pattern capture"); + CHECK_EQ(result.warnings[0].text, XorStr("Invalid match replacement: unfinished replacement")); + CHECK_EQ(result.warnings[1].text, XorStr("Invalid match replacement: unexpected replacement character; must be a digit or %")); + CHECK_EQ(result.warnings[2].text, XorStr("Invalid match replacement: invalid capture index, must refer to pattern capture")); + CHECK_EQ(result.warnings[3].text, XorStr("Invalid match replacement: invalid capture index, must refer to pattern capture")); } TEST_CASE_FIXTURE(Fixture, "FormatStringDate") @@ -1149,10 +1149,10 @@ os.date("!*t") )"); CHECK_EQ(result.warnings.size(), 4); - CHECK_EQ(result.warnings[0].text, "Invalid date format: unfinished replacement"); - CHECK_EQ(result.warnings[1].text, "Invalid date format: unexpected replacement character; must be a date format specifier or %"); - CHECK_EQ(result.warnings[2].text, "Invalid date format: unexpected replacement character; must be a date format specifier or %"); - CHECK_EQ(result.warnings[3].text, "Invalid date format: date format can not contain null characters"); + CHECK_EQ(result.warnings[0].text, XorStr("Invalid date format: unfinished replacement")); + CHECK_EQ(result.warnings[1].text, XorStr("Invalid date format: unexpected replacement character; must be a date format specifier or %")); + CHECK_EQ(result.warnings[2].text, XorStr("Invalid date format: unexpected replacement character; must be a date format specifier or %")); + CHECK_EQ(result.warnings[3].text, XorStr("Invalid date format: date format can not contain null characters")); } TEST_CASE_FIXTURE(Fixture, "FormatStringTyped") @@ -1168,9 +1168,9 @@ nons:match("[]") )~"); CHECK_EQ(result.warnings.size(), 2); - CHECK_EQ(result.warnings[0].text, "Invalid match pattern: expected ] at the end of the string to close a set"); + CHECK_EQ(result.warnings[0].text, XorStr("Invalid match pattern: expected ] at the end of the string to close a set")); CHECK_EQ(result.warnings[0].location.begin.line, 3); - CHECK_EQ(result.warnings[1].text, "Invalid match pattern: expected ] at the end of the string to close a set"); + CHECK_EQ(result.warnings[1].text, XorStr("Invalid match pattern: expected ] at the end of the string to close a set")); CHECK_EQ(result.warnings[1].location.begin.line, 4); } @@ -1218,12 +1218,12 @@ _ = { )"); CHECK_EQ(result.warnings.size(), 6); - CHECK_EQ(result.warnings[0].text, "Table field 'first' is a duplicate; previously defined at line 3"); - CHECK_EQ(result.warnings[1].text, "Table field 'first' is a duplicate; previously defined at line 9"); - CHECK_EQ(result.warnings[2].text, "Table index 1 is a duplicate; previously defined as a list entry"); - CHECK_EQ(result.warnings[3].text, "Table index 3 is a duplicate; previously defined as a list entry"); - CHECK_EQ(result.warnings[4].text, "Table type field 'first' is a duplicate; previously defined at line 24"); - CHECK_EQ(result.warnings[5].text, "Table index 1 is a duplicate; previously defined at line 36"); + CHECK_EQ(result.warnings[0].text, XorStr("Table field 'first' is a duplicate; previously defined at line 3")); + CHECK_EQ(result.warnings[1].text, XorStr("Table field 'first' is a duplicate; previously defined at line 9")); + CHECK_EQ(result.warnings[2].text, XorStr("Table index 1 is a duplicate; previously defined as a list entry")); + CHECK_EQ(result.warnings[3].text, XorStr("Table index 3 is a duplicate; previously defined as a list entry")); + CHECK_EQ(result.warnings[4].text, XorStr("Table type field 'first' is a duplicate; previously defined at line 24")); + CHECK_EQ(result.warnings[5].text, XorStr("Table index 1 is a duplicate; previously defined at line 36")); } TEST_CASE_FIXTURE(Fixture, "ImportOnlyUsedInTypeAnnotation") @@ -1235,7 +1235,7 @@ TEST_CASE_FIXTURE(Fixture, "ImportOnlyUsedInTypeAnnotation") )"); REQUIRE_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Variable 'x' is never used; prefix with '_' to silence"); + CHECK_EQ(result.warnings[0].text, XorStr("Variable 'x' is never used; prefix with '_' to silence")); } TEST_CASE_FIXTURE(Fixture, "DisableUnknownGlobalWithTypeChecking") @@ -1262,12 +1262,12 @@ TEST_CASE_FIXTURE(Fixture, "no_spurious_warning_after_a_function_type_alias") TEST_CASE_FIXTURE(Fixture, "use_all_parent_scopes_for_globals") { - ScopePtr testScope = frontend.addEnvironment("Test"); + ScopePtr testScope = frontend.addEnvironment(XorStr("Test")); unfreeze(typeChecker.globalTypes); loadDefinitionFile(frontend.typeChecker, testScope, R"( declare Foo: number )", - "@test"); + XorStr("@test")); freeze(typeChecker.globalTypes); fileResolver.environments["A"] = "Test"; @@ -1278,7 +1278,7 @@ TEST_CASE_FIXTURE(Fixture, "use_all_parent_scopes_for_globals") local _bar: typeof(os.clock) = os.clock )"; - LintResult result = frontend.lint("A"); + LintResult result = frontend.lint(XorStr("A")); CHECK_EQ(result.warnings.size(), 0); } @@ -1307,9 +1307,9 @@ end )"); CHECK_EQ(result.warnings.size(), 3); - CHECK_EQ(result.warnings[0].text, "Variable 'x' defined at line 4 is never initialized or assigned; initialize with 'nil' to silence"); - CHECK_EQ(result.warnings[1].text, "Assigning 2 values to 3 variables initializes extra variables with nil; add 'nil' to value list to silence"); - CHECK_EQ(result.warnings[2].text, "Variable 'c' defined at line 12 is never initialized or assigned; initialize with 'nil' to silence"); + CHECK_EQ(result.warnings[0].text, XorStr("Variable 'x' defined at line 4 is never initialized or assigned; initialize with 'nil' to silence")); + CHECK_EQ(result.warnings[1].text, XorStr("Assigning 2 values to 3 variables initializes extra variables with nil; add 'nil' to value list to silence")); + CHECK_EQ(result.warnings[2].text, XorStr("Variable 'c' defined at line 12 is never initialized or assigned; initialize with 'nil' to silence")); } TEST_CASE_FIXTURE(Fixture, "LocalFunctionNotDead") @@ -1446,7 +1446,7 @@ TEST_CASE_FIXTURE(Fixture, "DeprecatedApi") {"Wait", {typeChecker.anyType, /* deprecated= */ true}}, }; - TypeId colorType = typeChecker.globalTypes.addType(TableTypeVar{{}, std::nullopt, typeChecker.globalScope->level, Luau::TableState::Sealed}); + TypeId colorType = typeChecker.globalTypes.addType(TableTypeVar{{}, std::nullopt, typeChecker.globalScope->level, lluz::TableState::Sealed}); getMutable(colorType)->props = {{"toHSV", {typeChecker.anyType, /* deprecated= */ true, "Color3:ToHSV"}}}; @@ -1465,9 +1465,9 @@ end )"); REQUIRE_EQ(result.warnings.size(), 3); - CHECK_EQ(result.warnings[0].text, "Member 'Instance.Wait' is deprecated"); - CHECK_EQ(result.warnings[1].text, "Member 'toHSV' is deprecated, use 'Color3:ToHSV' instead"); - CHECK_EQ(result.warnings[2].text, "Member 'Instance.DataCost' is deprecated"); + CHECK_EQ(result.warnings[0].text, XorStr("Member 'Instance.Wait' is deprecated")); + CHECK_EQ(result.warnings[1].text, XorStr("Member 'toHSV' is deprecated, use 'Color3:ToHSV' instead")); + CHECK_EQ(result.warnings[2].text, XorStr("Member 'Instance.DataCost' is deprecated")); } TEST_CASE_FIXTURE(BuiltinsFixture, "TableOperations") @@ -1499,20 +1499,20 @@ table.create(42, {} :: {}) REQUIRE_EQ(result.warnings.size(), 10); CHECK_EQ(result.warnings[0].text, "table.insert will insert the value before the last element, which is likely a bug; consider removing the " - "second argument or wrap it in parentheses to silence"); - CHECK_EQ(result.warnings[1].text, "table.insert will append the value to the table; consider removing the second argument for efficiency"); - CHECK_EQ(result.warnings[2].text, "table.insert uses index 0 but arrays are 1-based; did you mean 1 instead?"); - CHECK_EQ(result.warnings[3].text, "table.remove uses index 0 but arrays are 1-based; did you mean 1 instead?"); + XorStr("second argument or wrap it in parentheses to silence")); + CHECK_EQ(result.warnings[1].text, XorStr("table.insert will append the value to the table; consider removing the second argument for efficiency")); + CHECK_EQ(result.warnings[2].text, XorStr("table.insert uses index 0 but arrays are 1-based; did you mean 1 instead?")); + CHECK_EQ(result.warnings[3].text, XorStr("table.remove uses index 0 but arrays are 1-based; did you mean 1 instead?")); CHECK_EQ(result.warnings[4].text, "table.remove will remove the value before the last element, which is likely a bug; consider removing the " - "second argument or wrap it in parentheses to silence"); + XorStr("second argument or wrap it in parentheses to silence")); CHECK_EQ(result.warnings[5].text, - "table.insert may change behavior if the call returns more than one result; consider adding parentheses around second argument"); - CHECK_EQ(result.warnings[6].text, "table.move uses index 0 but arrays are 1-based; did you mean 1 instead?"); - CHECK_EQ(result.warnings[7].text, "table.move uses index 0 but arrays are 1-based; did you mean 1 instead?"); + XorStr("table.insert may change behavior if the call returns more than one result; consider adding parentheses around second argument")); + CHECK_EQ(result.warnings[6].text, XorStr("table.move uses index 0 but arrays are 1-based; did you mean 1 instead?")); + CHECK_EQ(result.warnings[7].text, XorStr("table.move uses index 0 but arrays are 1-based; did you mean 1 instead?")); CHECK_EQ( - result.warnings[8].text, "table.create with a table literal will reuse the same object for all elements; consider using a for loop instead"); + result.warnings[8].text, XorStr("table.create with a table literal will reuse the same object for all elements; consider using a for loop instead")); CHECK_EQ( - result.warnings[9].text, "table.create with a table literal will reuse the same object for all elements; consider using a for loop instead"); + result.warnings[9].text, XorStr("table.create with a table literal will reuse the same object for all elements; consider using a for loop instead")); } TEST_CASE_FIXTURE(Fixture, "DuplicateConditions") @@ -1543,16 +1543,16 @@ _ = if true then 1 elseif true then 2 else 3 )"); REQUIRE_EQ(result.warnings.size(), 8); - CHECK_EQ(result.warnings[0].text, "Condition has already been checked on line 2"); + CHECK_EQ(result.warnings[0].text, XorStr("Condition has already been checked on line 2")); CHECK_EQ(result.warnings[0].location.begin.line + 1, 4); - CHECK_EQ(result.warnings[1].text, "Condition has already been checked on column 5"); - CHECK_EQ(result.warnings[2].text, "Condition has already been checked on column 5"); - CHECK_EQ(result.warnings[3].text, "Condition has already been checked on column 6"); - CHECK_EQ(result.warnings[4].text, "Condition has already been checked on column 6"); - CHECK_EQ(result.warnings[5].text, "Condition has already been checked on column 6"); - CHECK_EQ(result.warnings[6].text, "Condition has already been checked on column 15"); + CHECK_EQ(result.warnings[1].text, XorStr("Condition has already been checked on column 5")); + CHECK_EQ(result.warnings[2].text, XorStr("Condition has already been checked on column 5")); + CHECK_EQ(result.warnings[3].text, XorStr("Condition has already been checked on column 6")); + CHECK_EQ(result.warnings[4].text, XorStr("Condition has already been checked on column 6")); + CHECK_EQ(result.warnings[5].text, XorStr("Condition has already been checked on column 6")); + CHECK_EQ(result.warnings[6].text, XorStr("Condition has already been checked on column 15")); CHECK_EQ(result.warnings[6].location.begin.line + 1, 19); - CHECK_EQ(result.warnings[7].text, "Condition has already been checked on column 8"); + CHECK_EQ(result.warnings[7].text, XorStr("Condition has already been checked on column 8")); } TEST_CASE_FIXTURE(Fixture, "DuplicateConditionsExpr") @@ -1567,7 +1567,7 @@ end )"); REQUIRE_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Condition has already been checked on line 4"); + CHECK_EQ(result.warnings[0].text, XorStr("Condition has already been checked on line 4")); CHECK_EQ(result.warnings[0].location.begin.line + 1, 5); } @@ -1588,10 +1588,10 @@ return foo, moo, a1, a2 )"); REQUIRE_EQ(result.warnings.size(), 4); - CHECK_EQ(result.warnings[0].text, "Function parameter 'a1' already defined on column 14"); - CHECK_EQ(result.warnings[1].text, "Variable 'a1' is never used; prefix with '_' to silence"); - CHECK_EQ(result.warnings[2].text, "Variable 'a1' already defined on column 7"); - CHECK_EQ(result.warnings[3].text, "Function parameter 'self' already defined implicitly"); + CHECK_EQ(result.warnings[0].text, XorStr("Function parameter 'a1' already defined on column 14")); + CHECK_EQ(result.warnings[1].text, XorStr("Variable 'a1' is never used; prefix with '_' to silence")); + CHECK_EQ(result.warnings[2].text, XorStr("Variable 'a1' already defined on column 7")); + CHECK_EQ(result.warnings[3].text, XorStr("Function parameter 'self' already defined implicitly")); } TEST_CASE_FIXTURE(Fixture, "MisleadingAndOr") @@ -1606,9 +1606,9 @@ _ = (math.random() < 0.5 and false) or 42 -- currently ignored REQUIRE_EQ(result.warnings.size(), 2); CHECK_EQ(result.warnings[0].text, "The and-or expression always evaluates to the second alternative because the first alternative is false; " - "consider using if-then-else expression instead"); + XorStr("consider using if-then-else expression instead")); CHECK_EQ(result.warnings[1].text, "The and-or expression always evaluates to the second alternative because the first alternative is nil; " - "consider using if-then-else expression instead"); + XorStr("consider using if-then-else expression instead")); } TEST_CASE_FIXTURE(Fixture, "WrongComment") @@ -1627,12 +1627,12 @@ do end )"); REQUIRE_EQ(result.warnings.size(), 6); - CHECK_EQ(result.warnings[0].text, "Unknown comment directive 'struct'; did you mean 'strict'?"); - CHECK_EQ(result.warnings[1].text, "Unknown comment directive 'nolintGlobal'"); - CHECK_EQ(result.warnings[2].text, "nolint directive refers to unknown lint rule 'Global'"); - CHECK_EQ(result.warnings[3].text, "nolint directive refers to unknown lint rule 'KnownGlobal'; did you mean 'UnknownGlobal'?"); - CHECK_EQ(result.warnings[4].text, "Comment directive with the type checking mode has extra symbols at the end of the line"); - CHECK_EQ(result.warnings[5].text, "Comment directive is ignored because it is placed after the first non-comment token"); + CHECK_EQ(result.warnings[0].text, XorStr("Unknown comment directive 'struct'; did you mean 'strict'?")); + CHECK_EQ(result.warnings[1].text, XorStr("Unknown comment directive 'nolintGlobal'")); + CHECK_EQ(result.warnings[2].text, XorStr("nolint directive refers to unknown lint rule 'Global'")); + CHECK_EQ(result.warnings[3].text, XorStr("nolint directive refers to unknown lint rule 'KnownGlobal'; did you mean 'UnknownGlobal'?")); + CHECK_EQ(result.warnings[4].text, XorStr("Comment directive with the type checking mode has extra symbols at the end of the line")); + CHECK_EQ(result.warnings[5].text, XorStr("Comment directive is ignored because it is placed after the first non-comment token")); } TEST_CASE_FIXTURE(Fixture, "WrongCommentMuteSelf") @@ -1655,24 +1655,7 @@ end )"); REQUIRE_EQ(result.warnings.size(), 1); - CHECK_EQ(result.warnings[0].text, "Condition has already been checked on line 2"); -} - -TEST_CASE_FIXTURE(Fixture, "WrongCommentOptimize") -{ - LintResult result = lint(R"( ---!optimize ---!optimize ---!optimize me ---!optimize 100500 ---!optimize 2 -)"); - - REQUIRE_EQ(result.warnings.size(), 4); - CHECK_EQ(result.warnings[0].text, "optimize directive requires an optimization level"); - CHECK_EQ(result.warnings[1].text, "optimize directive requires an optimization level"); - CHECK_EQ(result.warnings[2].text, "optimize directive uses unknown optimization level 'me', 0..2 expected"); - CHECK_EQ(result.warnings[3].text, "optimize directive uses unknown optimization level '100500', 0..2 expected"); + CHECK_EQ(result.warnings[0].text, XorStr("Condition has already been checked on line 2")); } TEST_SUITE_END(); diff --git a/tests/Module.test.cpp b/tests/Module.test.cpp index dd94e9d7..2827c9b0 100644 --- a/tests/Module.test.cpp +++ b/tests/Module.test.cpp @@ -1,18 +1,18 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Clone.h" -#include "Luau/Module.h" -#include "Luau/Scope.h" -#include "Luau/RecursionCounter.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Clone.h" +#include "lluz/Module.h" +#include "lluz/Scope.h" +#include "lluz/RecursionCounter.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(LuauLowerBoundsCalculation); +lluz_FASTFLAG(LluLowerBoundsCalculation); -TEST_SUITE_BEGIN("ModuleTests"); +TEST_SUITE_BEGIN(XorStr("ModuleTests")); TEST_CASE_FIXTURE(Fixture, "is_within_comment") { @@ -78,14 +78,14 @@ TEST_CASE_FIXTURE(Fixture, "deepClone_cyclic_table") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); /* The inferred type of Cyclic is {get: () -> Cyclic} * * Assert that the return type of get() is the same as the outer table. */ - TypeId counterType = requireType("Cyclic"); + TypeId counterType = requireType(XorStr("Cyclic")); TypeArena dest; CloneState cloneState; @@ -106,7 +106,7 @@ TEST_CASE_FIXTURE(Fixture, "deepClone_cyclic_table") REQUIRE(methodReturnType); CHECK_EQ(methodReturnType, counterCopy); - if (FFlag::LuauLowerBoundsCalculation) + if (FFlag::LluLowerBoundsCalculation) CHECK_EQ(3, dest.typePacks.size()); // function args, its return type, and the hidden any... pack else CHECK_EQ(2, dest.typePacks.size()); // one for the function args, and another for its return type @@ -119,9 +119,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "builtin_types_point_into_globalTypes_arena") return {sign=math.sign} )"); dumpErrors(result); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - ModulePtr module = frontend.moduleResolver.getModule("MainModule"); + ModulePtr module = frontend.moduleResolver.getModule(XorStr("MainModule")); std::optional exports = first(module->getModuleScope()->returnType); REQUIRE(bool(exports)); @@ -255,8 +255,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "clone_self_property") return a; )"; - CheckResult result = frontend.check("Module/A"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = frontend.check(XorStr("Module/A")); + lluz_REQUIRE_NO_ERRORS(result); fileResolver.source["Module/B"] = R"( --!nonstrict @@ -264,9 +264,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "clone_self_property") return a.foo(5) )"; - result = frontend.check("Module/B"); + result = frontend.check(XorStr("Module/B")); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("This function must be called with self. Did you mean to use a colon instead of a dot?", toString(result.errors[0])); } @@ -278,7 +278,7 @@ TEST_CASE_FIXTURE(Fixture, "clone_recursion_limit") #else int limit = 400; #endif - ScopedFastInt luauTypeCloneRecursionLimit{"LuauTypeCloneRecursionLimit", limit}; + ScopedFastInt lluzTypeCloneRecursionLimit{"lluzTypeCloneRecursionLimit", limit}; TypeArena src; @@ -301,6 +301,8 @@ TEST_CASE_FIXTURE(Fixture, "clone_recursion_limit") TEST_CASE_FIXTURE(Fixture, "any_persistance_does_not_leak") { + ScopedFastFlag lluzNonCopyableTypeVarFields{"lluzNonCopyableTypeVarFields", true}; + fileResolver.source["Module/A"] = R"( export type A = B type B = A @@ -309,12 +311,12 @@ type B = A FrontendOptions opts; opts.retainFullTypeGraphs = false; CheckResult result = frontend.check("Module/A", opts); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); - auto mod = frontend.moduleResolver.getModule("Module/A"); - auto it = mod->getModuleScope()->exportedTypeBindings.find("A"); + auto mod = frontend.moduleResolver.getModule(XorStr("Module/A")); + auto it = mod->getModuleScope()->exportedTypeBindings.find(XorStr("A")); REQUIRE(it != mod->getModuleScope()->exportedTypeBindings.end()); - CHECK(toString(it->second.type) == "any"); + CHECK(toString(it->second.type) == XorStr("any")); } TEST_SUITE_END(); diff --git a/tests/NonstrictMode.test.cpp b/tests/NonstrictMode.test.cpp index 02e02e6b..d1e0e7ed 100644 --- a/tests/NonstrictMode.test.cpp +++ b/tests/NonstrictMode.test.cpp @@ -1,7 +1,7 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "Fixture.h" @@ -9,9 +9,80 @@ #include -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("NonstrictModeTests"); +TEST_SUITE_BEGIN(XorStr("NonstrictModeTests")); + +TEST_CASE_FIXTURE(Fixture, "globals") +{ + CheckResult result = check(R"( + --!nonstrict + foo = true + foo = "now i'm a string!" + )"); + + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ("any", toString(requireType("foo"))); +} + +TEST_CASE_FIXTURE(Fixture, "globals2") +{ + ScopedFastFlag sff[]{ + {"lluzReturnTypeInferenceInNonstrict", true}, + {"lluzLowerBoundsCalculation", true}, + }; + + CheckResult result = check(R"( + --!nonstrict + foo = function() return 1 end + foo = "now i'm a string!" + )"); + + lluz_REQUIRE_ERROR_COUNT(1, result); + + TypeMismatch* tm = get(result.errors[0]); + REQUIRE(tm); + CHECK_EQ("() -> number", toString(tm->wantedType)); + CHECK_EQ("string", toString(tm->givenType)); + CHECK_EQ("() -> number", toString(requireType("foo"))); +} + +TEST_CASE_FIXTURE(Fixture, "globals_everywhere") +{ + CheckResult result = check(R"( + --!nonstrict + foo = 1 + + if true then + bar = 2 + end + )"); + + lluz_REQUIRE_NO_ERRORS(result); + + CHECK_EQ("any", toString(requireType("foo"))); + CHECK_EQ("any", toString(requireType("bar"))); +} + +TEST_CASE_FIXTURE(BuiltinsFixture, "function_returns_number_or_string") +{ + ScopedFastFlag sff[]{{"lluzReturnTypeInferenceInNonstrict", true}, {"lluzLowerBoundsCalculation", true}}; + + CheckResult result = check(R"( + --!nonstrict + local function f() + if math.random() > 0.5 then + return 5 + else + return XorStr("hi") + end + end + )"); + + lluz_REQUIRE_NO_ERRORS(result); + + CHECK("() -> number | string" == toString(requireType("f"))); +} TEST_CASE_FIXTURE(Fixture, "infer_nullary_function") { @@ -20,7 +91,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_nullary_function") function foo(x, y) end )"); - TypeId fooType = requireType("foo"); + TypeId fooType = requireType(XorStr("foo")); REQUIRE(fooType); const FunctionTypeVar* ftv = get(fooType); @@ -35,8 +106,13 @@ TEST_CASE_FIXTURE(Fixture, "infer_nullary_function") REQUIRE_EQ(0, rets.size()); } -TEST_CASE_FIXTURE(Fixture, "infer_the_maximum_number_of_values_the_function_could_return") +TEST_CASE_FIXTURE(Fixture, "first_return_type_dictates_number_of_return_types") { + ScopedFastFlag sff[]{ + {"lluzReturnTypeInferenceInNonstrict", true}, + {"lluzLowerBoundsCalculation", true}, + }; + CheckResult result = check(R"( --!nonstrict function getMinCardCountForWidth(width) @@ -48,25 +124,21 @@ TEST_CASE_FIXTURE(Fixture, "infer_the_maximum_number_of_values_the_function_coul end )"); - TypeId t = requireType("getMinCardCountForWidth"); + TypeId t = requireType(XorStr("getMinCardCountForWidth")); REQUIRE(t); - REQUIRE_EQ("(any) -> (...any)", toString(t)); + REQUIRE_EQ("(any) -> number", toString(t)); } -#if 0 -// Maybe we want this? TEST_CASE_FIXTURE(Fixture, "return_annotation_is_still_checked") { CheckResult result = check(R"( + --!nonstrict function foo(x): number return 'hello' end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - - REQUIRE_NE(*typeChecker.anyType, *requireType("foo")); + lluz_REQUIRE_ERROR_COUNT(1, result); } -#endif TEST_CASE_FIXTURE(Fixture, "function_parameters_are_any") { @@ -78,7 +150,7 @@ TEST_CASE_FIXTURE(Fixture, "function_parameters_are_any") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "inconsistent_return_types_are_ok") @@ -95,7 +167,7 @@ TEST_CASE_FIXTURE(Fixture, "inconsistent_return_types_are_ok") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "locals_are_any_by_default") @@ -105,7 +177,7 @@ TEST_CASE_FIXTURE(Fixture, "locals_are_any_by_default") local m = 55 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.anyType, *requireType("m")); } @@ -121,7 +193,7 @@ TEST_CASE_FIXTURE(Fixture, "parameters_having_type_any_are_optional") f(5) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "local_tables_are_not_any") @@ -136,7 +208,7 @@ TEST_CASE_FIXTURE(Fixture, "local_tables_are_not_any") T:staticmethod() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("This function does not take self. Did you mean to use a dot instead of a colon?", toString(result.errors[0])); } @@ -150,7 +222,7 @@ TEST_CASE_FIXTURE(Fixture, "offer_a_hint_if_you_use_a_dot_instead_of_a_colon") T.method(5) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("This function must be called with self. Did you mean to use a colon instead of a dot?", toString(result.errors[0])); } @@ -163,7 +235,7 @@ TEST_CASE_FIXTURE(Fixture, "table_props_are_any") T.foo = 55 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); TableTypeVar* ttv = getMutable(requireType("T")); @@ -186,7 +258,7 @@ TEST_CASE_FIXTURE(Fixture, "inline_table_props_are_also_any") } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); TableTypeVar* ttv = getMutable(requireType("T")); REQUIRE_MESSAGE(ttv, "Should be a table: " << toString(requireType("T"))); @@ -212,7 +284,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_iterator_variables_are_any") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "table_dot_insert_and_recursive_calls") @@ -223,7 +295,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_dot_insert_and_recursive_calls") local newList = {} for _, value in ipairs(list) do - if type(value) == "table" then + if type(value) == XorStr("table") then table.insert(newList, populateListFromIds(value, normalizedData)) else table.insert(newList, normalizedData[value]) @@ -234,7 +306,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_dot_insert_and_recursive_calls") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "delay_function_does_not_require_its_argument_to_return_anything") @@ -247,11 +319,16 @@ TEST_CASE_FIXTURE(Fixture, "delay_function_does_not_require_its_argument_to_retu delay(50, function() end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "inconsistent_module_return_types_are_ok") { + ScopedFastFlag sff[]{ + {"lluzReturnTypeInferenceInNonstrict", true}, + {"lluzLowerBoundsCalculation", true}, + }; + CheckResult result = check(R"( --!nonstrict @@ -266,9 +343,9 @@ TEST_CASE_FIXTURE(Fixture, "inconsistent_module_return_types_are_ok") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - REQUIRE_EQ("any", toString(getMainModule()->getModuleScope()->returnType)); + REQUIRE_EQ("((any) -> string) | {| foo: any |}", toString(getMainModule()->getModuleScope()->returnType)); } TEST_CASE_FIXTURE(Fixture, "returning_insufficient_return_values") @@ -285,7 +362,7 @@ TEST_CASE_FIXTURE(Fixture, "returning_insufficient_return_values") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "returning_too_many_values") @@ -302,7 +379,7 @@ TEST_CASE_FIXTURE(Fixture, "returning_too_many_values") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_SUITE_END(); diff --git a/tests/Normalize.test.cpp b/tests/Normalize.test.cpp index 84a5a380..6ef7c177 100644 --- a/tests/Normalize.test.cpp +++ b/tests/Normalize.test.cpp @@ -1,17 +1,17 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #include "Fixture.h" #include "doctest.h" -#include "Luau/Normalize.h" -#include "Luau/BuiltinDefinitions.h" +#include "lluz/Normalize.h" +#include "lluz/BuiltinDefinitions.h" -using namespace Luau; +using namespace lluz; struct NormalizeFixture : Fixture { - ScopedFastFlag sff1{"LuauLowerBoundsCalculation", true}; + ScopedFastFlag sff1{"lluzLowerBoundsCalculation", true}; }; void createSomeClasses(TypeChecker& typeChecker) @@ -55,7 +55,7 @@ static bool isSubtype(TypeId a, TypeId b) return isSubtype(a, b, ice); } -TEST_SUITE_BEGIN("isSubtype"); +TEST_SUITE_BEGIN(XorStr("isSubtype")); TEST_CASE_FIXTURE(NormalizeFixture, "primitives") { @@ -67,10 +67,10 @@ TEST_CASE_FIXTURE(NormalizeFixture, "primitives") local d = "world" )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); - TypeId c = requireType("c"); - TypeId d = requireType("d"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); + TypeId c = requireType(XorStr("c")); + TypeId d = requireType(XorStr("d")); CHECK(isSubtype(b, a)); CHECK(isSubtype(d, c)); @@ -87,10 +87,10 @@ TEST_CASE_FIXTURE(NormalizeFixture, "functions") function d(x: number): number? return x end )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); - TypeId c = requireType("c"); - TypeId d = requireType("d"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); + TypeId c = requireType(XorStr("c")); + TypeId d = requireType(XorStr("d")); CHECK(isSubtype(b, a)); CHECK(isSubtype(c, a)); @@ -101,12 +101,12 @@ TEST_CASE_FIXTURE(NormalizeFixture, "functions") TEST_CASE_FIXTURE(NormalizeFixture, "functions_and_any") { check(R"( - function a(n: number) return "string" end + function a(n: number) return XorStr("string") end function b(q: any) return 5 :: any end )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); // Intuition: // We cannot use b where a is required because we cannot rely on b to return a string. @@ -128,8 +128,8 @@ TEST_CASE_FIXTURE(NormalizeFixture, "intersection_of_functions_of_different_arit local t: T )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); CHECK(!isSubtype(a, b)); // !! CHECK(!isSubtype(b, a)); @@ -146,9 +146,9 @@ TEST_CASE_FIXTURE(NormalizeFixture, "functions_with_mismatching_arity") local c: () -> number )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); - TypeId c = requireType("c"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); + TypeId c = requireType(XorStr("c")); CHECK(!isSubtype(b, a)); CHECK(!isSubtype(c, a)); @@ -178,9 +178,9 @@ TEST_CASE_FIXTURE(NormalizeFixture, "functions_with_mismatching_arity_but_option local c: (number, number?) -> () )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); - TypeId c = requireType("c"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); + TypeId c = requireType(XorStr("c")); /* * (number) -> () () @@ -228,9 +228,9 @@ TEST_CASE_FIXTURE(NormalizeFixture, "functions_with_mismatching_arity_but_any_is local c: (number, any) -> () )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); - TypeId c = requireType("c"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); + TypeId c = requireType(XorStr("c")); /* * (number) -> () () @@ -276,8 +276,8 @@ TEST_CASE_FIXTURE(NormalizeFixture, "variadic_functions_with_no_head") local b: (...number?) -> () )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); CHECK(isSubtype(b, a)); CHECK(!isSubtype(a, b)); @@ -291,8 +291,8 @@ TEST_CASE_FIXTURE(NormalizeFixture, "variadic_function_with_head") local b: (number, number) -> () )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); CHECK(!isSubtype(b, a)); CHECK(isSubtype(a, b)); @@ -308,10 +308,10 @@ TEST_CASE_FIXTURE(NormalizeFixture, "union") local d: number? )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); - TypeId c = requireType("c"); - TypeId d = requireType("d"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); + TypeId c = requireType(XorStr("c")); + TypeId d = requireType(XorStr("d")); CHECK(isSubtype(b, a)); CHECK(!isSubtype(a, b)); @@ -333,8 +333,8 @@ TEST_CASE_FIXTURE(NormalizeFixture, "table_with_union_prop") local b: {x: number?} )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); CHECK(isSubtype(a, b)); CHECK(!isSubtype(b, a)); @@ -347,8 +347,8 @@ TEST_CASE_FIXTURE(NormalizeFixture, "table_with_any_prop") local b: {x: any} )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); CHECK(isSubtype(a, b)); CHECK(!isSubtype(b, a)); @@ -363,10 +363,10 @@ TEST_CASE_FIXTURE(NormalizeFixture, "intersection") local d: number & nil )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); - TypeId c = requireType("c"); - TypeId d = requireType("d"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); + TypeId c = requireType(XorStr("c")); + TypeId d = requireType(XorStr("d")); CHECK(!isSubtype(b, a)); CHECK(isSubtype(a, b)); @@ -385,8 +385,8 @@ TEST_CASE_FIXTURE(NormalizeFixture, "union_and_intersection") local b: number | nil )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); CHECK(!isSubtype(b, a)); CHECK(isSubtype(a, b)); @@ -411,10 +411,10 @@ TEST_CASE_FIXTURE(NormalizeFixture, "tables") local d: {x: number, y: number} )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); - TypeId c = requireType("c"); - TypeId d = requireType("d"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); + TypeId c = requireType(XorStr("c")); + TypeId d = requireType(XorStr("d")); CHECK(isSubtype(a, b)); CHECK(!isSubtype(b, a)); @@ -438,9 +438,9 @@ TEST_CASE_FIXTURE(NormalizeFixture, "table_indexers_are_invariant") local c: {[string]: number} )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); - TypeId c = requireType("c"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); + TypeId c = requireType(XorStr("c")); CHECK(!isSubtype(b, a)); CHECK(!isSubtype(a, b)); @@ -457,9 +457,9 @@ TEST_CASE_FIXTURE(NormalizeFixture, "mismatched_indexers") local c: {} )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); - TypeId c = requireType("c"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); + TypeId c = requireType(XorStr("c")); CHECK(isSubtype(b, a)); CHECK(!isSubtype(a, b)); @@ -487,11 +487,11 @@ TEST_CASE_FIXTURE(NormalizeFixture, "cyclic_table") local e: E )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); - TypeId c = requireType("c"); - TypeId d = requireType("d"); - TypeId e = requireType("e"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); + TypeId c = requireType(XorStr("c")); + TypeId d = requireType(XorStr("d")); + TypeId e = requireType(XorStr("e")); CHECK(isSubtype(b, a)); CHECK(!isSubtype(a, b)); @@ -537,8 +537,8 @@ TEST_CASE_FIXTURE(NormalizeFixture, "metatable" * doctest::expected_failures{1}) local b: {method: (any) -> ()} )"); - TypeId a = requireType("a"); - TypeId b = requireType("b"); + TypeId a = requireType(XorStr("a")); + TypeId b = requireType(XorStr("b")); CHECK(isSubtype(a, b)); } @@ -556,7 +556,7 @@ TEST_CASE_FIXTURE(NormalizeFixture, "intersection_of_tables") TEST_SUITE_END(); -TEST_SUITE_BEGIN("Normalize"); +TEST_SUITE_BEGIN(XorStr("Normalize")); TEST_CASE_FIXTURE(NormalizeFixture, "intersection_of_disjoint_tables") { @@ -601,7 +601,7 @@ TEST_CASE_FIXTURE(NormalizeFixture, "union_with_overlapping_field_that_has_a_sub ModulePtr mainModule = getMainModule(); unfreeze(mainModule->internalTypes); - TypeId tType = requireType("t"); + TypeId tType = requireType(XorStr("t")); normalize(tType, tempModule, *typeChecker.iceHandler); CHECK_EQ("{| x: number? |}", toString(tType, {true})); @@ -620,7 +620,8 @@ TEST_CASE_FIXTURE(NormalizeFixture, "intersection_of_functions") TEST_CASE_FIXTURE(Fixture, "normalize_module_return_type") { ScopedFastFlag sff[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, + {"lluzReturnTypeInferenceInNonstrict", true}, }; check(R"( @@ -641,7 +642,7 @@ TEST_CASE_FIXTURE(Fixture, "normalize_module_return_type") end )"); - CHECK_EQ("(any, any) -> (...any)", toString(getMainModule()->getModuleScope()->returnType)); + CHECK_EQ("(any, any) -> (any, any) -> any", toString(getMainModule()->getModuleScope()->returnType)); } TEST_CASE_FIXTURE(Fixture, "return_type_is_not_a_constrained_intersection") @@ -665,7 +666,7 @@ TEST_CASE_FIXTURE(Fixture, "higher_order_function") local a = apply(function(x: number) return x + x end, 5) )"); - TypeId aType = requireType("a"); + TypeId aType = requireType(XorStr("a")); CHECK_MESSAGE(isNumber(follow(aType)), "Expected a number but got ", toString(aType)); } @@ -682,7 +683,7 @@ TEST_CASE_FIXTURE(Fixture, "higher_order_function_with_annotation") TEST_CASE_FIXTURE(Fixture, "cyclic_table_is_marked_normal") { - ScopedFastFlag flags[] = {{"LuauLowerBoundsCalculation", true}, {"LuauNormalizeFlagIsConservative", false}}; + ScopedFastFlag flags[] = {{"lluzLowerBoundsCalculation", true}, {"lluzNormalizeFlagIsConservative", false}}; check(R"( type Fiber = { @@ -692,14 +693,14 @@ TEST_CASE_FIXTURE(Fixture, "cyclic_table_is_marked_normal") local f: Fiber )"); - TypeId t = requireType("f"); + TypeId t = requireType(XorStr("f")); CHECK(t->normal); } // Unfortunately, getting this right in the general case is difficult. TEST_CASE_FIXTURE(Fixture, "cyclic_table_is_not_marked_normal") { - ScopedFastFlag flags[] = {{"LuauLowerBoundsCalculation", true}, {"LuauNormalizeFlagIsConservative", true}}; + ScopedFastFlag flags[] = {{"lluzLowerBoundsCalculation", true}, {"lluzNormalizeFlagIsConservative", true}}; check(R"( type Fiber = { @@ -709,14 +710,14 @@ TEST_CASE_FIXTURE(Fixture, "cyclic_table_is_not_marked_normal") local f: Fiber )"); - TypeId t = requireType("f"); + TypeId t = requireType(XorStr("f")); CHECK(!t->normal); } TEST_CASE_FIXTURE(Fixture, "variadic_tail_is_marked_normal") { ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( @@ -725,9 +726,9 @@ TEST_CASE_FIXTURE(Fixture, "variadic_tail_is_marked_normal") local w: Weirdo )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId t = requireType("w"); + TypeId t = requireType(XorStr("w")); auto ftv = get(t); REQUIRE(ftv); @@ -749,75 +750,16 @@ TEST_CASE_FIXTURE(Fixture, "cyclic_table_normalizes_sensibly") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId ty = requireType("Cyclic"); + TypeId ty = requireType(XorStr("Cyclic")); CHECK_EQ("t1 where t1 = { get: () -> t1 }", toString(ty, {true})); } -TEST_CASE_FIXTURE(Fixture, "cyclic_union") -{ - ScopedFastFlag sff[] = { - {"LuauLowerBoundsCalculation", true}, - {"LuauFixNormalizationOfCyclicUnions", true}, - }; - - CheckResult result = check(R"( - type T = {T?}? - - local a: T - )"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK("t1? where t1 = {t1?}" == toString(requireType("a"))); -} - -TEST_CASE_FIXTURE(Fixture, "cyclic_intersection") -{ - ScopedFastFlag sff[] = { - {"LuauLowerBoundsCalculation", true}, - {"LuauFixNormalizationOfCyclicUnions", true}, - }; - - CheckResult result = check(R"( - type T = {T & {}} - - local a: T - )"); - - LUAU_REQUIRE_NO_ERRORS(result); - - // FIXME: We are not properly normalizing this type, but we are at least not improperly discarding information - CHECK("t1 where t1 = {{t1 & {| |}}}" == toString(requireType("a"), {true})); -} - -TEST_CASE_FIXTURE(Fixture, "intersection_of_tables_with_indexers") -{ - ScopedFastFlag sff[] = { - {"LuauLowerBoundsCalculation", true}, - {"LuauFixNormalizationOfCyclicUnions", true}, - }; - - CheckResult result = check(R"( - type A = {number} - type B = {string} - - type C = A & B - - local a: C - )"); - - LUAU_REQUIRE_NO_ERRORS(result); - - // FIXME: We are not properly normalizing this type, but we are at least not improperly discarding information - CHECK("{number & string}" == toString(requireType("a"), {true})); -} - TEST_CASE_FIXTURE(BuiltinsFixture, "union_of_distinct_free_types") { ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( @@ -830,7 +772,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "union_of_distinct_free_types") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK("(a, b) -> a | b" == toString(requireType("fussy"))); } @@ -838,7 +780,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "union_of_distinct_free_types") TEST_CASE_FIXTURE(BuiltinsFixture, "constrained_intersection_of_intersections") { ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( @@ -854,9 +796,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "constrained_intersection_of_intersections") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId h = requireType("h"); + TypeId h = requireType(XorStr("h")); CHECK("() -> (() -> number) | ((number) -> number) | ((string) -> number)" == toString(h)); } @@ -864,7 +806,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "constrained_intersection_of_intersections") TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersection") { ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( @@ -881,7 +823,7 @@ TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersect local t: T )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK("{| |}" == toString(requireType("x"), {true})); CHECK("{| y: number |}" == toString(requireType("y"), {true})); @@ -893,8 +835,8 @@ TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersect TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersection_2") { ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, - {"LuauQuantifyConstrained", true}, + {"lluzLowerBoundsCalculation", true}, + {"lluzQuantifyConstrained", true}, }; // We use a function and inferred parameter types to prevent intermediate normalizations from being performed. @@ -911,9 +853,9 @@ TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersect end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId t = requireType("strange"); + TypeId t = requireType(XorStr("strange")); auto ftv = get(t); REQUIRE(ftv != nullptr); @@ -934,8 +876,8 @@ TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersect TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersection_3") { ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, - {"LuauQuantifyConstrained", true}, + {"lluzLowerBoundsCalculation", true}, + {"lluzQuantifyConstrained", true}, }; // We use a function and inferred parameter types to prevent intermediate normalizations from being performed. @@ -952,9 +894,9 @@ TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersect end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId t = requireType("strange"); + TypeId t = requireType(XorStr("strange")); auto ftv = get(t); REQUIRE(ftv != nullptr); @@ -974,8 +916,8 @@ TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersect TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersection_4") { ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, - {"LuauQuantifyConstrained", true}, + {"lluzLowerBoundsCalculation", true}, + {"lluzQuantifyConstrained", true}, }; // We use a function and inferred parameter types to prevent intermediate normalizations from being performed. @@ -994,9 +936,9 @@ TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersect end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId t = requireType("strange"); + TypeId t = requireType(XorStr("strange")); auto ftv = get(t); REQUIRE(ftv != nullptr); @@ -1016,8 +958,8 @@ TEST_CASE_FIXTURE(Fixture, "intersection_inside_a_table_inside_another_intersect TEST_CASE_FIXTURE(Fixture, "nested_table_normalization_with_non_table__no_ice") { ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, - {"LuauNormalizeCombineTableFix", true}, + {"lluzLowerBoundsCalculation", true}, + {"lluzNormalizeCombineTableFix", true}, }; // CLI-52787 // ends up combining {_:any} with any, recursively @@ -1026,12 +968,12 @@ TEST_CASE_FIXTURE(Fixture, "nested_table_normalization_with_non_table__no_ice") export type t0 = any & { _: {_:any} } & { _:any } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "visiting_a_type_twice_is_not_considered_normal") { - ScopedFastFlag sff{"LuauLowerBoundsCalculation", true}; + ScopedFastFlag sff{"lluzLowerBoundsCalculation", true}; CheckResult result = check(R"( --!strict @@ -1046,33 +988,33 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "visiting_a_type_twice_is_not_considered_norm end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("(() -> a, a) -> ()", toString(requireType("f"))); } TEST_CASE_FIXTURE(Fixture, "fuzz_failure_instersection_combine_must_follow") { ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( export type t0 = {_:{_:any} & {_:any|string}} & {_:{_:{}}} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "fuzz_failure_bound_type_is_normal_but_not_its_bounded_to") { - ScopedFastFlag sff{"LuauLowerBoundsCalculation", true}; + ScopedFastFlag sff{"lluzLowerBoundsCalculation", true}; CheckResult result = check(R"( type t252 = ((t0)|(any))|(any) type t0 = t252,t24...> )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } // We had an issue where a normal BoundTypeVar might point at a non-normal BoundTypeVar if it in turn pointed to a @@ -1080,8 +1022,8 @@ TEST_CASE_FIXTURE(Fixture, "fuzz_failure_bound_type_is_normal_but_not_its_bounde TEST_CASE_FIXTURE(Fixture, "bound_typevars_should_only_be_marked_normal_if_their_pointee_is_normal") { ScopedFastFlag sff[]{ - {"LuauLowerBoundsCalculation", true}, - {"LuauNormalizeFlagIsConservative", true}, + {"lluzLowerBoundsCalculation", true}, + {"lluzNormalizeFlagIsConservative", true}, }; CheckResult result = check(R"( @@ -1108,63 +1050,25 @@ export type t0 = { a: Child } export type t1 = { a: typeof(string.byte) } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "intersection_combine_on_bound_self") { + ScopedFastFlag lluzNormalizeCombineEqFix{"lluzNormalizeCombineEqFix", true}; + CheckResult result = check(R"( export type t0 = (((any)&({_:l0.t0,n0:t0,_G:any,}))&({_:any,}))&(((any)&({_:l0.t0,n0:t0,_G:any,}))&({_:any,})) )"); - LUAU_REQUIRE_ERRORS(result); -} - -TEST_CASE_FIXTURE(Fixture, "normalize_unions_containing_never") -{ - ScopedFastFlag sff{"LuauLowerBoundsCalculation", true}; - - CheckResult result = check(R"( - type Foo = string | never - local foo: Foo - )"); - - CHECK_EQ("string", toString(requireType("foo"))); -} - -TEST_CASE_FIXTURE(Fixture, "normalize_unions_containing_unknown") -{ - ScopedFastFlag sff{"LuauLowerBoundsCalculation", true}; - - CheckResult result = check(R"( - type Foo = string | unknown - local foo: Foo - )"); - - CHECK_EQ("unknown", toString(requireType("foo"))); -} - -TEST_CASE_FIXTURE(Fixture, "any_wins_the_battle_over_unknown_in_unions") -{ - ScopedFastFlag sff{"LuauLowerBoundsCalculation", true}; - - CheckResult result = check(R"( - type Foo = unknown | any - local foo: Foo - - type Bar = any | unknown - local bar: Bar - )"); - - CHECK_EQ("any", toString(requireType("foo"))); - CHECK_EQ("any", toString(requireType("bar"))); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "normalization_does_not_convert_ever") { ScopedFastFlag sff[]{ - {"LuauLowerBoundsCalculation", true}, - {"LuauQuantifyConstrained", true}, + {"lluzLowerBoundsCalculation", true}, + {"lluzQuantifyConstrained", true}, }; CheckResult result = check(R"( @@ -1175,13 +1079,13 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "normalization_does_not_convert_ever") end type Ret = typeof(f()) if math.random() > 0.5 then - return "something" + return XorStr("something") end - return "something" :: Ret + return XorStr("something") :: Ret end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("() -> boolean | string", toString(requireType("f"))); } diff --git a/tests/NotNull.test.cpp b/tests/NotNull.test.cpp index e77ba78a..57b91648 100644 --- a/tests/NotNull.test.cpp +++ b/tests/NotNull.test.cpp @@ -1,4 +1,4 @@ -#include "Luau/NotNull.h" +#include "lluz/NotNull.h" #include "doctest.h" @@ -6,7 +6,7 @@ #include #include -using Luau::NotNull; +using lluz::NotNull; namespace { @@ -39,7 +39,7 @@ int foo(NotNull p) void bar(int* q) {} -TEST_SUITE_BEGIN("NotNull"); +TEST_SUITE_BEGIN(XorStr("NotNull")); TEST_CASE("basic_stuff") { diff --git a/tests/Parser.test.cpp b/tests/Parser.test.cpp index c5c019aa..34a856f9 100644 --- a/tests/Parser.test.cpp +++ b/tests/Parser.test.cpp @@ -1,5 +1,5 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Parser.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Parser.h" #include "Fixture.h" #include "ScopedFlags.h" @@ -8,7 +8,7 @@ #include -using namespace Luau; +using namespace lluz; namespace { @@ -37,39 +37,39 @@ std::string getParseError(const std::string& code) { f.parse(code); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { // in general, tests check only the first error return e.getErrors().front().getMessage(); } - throw std::runtime_error("Expected a parse error in '" + code + "'"); + throw std::runtime_error(XorStr("Expected a parse error in '" + code + "'")); } } // namespace -TEST_SUITE_BEGIN("AllocatorTests"); +TEST_SUITE_BEGIN(XorStr("AllocatorTests")); TEST_CASE("allocator_can_be_moved") { Counter* c = nullptr; auto inner = [&]() { - Luau::Allocator allocator; + lluz::Allocator allocator; c = allocator.alloc(); - Luau::Allocator moved{std::move(allocator)}; + lluz::Allocator moved{std::move(allocator)}; return moved; }; Counter::instanceCount = 0; - Luau::Allocator a{inner()}; + lluz::Allocator a{inner()}; CHECK_EQ(1, c->id); } TEST_CASE("moved_out_Allocator_can_still_be_used") { - Luau::Allocator outer; - Luau::Allocator inner{std::move(outer)}; + lluz::Allocator outer; + lluz::Allocator inner{std::move(outer)}; int* i = outer.alloc(); REQUIRE(i != nullptr); @@ -79,7 +79,7 @@ TEST_CASE("moved_out_Allocator_can_still_be_used") TEST_CASE("aligns_things") { - Luau::Allocator alloc; + lluz::Allocator alloc; char* one = alloc.alloc(); double* two = alloc.alloc(); @@ -89,7 +89,7 @@ TEST_CASE("aligns_things") TEST_CASE("initial_double_is_aligned") { - Luau::Allocator alloc; + lluz::Allocator alloc; double* one = alloc.alloc(); CHECK_EQ(0, reinterpret_cast(one) & (alignof(double) - 1)); @@ -97,23 +97,155 @@ TEST_CASE("initial_double_is_aligned") TEST_SUITE_END(); -TEST_SUITE_BEGIN("ParserTests"); +TEST_SUITE_BEGIN(XorStr("LexerTests")); + +TEST_CASE("broken_string_works") +{ + const std::string testInput = "[["; + lluz::Allocator alloc; + AstNameTable table(alloc); + Lexer lexer(testInput.c_str(), testInput.size(), table); + Lexeme lexeme = lexer.next(); + CHECK_EQ(lexeme.type, Lexeme::Type::BrokenString); + CHECK_EQ(lexeme.location, lluz::Location(lluz::Position(0, 0), lluz::Position(0, 2))); +} + +TEST_CASE("broken_comment") +{ + const std::string testInput = "--[[ "; + lluz::Allocator alloc; + AstNameTable table(alloc); + Lexer lexer(testInput.c_str(), testInput.size(), table); + Lexeme lexeme = lexer.next(); + CHECK_EQ(lexeme.type, Lexeme::Type::BrokenComment); + CHECK_EQ(lexeme.location, lluz::Location(lluz::Position(0, 0), lluz::Position(0, 6))); +} + +TEST_CASE("broken_comment_kept") +{ + const std::string testInput = "--[[ "; + lluz::Allocator alloc; + AstNameTable table(alloc); + Lexer lexer(testInput.c_str(), testInput.size(), table); + lexer.setSkipComments(true); + CHECK_EQ(lexer.next().type, Lexeme::Type::BrokenComment); +} + +TEST_CASE("comment_skipped") +{ + const std::string testInput = "-- "; + lluz::Allocator alloc; + AstNameTable table(alloc); + Lexer lexer(testInput.c_str(), testInput.size(), table); + lexer.setSkipComments(true); + CHECK_EQ(lexer.next().type, Lexeme::Type::Eof); +} + +TEST_CASE("multilineCommentWithLexemeInAndAfter") +{ + const std::string testInput = "--[[ function \n" + "]] end"; + lluz::Allocator alloc; + AstNameTable table(alloc); + Lexer lexer(testInput.c_str(), testInput.size(), table); + Lexeme comment = lexer.next(); + Lexeme end = lexer.next(); + + CHECK_EQ(comment.type, Lexeme::Type::BlockComment); + CHECK_EQ(comment.location, lluz::Location(lluz::Position(0, 0), lluz::Position(1, 2))); + CHECK_EQ(end.type, Lexeme::Type::ReservedEnd); + CHECK_EQ(end.location, lluz::Location(lluz::Position(1, 3), lluz::Position(1, 6))); +} + +TEST_CASE("testBrokenEscapeTolerant") +{ + const std::string testInput = "'\\3729472897292378'"; + lluz::Allocator alloc; + AstNameTable table(alloc); + Lexer lexer(testInput.c_str(), testInput.size(), table); + Lexeme item = lexer.next(); + + CHECK_EQ(item.type, Lexeme::QuotedString); + CHECK_EQ(item.location, lluz::Location(lluz::Position(0, 0), lluz::Position(0, int(testInput.size())))); +} + +TEST_CASE("testBigDelimiters") +{ + const std::string testInput = "--[===[\n" + "\n" + "\n" + "\n" + "]===]"; + lluz::Allocator alloc; + AstNameTable table(alloc); + Lexer lexer(testInput.c_str(), testInput.size(), table); + Lexeme item = lexer.next(); + + CHECK_EQ(item.type, Lexeme::Type::BlockComment); + CHECK_EQ(item.location, lluz::Location(lluz::Position(0, 0), lluz::Position(4, 5))); +} + +TEST_CASE("lookahead") +{ + const std::string testInput = "foo --[[ comment ]] bar : nil end"; + + lluz::Allocator alloc; + AstNameTable table(alloc); + Lexer lexer(testInput.c_str(), testInput.size(), table); + lexer.setSkipComments(true); + lexer.next(); // must call next() before reading data from lexer at least once + + CHECK_EQ(lexer.current().type, Lexeme::Name); + CHECK_EQ(lexer.current().name, std::string("foo")); + CHECK_EQ(lexer.lookahead().type, Lexeme::Name); + CHECK_EQ(lexer.lookahead().name, std::string("bar")); + + lexer.next(); + + CHECK_EQ(lexer.current().type, Lexeme::Name); + CHECK_EQ(lexer.current().name, std::string("bar")); + CHECK_EQ(lexer.lookahead().type, ':'); + + lexer.next(); + + CHECK_EQ(lexer.current().type, ':'); + CHECK_EQ(lexer.lookahead().type, Lexeme::ReservedNil); + + lexer.next(); + + CHECK_EQ(lexer.current().type, Lexeme::ReservedNil); + CHECK_EQ(lexer.lookahead().type, Lexeme::ReservedEnd); + + lexer.next(); + + CHECK_EQ(lexer.current().type, Lexeme::ReservedEnd); + CHECK_EQ(lexer.lookahead().type, Lexeme::Eof); + + lexer.next(); + + CHECK_EQ(lexer.current().type, Lexeme::Eof); + CHECK_EQ(lexer.lookahead().type, Lexeme::Eof); +} + +TEST_SUITE_END(); + +TEST_SUITE_BEGIN(XorStr("ParserTests")); TEST_CASE_FIXTURE(Fixture, "basic_parse") { - AstStat* stat = parse("print(\"Hello World!\")"); + AstStat* stat = parse(XorStr("print(\"Hello World!\")")); REQUIRE(stat != nullptr); } TEST_CASE_FIXTURE(Fixture, "can_haz_annotations") { - AstStatBlock* block = parse("local foo: string = \"Hello Types!\""); + AstStatBlock* block = parse(XorStr("local foo: string = \"Hello Types!\"")); REQUIRE(block != nullptr); } TEST_CASE_FIXTURE(Fixture, "local_cannot_have_annotation_with_extensions_disabled") { - Luau::ParseOptions options; + lluz::ParseOptions options; options.allowTypeAnnotations = false; CHECK_THROWS_AS(parse("local foo: string = \"Hello Types!\"", options), std::exception); @@ -151,7 +283,7 @@ TEST_CASE_FIXTURE(Fixture, "type_names_can_contain_dots") TEST_CASE_FIXTURE(Fixture, "functions_cannot_have_return_annotations_if_extensions_are_disabled") { - Luau::ParseOptions options; + lluz::ParseOptions options; options.allowTypeAnnotations = false; CHECK_THROWS_AS(parse("function foo(): number return 55 end", options), std::exception); @@ -214,11 +346,11 @@ TEST_CASE_FIXTURE(Fixture, "function_return_type_should_disambiguate_from_functi AstTypeReference* ty0 = retTypes.data[0]->as(); REQUIRE(ty0 != nullptr); - REQUIRE(ty0->name == "number"); + REQUIRE(ty0->name == XorStr("number")); AstTypeReference* ty1 = retTypes.data[1]->as(); REQUIRE(ty1 != nullptr); - REQUIRE(ty1->name == "string"); + REQUIRE(ty1->name == XorStr("string")); } TEST_CASE_FIXTURE(Fixture, "function_return_type_should_parse_as_function_type_annotation_with_no_args") @@ -246,7 +378,7 @@ TEST_CASE_FIXTURE(Fixture, "function_return_type_should_parse_as_function_type_a AstTypeReference* ty = funTy->returnTypes.types.data[0]->as(); REQUIRE(ty != nullptr); - REQUIRE(ty->name == "nil"); + REQUIRE(ty->name == XorStr("nil")); } TEST_CASE_FIXTURE(Fixture, "annotations_can_be_tables") @@ -396,7 +528,7 @@ TEST_CASE_FIXTURE(Fixture, "return_type_is_an_intersection_type_if_led_with_one_ TEST_CASE_FIXTURE(Fixture, "illegal_type_alias_if_extensions_are_disabled") { - Luau::ParseOptions options; + lluz::ParseOptions options; options.allowTypeAnnotations = false; CHECK_THROWS_AS(parse("type A = number", options), std::exception); @@ -462,55 +594,55 @@ TEST_CASE_FIXTURE(Fixture, "parse_error_messages") CHECK_EQ(getParseError(R"( local a: (number, number) -> (string )"), - "Expected ')' (to close '(' at line 2), got "); + XorStr("Expected ')' (to close '(' at line 2), got ")); CHECK_EQ(getParseError(R"( local a: (number, number) -> ( string )"), - "Expected ')' (to close '(' at line 2), got "); + XorStr("Expected ')' (to close '(' at line 2), got ")); CHECK_EQ(getParseError(R"( local a: (number, number) )"), - "Expected '->' when parsing function type, got "); + XorStr("Expected '->' when parsing function type, got ")); CHECK_EQ(getParseError(R"( local a: (number, number )"), - "Expected ')' (to close '(' at line 2), got "); + XorStr("Expected ')' (to close '(' at line 2), got ")); CHECK_EQ(getParseError(R"( local a: {foo: string, )"), - "Expected identifier when parsing table field, got "); + XorStr("Expected identifier when parsing table field, got ")); CHECK_EQ(getParseError(R"( local a: {foo: string )"), - "Expected '}' (to close '{' at line 2), got "); + XorStr("Expected '}' (to close '{' at line 2), got ")); CHECK_EQ(getParseError(R"( local a: { [string]: number, [number]: string } )"), - "Cannot have more than one table indexer"); + XorStr("Cannot have more than one table indexer")); CHECK_EQ(getParseError(R"( type T = foo )"), - "Expected '(' when parsing function parameters, got 'foo'"); + XorStr("Expected '(' when parsing function parameters, got 'foo'")); } TEST_CASE_FIXTURE(Fixture, "mixed_intersection_and_union_not_allowed") { - matchParseError("type A = number & string | boolean", "Mixing union and intersection types is not allowed; consider wrapping in parentheses."); + matchParseError(XorStr("type A = number & string | boolean", "Mixing union and intersection types is not allowed; consider wrapping in parentheses.")); } TEST_CASE_FIXTURE(Fixture, "mixed_intersection_and_union_allowed_when_parenthesized") { try { - parse("type A = (number & string) | boolean"); + parse(XorStr("type A = (number & string) | boolean")); } catch (const ParseErrors& e) { @@ -520,16 +652,16 @@ TEST_CASE_FIXTURE(Fixture, "mixed_intersection_and_union_allowed_when_parenthesi TEST_CASE_FIXTURE(Fixture, "cannot_write_multiple_values_in_type_groups") { - matchParseError("type F = ((string, number))", "Expected '->' when parsing function type, got ')'"); - matchParseError("type F = () -> ((string, number))", "Expected '->' when parsing function type, got ')'"); + matchParseError(XorStr("type F = ((string, number))", "Expected '->' when parsing function type, got ')'")); + matchParseError(XorStr("type F = () -> ((string, number))", "Expected '->' when parsing function type, got ')'")); } TEST_CASE_FIXTURE(Fixture, "type_alias_error_messages") { - CHECK_EQ(getParseError("type 5 = number"), "Expected identifier when parsing type name, got '5'"); - CHECK_EQ(getParseError("type A"), "Expected '=' when parsing type alias, got "); - CHECK_EQ(getParseError("type A<"), "Expected identifier, got "); - CHECK_EQ(getParseError("type A' (to close '<' at column 7), got "); + CHECK_EQ(getParseError(XorStr("type 5 = number"), "Expected identifier when parsing type name, got '5'")); + CHECK_EQ(getParseError(XorStr("type A"), "Expected '=' when parsing type alias, got ")); + CHECK_EQ(getParseError(XorStr("type A<"), "Expected identifier, got ")); + CHECK_EQ(getParseError(XorStr("type A' (to close '<' at column 7), got ")); } TEST_CASE_FIXTURE(Fixture, "type_assertion_expression") @@ -543,7 +675,7 @@ TEST_CASE_FIXTURE(Fixture, "type_assertion_expression") // TODO: Set a timer and crash if the timeout is exceeded. TEST_CASE_FIXTURE(Fixture, "last_line_does_not_have_to_be_blank") { - (void)parse("-- print('hello')"); + (void)parse(XorStr("-- print('hello')")); } TEST_CASE_FIXTURE(Fixture, "type_assertion_expression_binds_tightly") @@ -571,7 +703,7 @@ TEST_CASE_FIXTURE(Fixture, "type_assertion_expression_binds_tightly") TEST_CASE_FIXTURE(Fixture, "mode_is_unset_if_no_hot_comment") { - ParseResult result = parseEx("print('Hello World!')"); + ParseResult result = parseEx(XorStr("print('Hello World!')")); CHECK(result.hotcomments.empty()); } @@ -627,7 +759,7 @@ TEST_CASE_FIXTURE(Fixture, "nocheck_mode") TEST_CASE_FIXTURE(Fixture, "vertical_space") { - ParseResult result = parseEx("a()\vb()"); + ParseResult result = parseEx(XorStr("a()\vb()")); CHECK(result.errors.empty()); } @@ -636,12 +768,12 @@ TEST_CASE_FIXTURE(Fixture, "parse_error_type_name") CHECK_EQ(getParseError(R"( local a: Foo.= )"), - "Expected identifier when parsing field name, got '='"); + XorStr("Expected identifier when parsing field name, got '='")); } TEST_CASE_FIXTURE(Fixture, "parse_numbers_decimal") { - AstStat* stat = parse("return 1, .5, 1.5, 1e-5, 1.5e-5, 12_345.1_25"); + AstStat* stat = parse(XorStr("return 1, .5, 1.5, 1e-5, 1.5e-5, 12_345.1_25")); REQUIRE(stat != nullptr); AstStatReturn* str = stat->as()->body.data[0]->as(); @@ -656,7 +788,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_numbers_decimal") TEST_CASE_FIXTURE(Fixture, "parse_numbers_hexadecimal") { - AstStat* stat = parse("return 0xab, 0XAB05, 0xff_ff, 0xffffffffffffffff"); + AstStat* stat = parse(XorStr("return 0xab, 0XAB05, 0xff_ff, 0xffffffffffffffff")); REQUIRE(stat != nullptr); AstStatReturn* str = stat->as()->body.data[0]->as(); @@ -669,7 +801,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_numbers_hexadecimal") TEST_CASE_FIXTURE(Fixture, "parse_numbers_binary") { - AstStat* stat = parse("return 0b1, 0b0, 0b101010, 0b1111111111111111111111111111111111111111111111111111111111111111"); + AstStat* stat = parse(XorStr("return 0b1, 0b0, 0b101010, 0b1111111111111111111111111111111111111111111111111111111111111111")); REQUIRE(stat != nullptr); AstStatReturn* str = stat->as()->body.data[0]->as(); @@ -682,26 +814,26 @@ TEST_CASE_FIXTURE(Fixture, "parse_numbers_binary") TEST_CASE_FIXTURE(Fixture, "parse_numbers_error") { - ScopedFastFlag luauErrorParseIntegerIssues{"LuauErrorParseIntegerIssues", true}; + ScopedFastFlag lluzErrorParseIntegerIssues{"lluzErrorParseIntegerIssues", true}; - CHECK_EQ(getParseError("return 0b123"), "Malformed number"); - CHECK_EQ(getParseError("return 123x"), "Malformed number"); - CHECK_EQ(getParseError("return 0xg"), "Malformed number"); - CHECK_EQ(getParseError("return 0x0x123"), "Malformed number"); + CHECK_EQ(getParseError(XorStr("return 0b123"), "Malformed number")); + CHECK_EQ(getParseError(XorStr("return 123x"), "Malformed number")); + CHECK_EQ(getParseError(XorStr("return 0xg"), "Malformed number")); + CHECK_EQ(getParseError(XorStr("return 0x0x123"), "Malformed number")); } TEST_CASE_FIXTURE(Fixture, "parse_numbers_range_error") { - ScopedFastFlag luauErrorParseIntegerIssues{"LuauErrorParseIntegerIssues", true}; + ScopedFastFlag lluzErrorParseIntegerIssues{"lluzErrorParseIntegerIssues", true}; - CHECK_EQ(getParseError("return 0x10000000000000000"), "Integer number value is out of range"); - CHECK_EQ(getParseError("return 0b10000000000000000000000000000000000000000000000000000000000000000"), "Integer number value is out of range"); + CHECK_EQ(getParseError(XorStr("return 0x10000000000000000"), "Integer number value is out of range")); + CHECK_EQ(getParseError(XorStr("return 0b10000000000000000000000000000000000000000000000000000000000000000"), "Integer number value is out of range")); } TEST_CASE_FIXTURE(Fixture, "break_return_not_last_error") { - CHECK_EQ(getParseError("return 0 print(5)"), "Expected , got 'print'"); - CHECK_EQ(getParseError("while true do break print(5) end"), "Expected 'end' (to close 'do' at column 12), got 'print'"); + CHECK_EQ(getParseError(XorStr("return 0 print(5)"), "Expected , got 'print'")); + CHECK_EQ(getParseError(XorStr("while true do break print(5) end"), "Expected 'end' (to close 'do' at column 12), got 'print'")); } TEST_CASE_FIXTURE(Fixture, "error_on_unicode") @@ -709,12 +841,12 @@ TEST_CASE_FIXTURE(Fixture, "error_on_unicode") CHECK_EQ(getParseError(R"( local ☃ = 10 )"), - "Expected identifier when parsing variable name, got Unicode character U+2603"); + XorStr("Expected identifier when parsing variable name, got Unicode character U+2603")); } TEST_CASE_FIXTURE(Fixture, "allow_unicode_in_string") { - ParseResult result = parseEx("local snowman = \"☃\""); + ParseResult result = parseEx(XorStr("local snowman = \"☃\"")); CHECK(result.errors.empty()); } @@ -723,7 +855,7 @@ TEST_CASE_FIXTURE(Fixture, "error_on_confusable") CHECK_EQ(getParseError(R"( local pi = 3․13 )"), - "Expected identifier when parsing expression, got Unicode character U+2024 (did you mean '.'?)"); + XorStr("Expected identifier when parsing expression, got Unicode character U+2024 (did you mean '.'?)")); } TEST_CASE_FIXTURE(Fixture, "error_on_non_utf8_sequence") @@ -736,9 +868,9 @@ TEST_CASE_FIXTURE(Fixture, "error_on_non_utf8_sequence") TEST_CASE_FIXTURE(Fixture, "lex_broken_unicode") { - const std::string testInput = std::string("\xFF\xFE☃․"); + const std::string testInput = std::string(XorStr("\xFF\xFE☃․")); - Luau::Allocator alloc; + lluz::Allocator alloc; AstNameTable table(alloc); Lexer lexer(testInput.c_str(), testInput.size(), table); Lexeme lexeme = lexer.current(); @@ -746,22 +878,22 @@ TEST_CASE_FIXTURE(Fixture, "lex_broken_unicode") lexeme = lexer.next(); CHECK_EQ(lexeme.type, Lexeme::BrokenUnicode); CHECK_EQ(lexeme.codepoint, 0); - CHECK_EQ(lexeme.location, Luau::Location(Luau::Position(0, 0), Luau::Position(0, 1))); + CHECK_EQ(lexeme.location, lluz::Location(lluz::Position(0, 0), lluz::Position(0, 1))); lexeme = lexer.next(); CHECK_EQ(lexeme.type, Lexeme::BrokenUnicode); CHECK_EQ(lexeme.codepoint, 0); - CHECK_EQ(lexeme.location, Luau::Location(Luau::Position(0, 1), Luau::Position(0, 2))); + CHECK_EQ(lexeme.location, lluz::Location(lluz::Position(0, 1), lluz::Position(0, 2))); lexeme = lexer.next(); CHECK_EQ(lexeme.type, Lexeme::BrokenUnicode); CHECK_EQ(lexeme.codepoint, 0x2603); - CHECK_EQ(lexeme.location, Luau::Location(Luau::Position(0, 2), Luau::Position(0, 5))); + CHECK_EQ(lexeme.location, lluz::Location(lluz::Position(0, 2), lluz::Position(0, 5))); lexeme = lexer.next(); CHECK_EQ(lexeme.type, Lexeme::BrokenUnicode); CHECK_EQ(lexeme.codepoint, 0x2024); - CHECK_EQ(lexeme.location, Luau::Location(Luau::Position(0, 5), Luau::Position(0, 8))); + CHECK_EQ(lexeme.location, lluz::Location(lluz::Position(0, 5), lluz::Position(0, 8))); lexeme = lexer.next(); CHECK_EQ(lexeme.type, Lexeme::Eof); @@ -799,7 +931,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_continue") TEST_CASE_FIXTURE(Fixture, "continue_not_last_error") { - CHECK_EQ(getParseError("while true do continue print(5) end"), "Expected 'end' (to close 'do' at column 12), got 'print'"); + CHECK_EQ(getParseError(XorStr("while true do continue print(5) end"), "Expected 'end' (to close 'do' at column 12), got 'print'")); } TEST_CASE_FIXTURE(Fixture, "parse_export_type") @@ -832,7 +964,7 @@ TEST_CASE_FIXTURE(Fixture, "export_is_an_identifier_only_when_followed_by_type") parse(R"( export function a() end )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -842,7 +974,7 @@ TEST_CASE_FIXTURE(Fixture, "export_is_an_identifier_only_when_followed_by_type") TEST_CASE_FIXTURE(Fixture, "incomplete_statement_error") { - CHECK_EQ(getParseError("fiddlesticks"), "Incomplete statement: expected assignment or a function call"); + CHECK_EQ(getParseError(XorStr("fiddlesticks"), "Incomplete statement: expected assignment or a function call")); } TEST_CASE_FIXTURE(Fixture, "parse_compound_assignment") @@ -864,7 +996,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_compound_assignment_error_call") parse(R"( a() += 5 )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -879,7 +1011,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_compound_assignment_error_not_lvalue") parse(R"( (a) += 5 )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -894,7 +1026,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_compound_assignment_error_multiple") parse(R"( a, b += 5 )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -925,7 +1057,7 @@ function ItemCheck(tree) end end )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -954,7 +1086,7 @@ function BottomUpTree(item, depth) end end )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -975,7 +1107,7 @@ repeat print(3) until false )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -1007,7 +1139,7 @@ local function ItemCheck(tree) end end )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -1039,7 +1171,7 @@ local function BottomUpTree(item, depth) return { item } end )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -1056,7 +1188,7 @@ function stringifyTable(t) local entries = {} for k, v in pairs(t) do -- if we find a nested table, convert that recursively - if type(v) == "table" then + if type(v) == XorStr("table") then v = stringifyTable(v) else v = tostring(v) @@ -1072,7 +1204,7 @@ function stringifyTable(t) return ("{s}@s"):format(table.concat(entries, ", "), id) end )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -1091,7 +1223,7 @@ function stringifyTable(t) return foo end )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -1110,7 +1242,7 @@ function stringifyTable(t) return foo end )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -1129,7 +1261,7 @@ function stringifyTable(t) return foo end )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } catch (const ParseErrors& e) { @@ -1140,64 +1272,64 @@ end TEST_CASE_FIXTURE(Fixture, "parse_error_with_too_many_nested_type_group") { - ScopedFastInt sfis{"LuauRecursionLimit", 20}; + ScopedFastInt sfis{"lluzRecursionLimit", 20}; matchParseError( - "function f(): (((((((((Fail))))))))) end", "Exceeded allowed recursion depth; simplify your type annotation to make the code compile"); + XorStr("function f(): (((((((((Fail))))))))) end", "Exceeded allowed recursion depth; simplify your type annotation to make the code compile")); matchParseError("function f(): () -> () -> () -> () -> () -> () -> () -> () -> () -> () -> () end", - "Exceeded allowed recursion depth; simplify your type annotation to make the code compile"); + XorStr("Exceeded allowed recursion depth; simplify your type annotation to make the code compile")); matchParseError( - "local t: {a: {b: {c: {d: {e: {f: {}}}}}}}", "Exceeded allowed recursion depth; simplify your type annotation to make the code compile"); + XorStr("local t: {a: {b: {c: {d: {e: {f: {}}}}}}}", "Exceeded allowed recursion depth; simplify your type annotation to make the code compile")); } TEST_CASE_FIXTURE(Fixture, "parse_error_with_too_many_nested_if_statements") { - ScopedFastInt sfis{"LuauRecursionLimit", 10}; + ScopedFastInt sfis{"lluzRecursionLimit", 10}; matchParseErrorPrefix( "function f() if true then if true then if true then if true then if true then if true then if true then if true then if true " "then if true then if true then end end end end end end end end end end end end", - "Exceeded allowed recursion depth;"); + XorStr("Exceeded allowed recursion depth;")); } TEST_CASE_FIXTURE(Fixture, "parse_error_with_too_many_changed_elseif_statements") { - ScopedFastInt sfis{"LuauRecursionLimit", 10}; + ScopedFastInt sfis{"lluzRecursionLimit", 10}; matchParseErrorPrefix( "function f() if false then elseif false then elseif false then elseif false then elseif false then elseif false then elseif " "false then elseif false then elseif false then elseif false then elseif false then end end", - "Exceeded allowed recursion depth;"); + XorStr("Exceeded allowed recursion depth;")); } TEST_CASE_FIXTURE(Fixture, "parse_error_with_too_many_nested_ifelse_expressions1") { - ScopedFastInt sfis{"LuauRecursionLimit", 10}; + ScopedFastInt sfis{"lluzRecursionLimit", 10}; matchParseError("function f() return if true then 1 elseif true then 2 elseif true then 3 elseif true then 4 elseif true then 5 elseif true then " "6 elseif true then 7 elseif true then 8 elseif true then 9 elseif true then 10 else 11 end", - "Exceeded allowed recursion depth; simplify your expression to make the code compile"); + XorStr("Exceeded allowed recursion depth; simplify your expression to make the code compile")); } TEST_CASE_FIXTURE(Fixture, "parse_error_with_too_many_nested_ifelse_expressions2") { - ScopedFastInt sfis{"LuauRecursionLimit", 10}; + ScopedFastInt sfis{"lluzRecursionLimit", 10}; matchParseError( "function f() return if if if if if if if if if if true then false else true then false else true then false else true then false else true " "then false else true then false else true then false else true then false else true then false else true then 1 else 2 end", - "Exceeded allowed recursion depth; simplify your expression to make the code compile"); + XorStr("Exceeded allowed recursion depth; simplify your expression to make the code compile")); } TEST_CASE_FIXTURE(Fixture, "unparenthesized_function_return_type_list") { matchParseError( - "function foo(): string, number end", "Expected a statement, got ','; did you forget to wrap the list of return types in parentheses?"); + XorStr("function foo(): string, number end", "Expected a statement, got ','; did you forget to wrap the list of return types in parentheses?")); matchParseError("function foo(): (number) -> string, string", - "Expected a statement, got ','; did you forget to wrap the list of return types in parentheses?"); + XorStr("Expected a statement, got ','; did you forget to wrap the list of return types in parentheses?")); // Will throw if the parse fails parse(R"( @@ -1221,17 +1353,17 @@ TEST_CASE_FIXTURE(Fixture, "short_array_types") CHECK(annotation->props.size == 0); REQUIRE(annotation->indexer); REQUIRE(annotation->indexer->indexType->is()); - CHECK(annotation->indexer->indexType->as()->name == "number"); + CHECK(annotation->indexer->indexType->as()->name == XorStr("number")); REQUIRE(annotation->indexer->resultType->is()); - CHECK(annotation->indexer->resultType->as()->name == "string"); + CHECK(annotation->indexer->resultType->as()->name == XorStr("string")); } TEST_CASE_FIXTURE(Fixture, "short_array_types_must_be_alone") { - matchParseError("local n: {string, number}", "Expected '}' (to close '{' at column 10), got ','"); - matchParseError("local n: {[number]: string, number}", "Expected ':' when parsing table field, got '}'"); - matchParseError("local n: {x: string, number}", "Expected ':' when parsing table field, got '}'"); - matchParseError("local n: {x: string, nil}", "Expected identifier when parsing table field, got 'nil'"); + matchParseError(XorStr("local n: {string, number}", "Expected '}' (to close '{' at column 10), got ','")); + matchParseError(XorStr("local n: {[number]: string, number}", "Expected ':' when parsing table field, got '}'")); + matchParseError(XorStr("local n: {x: string, number}", "Expected ':' when parsing table field, got '}'")); + matchParseError(XorStr("local n: {x: string, nil}", "Expected identifier when parsing table field, got 'nil'")); } TEST_CASE_FIXTURE(Fixture, "short_array_types_do_not_break_field_names") @@ -1246,24 +1378,24 @@ TEST_CASE_FIXTURE(Fixture, "short_array_types_do_not_break_field_names") REQUIRE(annotation != nullptr); REQUIRE(annotation->props.size == 1); CHECK(!annotation->indexer); - REQUIRE(annotation->props.data[0].name == "string"); + REQUIRE(annotation->props.data[0].name == XorStr("string")); REQUIRE(annotation->props.data[0].type->is()); - REQUIRE(annotation->props.data[0].type->as()->name == "number"); + REQUIRE(annotation->props.data[0].type->as()->name == XorStr("number")); } TEST_CASE_FIXTURE(Fixture, "short_array_types_are_not_field_names_when_complex") { - matchParseError("local n: {string | number: number}", "Expected '}' (to close '{' at column 10), got ':'"); + matchParseError(XorStr("local n: {string | number: number}", "Expected '}' (to close '{' at column 10), got ':'")); } TEST_CASE_FIXTURE(Fixture, "nil_can_not_be_a_field_name") { - matchParseError("local n: {nil: number}", "Expected '}' (to close '{' at column 10), got ':'"); + matchParseError(XorStr("local n: {nil: number}", "Expected '}' (to close '{' at column 10), got ':'")); } TEST_CASE_FIXTURE(Fixture, "string_literal_call") { - AstStatBlock* stat = parse("do foo 'bar' end"); + AstStatBlock* stat = parse(XorStr("do foo 'bar' end")); REQUIRE(stat != nullptr); AstStatBlock* dob = stat->body.data[0]->as(); AstStatExpr* stc = dob->body.data[0]->as(); @@ -1272,12 +1404,12 @@ TEST_CASE_FIXTURE(Fixture, "string_literal_call") CHECK(ec->args.size == 1); AstExprConstantString* arg = ec->args.data[0]->as(); REQUIRE(arg != nullptr); - CHECK(std::string(arg->value.data, arg->value.size) == "bar"); + CHECK(std::string(arg->value.data, arg->value.size) == XorStr("bar")); } TEST_CASE_FIXTURE(Fixture, "multiline_strings_newlines") { - AstStatBlock* stat = parse("return [=[\nfoo\r\nbar\n\nbaz\n]=]"); + AstStatBlock* stat = parse(XorStr("return [=[\nfoo\r\nbar\n\nbaz\n]=]")); REQUIRE(stat != nullptr); AstStatReturn* ret = stat->body.data[0]->as(); @@ -1285,7 +1417,7 @@ TEST_CASE_FIXTURE(Fixture, "multiline_strings_newlines") AstExprConstantString* str = ret->list.data[0]->as(); REQUIRE(str != nullptr); - CHECK(std::string(str->value.data, str->value.size) == "foo\nbar\n\nbaz\n"); + CHECK(std::string(str->value.data, str->value.size) == XorStr("foo\nbar\n\nbaz\n")); } TEST_CASE_FIXTURE(Fixture, "string_literals_escape") @@ -1309,28 +1441,28 @@ return str = ret->list.data[0]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "foo\n\r"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("foo\n\r")); str = ret->list.data[1]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "foo 4"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("foo 4")); str = ret->list.data[2]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "foo 4"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("foo 4")); str = ret->list.data[3]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "foo "); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("foo ")); str = ret->list.data[4]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "foo\xd1\x91"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("foo\xd1\x91")); } TEST_CASE_FIXTURE(Fixture, "string_literals_escape_newline") { - AstStatBlock* stat = parse("return \"foo\\z\n bar\", \"foo\\\n bar\", \"foo\\\r\nbar\""); + AstStatBlock* stat = parse(XorStr("return \"foo\\z\n bar\", \"foo\\\n bar\", \"foo\\\r\nbar\"")); REQUIRE(stat != nullptr); @@ -1342,15 +1474,15 @@ TEST_CASE_FIXTURE(Fixture, "string_literals_escape_newline") str = ret->list.data[0]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "foobar"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("foobar")); str = ret->list.data[1]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "foo\n bar"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("foo\n bar")); str = ret->list.data[2]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "foo\nbar"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("foo\nbar")); } TEST_CASE_FIXTURE(Fixture, "string_literals_escapes") @@ -1375,27 +1507,27 @@ return str = ret->list.data[0]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "\xAB"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("\xAB")); str = ret->list.data[1]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "\xE2\x80\xA4"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("\xE2\x80\xA4")); str = ret->list.data[2]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "\x79"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("\x79")); str = ret->list.data[3]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "\x01x"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("\x01x")); str = ret->list.data[4]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "\t"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("\t")); str = ret->list.data[5]->as(); REQUIRE(str != nullptr); - CHECK_EQ(std::string(str->value.data, str->value.size), "\n"); + CHECK_EQ(std::string(str->value.data, str->value.size), XorStr("\n")); } TEST_CASE_FIXTURE(Fixture, "parse_error_broken_comment") @@ -1422,9 +1554,9 @@ TEST_CASE_FIXTURE(Fixture, "string_literals_escapes_broken") TEST_CASE_FIXTURE(Fixture, "string_literals_broken") { - matchParseError("return \"", "Malformed string"); - matchParseError("return \"\\", "Malformed string"); - matchParseError("return \"\r\r", "Malformed string"); + matchParseError(XorStr("return \"", "Malformed string")); + matchParseError(XorStr("return \"\\", "Malformed string")); + matchParseError(XorStr("return \"\r\r", "Malformed string")); } TEST_CASE_FIXTURE(Fixture, "number_literals") @@ -1518,10 +1650,10 @@ TEST_CASE_FIXTURE(Fixture, "end_extent_doesnt_consume_comments_even_with_capture TEST_CASE_FIXTURE(Fixture, "parse_error_loop_control") { - matchParseError("break", "break statement must be inside a loop"); - matchParseError("repeat local function a() break end until false", "break statement must be inside a loop"); - matchParseError("continue", "continue statement must be inside a loop"); - matchParseError("repeat local function a() continue end until false", "continue statement must be inside a loop"); + matchParseError(XorStr("break", "break statement must be inside a loop")); + matchParseError(XorStr("repeat local function a() break end until false", "break statement must be inside a loop")); + matchParseError(XorStr("continue", "continue statement must be inside a loop")); + matchParseError(XorStr("repeat local function a() continue end until false", "continue statement must be inside a loop")); } TEST_CASE_FIXTURE(Fixture, "parse_error_confusing_function_call") @@ -1532,7 +1664,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_error_confusing_function_call") (4, 7) )", "Ambiguous syntax: this looks like an argument list for a function call, but could also be a start of new statement; use ';' to separate " - "statements"); + XorStr("statements")); CHECK(result1.errors.size() == 1); @@ -1542,7 +1674,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_error_confusing_function_call") (f :: any)['x'] = 2 )", "Ambiguous syntax: this looks like an argument list for a function call, but could also be a start of new statement; use ';' to separate " - "statements"); + XorStr("statements")); CHECK(result2.errors.size() == 1); @@ -1553,7 +1685,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_error_confusing_function_call") (1, 2) )", "Ambiguous syntax: this looks like an argument list for a function call, but could also be a start of new statement; use ';' to separate " - "statements"); + XorStr("statements")); CHECK(result3.errors.size() == 1); @@ -1564,14 +1696,14 @@ TEST_CASE_FIXTURE(Fixture, "parse_error_confusing_function_call") ().y = 5, 6 )", "Ambiguous syntax: this looks like an argument list for a function call, but could also be a start of new statement; use ';' to separate " - "statements"); + XorStr("statements")); CHECK(result4.errors.size() == 1); } TEST_CASE_FIXTURE(Fixture, "parse_error_varargs") { - matchParseError("function add(x, y) return ... end", "Cannot use '...' outside of a vararg function"); + matchParseError(XorStr("function add(x, y) return ... end", "Cannot use '...' outside of a vararg function")); } TEST_CASE_FIXTURE(Fixture, "parse_error_assignment_lvalue") @@ -1580,18 +1712,18 @@ TEST_CASE_FIXTURE(Fixture, "parse_error_assignment_lvalue") local a, b (2), b = b, a )", - "Assigned expression must be a variable or a field"); + XorStr("Assigned expression must be a variable or a field")); matchParseError(R"( local a, b a, (3) = b, a )", - "Assigned expression must be a variable or a field"); + XorStr("Assigned expression must be a variable or a field")); } TEST_CASE_FIXTURE(Fixture, "parse_error_type_annotation") { - matchParseError("local a : 2 = 2", "Expected type, got '2'"); + matchParseError(XorStr("local a : 2 = 2", "Expected type, got '2'")); } TEST_CASE_FIXTURE(Fixture, "parse_declarations") @@ -1608,22 +1740,22 @@ TEST_CASE_FIXTURE(Fixture, "parse_declarations") AstStatDeclareGlobal* global = stat->body.data[0]->as(); REQUIRE(global); - CHECK(global->name == "foo"); + CHECK(global->name == XorStr("foo")); CHECK(global->type); AstStatDeclareFunction* func = stat->body.data[1]->as(); REQUIRE(func); - CHECK(func->name == "bar"); + CHECK(func->name == XorStr("bar")); REQUIRE_EQ(func->params.types.size, 1); REQUIRE_EQ(func->retTypes.types.size, 1); AstStatDeclareFunction* varFunc = stat->body.data[2]->as(); REQUIRE(varFunc); - CHECK(varFunc->name == "var"); + CHECK(varFunc->name == XorStr("var")); CHECK(varFunc->params.tailType); - matchParseError("declare function foo(x)", "All declaration parameters must be annotated"); - matchParseError("declare foo", "Expected ':' when parsing global variable declaration, got "); + matchParseError(XorStr("declare function foo(x)", "All declaration parameters must be annotated")); + matchParseError(XorStr("declare foo", "Expected ':' when parsing global variable declaration, got ")); } TEST_CASE_FIXTURE(Fixture, "parse_class_declarations") @@ -1644,28 +1776,28 @@ TEST_CASE_FIXTURE(Fixture, "parse_class_declarations") AstStatDeclareClass* declaredClass = stat->body.data[0]->as(); REQUIRE(declaredClass); - CHECK(declaredClass->name == "Foo"); + CHECK(declaredClass->name == XorStr("Foo")); CHECK(!declaredClass->superName); REQUIRE_EQ(declaredClass->props.size, 2); AstDeclaredClassProp& prop = declaredClass->props.data[0]; - CHECK(prop.name == "prop"); + CHECK(prop.name == XorStr("prop")); CHECK(prop.ty->is()); AstDeclaredClassProp& method = declaredClass->props.data[1]; - CHECK(method.name == "method"); + CHECK(method.name == XorStr("method")); CHECK(method.ty->is()); AstStatDeclareClass* subclass = stat->body.data[1]->as(); REQUIRE(subclass); REQUIRE(subclass->superName); - CHECK(subclass->name == "Bar"); - CHECK(*subclass->superName == "Foo"); + CHECK(subclass->name == XorStr("Bar")); + CHECK(*subclass->superName == XorStr("Foo")); REQUIRE_EQ(subclass->props.size, 1); AstDeclaredClassProp& prop2 = subclass->props.data[0]; - CHECK(prop2.name == "prop2"); + CHECK(prop2.name == XorStr("prop2")); CHECK(prop2.ty->is()); } @@ -1678,7 +1810,7 @@ TEST_CASE_FIXTURE(Fixture, "class_method_properties") function method2(self) end )", - "'self' must be present as the unannotated first parameter"); + XorStr("'self' must be present as the unannotated first parameter")); REQUIRE_EQ(1, p1.root->body.size); @@ -1693,7 +1825,7 @@ TEST_CASE_FIXTURE(Fixture, "class_method_properties") function method2() end )", - "All declaration parameters aside from 'self' must be annotated"); + XorStr("All declaration parameters aside from 'self' must be annotated")); REQUIRE_EQ(1, p2.root->body.size); @@ -1745,8 +1877,8 @@ TEST_CASE_FIXTURE(Fixture, "parse_variadics") TEST_CASE_FIXTURE(Fixture, "variadics_must_be_last") { - matchParseError("function foo(): (...number, string) end", "Expected ')' (to close '(' at column 17), got ','"); - matchParseError("type Foo = (...number, string) -> (...string, number)", "Expected ')' (to close '(' at column 12), got ','"); + matchParseError(XorStr("function foo(): (...number, string) end", "Expected ')' (to close '(' at column 17), got ','")); + matchParseError(XorStr("type Foo = (...number, string) -> (...string, number)", "Expected ')' (to close '(' at column 12), got ','")); } TEST_CASE_FIXTURE(Fixture, "variadic_definition_parsing") @@ -1761,8 +1893,8 @@ TEST_CASE_FIXTURE(Fixture, "variadic_definition_parsing") REQUIRE(stat != nullptr); - matchParseError("declare function foo(...)", "All declaration parameters must be annotated"); - matchParseError("declare class Foo function a(self, ...) end", "All declaration parameters aside from 'self' must be annotated"); + matchParseError(XorStr("declare function foo(...)", "All declaration parameters must be annotated")); + matchParseError(XorStr("declare class Foo function a(self, ...) end", "All declaration parameters aside from 'self' must be annotated")); } TEST_CASE_FIXTURE(Fixture, "generic_pack_parsing") @@ -1783,7 +1915,7 @@ TEST_CASE_FIXTURE(Fixture, "generic_pack_parsing") AstTypePackGeneric* annot = fn->func->varargAnnotation->as(); REQUIRE(annot != nullptr); - CHECK(annot->genericName == "a"); + CHECK(annot->genericName == XorStr("a")); AstStatTypeAlias* alias = stat->body.data[1]->as(); REQUIRE(alias != nullptr); @@ -1792,11 +1924,11 @@ TEST_CASE_FIXTURE(Fixture, "generic_pack_parsing") AstTypePackGeneric* argAnnot = fnTy->argTypes.tailType->as(); REQUIRE(argAnnot != nullptr); - CHECK(argAnnot->genericName == "a"); + CHECK(argAnnot->genericName == XorStr("a")); AstTypePackGeneric* retAnnot = fnTy->returnTypes.tailType->as(); REQUIRE(retAnnot != nullptr); - CHECK(retAnnot->genericName == "b"); + CHECK(retAnnot->genericName == XorStr("b")); } TEST_CASE_FIXTURE(Fixture, "generic_function_declaration_parsing") @@ -1817,7 +1949,7 @@ TEST_CASE_FIXTURE(Fixture, "generic_function_declaration_parsing") TEST_CASE_FIXTURE(Fixture, "function_type_named_arguments") { { - ParseResult result = parseEx("type MyFunc = (a: number, b: string, c: number) -> string"); + ParseResult result = parseEx(XorStr("type MyFunc = (a: number, b: string, c: number) -> string")); AstStatBlock* stat = result.root; REQUIRE(stat != nullptr); @@ -1829,11 +1961,11 @@ TEST_CASE_FIXTURE(Fixture, "function_type_named_arguments") REQUIRE_EQ(func->argTypes.types.size, 3); REQUIRE_EQ(func->argNames.size, 3); REQUIRE(func->argNames.data[2]); - CHECK_EQ(func->argNames.data[2]->first, "c"); + CHECK_EQ(func->argNames.data[2]->first, XorStr("c")); } { - ParseResult result = parseEx("type MyFunc = (a: number, string, c: number) -> string"); + ParseResult result = parseEx(XorStr("type MyFunc = (a: number, string, c: number) -> string")); AstStatBlock* stat = result.root; REQUIRE(stat != nullptr); @@ -1846,11 +1978,11 @@ TEST_CASE_FIXTURE(Fixture, "function_type_named_arguments") REQUIRE_EQ(func->argNames.size, 3); REQUIRE(!func->argNames.data[1]); REQUIRE(func->argNames.data[2]); - CHECK_EQ(func->argNames.data[2]->first, "c"); + CHECK_EQ(func->argNames.data[2]->first, XorStr("c")); } { - ParseResult result = parseEx("type MyFunc = (a: number, string, number) -> string"); + ParseResult result = parseEx(XorStr("type MyFunc = (a: number, string, number) -> string")); AstStatBlock* stat = result.root; REQUIRE(stat != nullptr); @@ -1866,7 +1998,7 @@ TEST_CASE_FIXTURE(Fixture, "function_type_named_arguments") } { - ParseResult result = parseEx("type MyFunc = (a: number, b: string, c: number) -> (d: number, e: string, f: number) -> string"); + ParseResult result = parseEx(XorStr("type MyFunc = (a: number, b: string, c: number) -> (d: number, e: string, f: number) -> string")); AstStatBlock* stat = result.root; REQUIRE(stat != nullptr); @@ -1878,24 +2010,24 @@ TEST_CASE_FIXTURE(Fixture, "function_type_named_arguments") REQUIRE_EQ(func->argTypes.types.size, 3); REQUIRE_EQ(func->argNames.size, 3); REQUIRE(func->argNames.data[2]); - CHECK_EQ(func->argNames.data[2]->first, "c"); + CHECK_EQ(func->argNames.data[2]->first, XorStr("c")); AstTypeFunction* funcRet = func->returnTypes.types.data[0]->as(); REQUIRE(funcRet != nullptr); REQUIRE_EQ(funcRet->argTypes.types.size, 3); REQUIRE_EQ(funcRet->argNames.size, 3); REQUIRE(func->argNames.data[2]); - CHECK_EQ(funcRet->argNames.data[2]->first, "f"); + CHECK_EQ(funcRet->argNames.data[2]->first, XorStr("f")); } matchParseError("type MyFunc = (a: number, b: string, c: number) -> (d: number, e: string, f: number)", - "Expected '->' when parsing function type, got "); + XorStr("Expected '->' when parsing function type, got ")); - matchParseError("type MyFunc = (number) -> (d: number) -> number", "Expected '->' when parsing function type, got '<'"); + matchParseError(XorStr("type MyFunc = (number) -> (d: number) -> number", "Expected '->' when parsing function type, got '<'")); } TEST_CASE_FIXTURE(Fixture, "function_type_matching_parenthesis") { - matchParseError("local a: (number -> string", "Expected ')' (to close '(' at column 13), got '->'"); + matchParseError(XorStr("local a: (number -> string", "Expected ')' (to close '(' at column 13), got '->'")); } TEST_CASE_FIXTURE(Fixture, "parse_type_alias_default_type") @@ -1930,7 +2062,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_type_pack_errors") TEST_CASE_FIXTURE(Fixture, "parse_if_else_expression") { { - AstStat* stat = parse("return if true then 1 else 2"); + AstStat* stat = parse(XorStr("return if true then 1 else 2")); REQUIRE(stat != nullptr); AstStatReturn* str = stat->as()->body.data[0]->as(); @@ -1941,7 +2073,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_if_else_expression") } { - AstStat* stat = parse("return if true then 1 elseif true then 2 else 3"); + AstStat* stat = parse(XorStr("return if true then 1 elseif true then 2 else 3")); REQUIRE(stat != nullptr); AstStatReturn* str = stat->as()->body.data[0]->as(); @@ -1955,7 +2087,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_if_else_expression") // Use "else if" as opposed to elseif { - AstStat* stat = parse("return if true then 1 else if true then 2 else 3"); + AstStat* stat = parse(XorStr("return if true then 1 else if true then 2 else 3")); REQUIRE(stat != nullptr); AstStatReturn* str = stat->as()->body.data[0]->as(); @@ -1969,7 +2101,7 @@ TEST_CASE_FIXTURE(Fixture, "parse_if_else_expression") // Use an if-else expression as the conditional expression of an if-else expression { - AstStat* stat = parse("return if if true then false else true then 1 else 2"); + AstStat* stat = parse(XorStr("return if if true then false else true then 1 else 2")); REQUIRE(stat != nullptr); AstStatReturn* str = stat->as()->body.data[0]->as(); @@ -1996,16 +2128,16 @@ type C = Packed<(number, X...)> TEST_CASE_FIXTURE(Fixture, "invalid_type_forms") { - ScopedFastFlag luauFixNamedFunctionParse{"LuauFixNamedFunctionParse", true}; + ScopedFastFlag lluzFixNamedFunctionParse{"lluzFixNamedFunctionParse", true}; - matchParseError("type A = (b: number)", "Expected '->' when parsing function type, got "); - matchParseError("type P = () -> T... type B = P<(x: number, y: string)>", "Expected '->' when parsing function type, got '>'"); - matchParseError("type F = (T...) -> ()", "Expected '->' when parsing function type, got '>'"); + matchParseError(XorStr("type A = (b: number)", "Expected '->' when parsing function type, got ")); + matchParseError(XorStr("type P = () -> T... type B = P<(x: number, y: string)>", "Expected '->' when parsing function type, got '>'")); + matchParseError(XorStr("type F = (T...) -> ()", "Expected '->' when parsing function type, got '>'")); } TEST_SUITE_END(); -TEST_SUITE_BEGIN("ParseErrorRecovery"); +TEST_SUITE_BEGIN(XorStr("ParseErrorRecovery")); TEST_CASE_FIXTURE(Fixture, "multiple_parse_errors") { @@ -2015,9 +2147,9 @@ TEST_CASE_FIXTURE(Fixture, "multiple_parse_errors") local a = 3 * ( return a + )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ(2, e.getErrors().size()); } @@ -2033,9 +2165,9 @@ function a(a, b) return a + b end some a(2, 5) )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ(1, e.getErrors().size()); } @@ -2045,10 +2177,10 @@ TEST_CASE_FIXTURE(Fixture, "statement_error_recovery_unexpected") { try { - parse(R"(+)"); - FAIL("Expected ParseErrors to be thrown"); + parse(RXorStr("(+)")); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ(1, e.getErrors().size()); } @@ -2062,9 +2194,9 @@ TEST_CASE_FIXTURE(Fixture, "extra_token_in_consume") function test + (a, f) return a + f end return test(2, 3) )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ(1, e.getErrors().size()); CHECK_EQ("Expected '(' when parsing function, got '+'", e.getErrors().front().getMessage()); @@ -2079,9 +2211,9 @@ TEST_CASE_FIXTURE(Fixture, "extra_token_in_consume_match") function test(a, f+) return a + f end return test(2, 3) )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ(1, e.getErrors().size()); CHECK_EQ("Expected ')' (to close '(' at column 14), got '+'", e.getErrors().front().getMessage()); @@ -2098,9 +2230,9 @@ if true then then end )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ(1, e.getErrors().size()); CHECK_EQ("Expected 'end' (to close 'then' at line 2), got 'then'", e.getErrors().front().getMessage()); @@ -2114,9 +2246,9 @@ TEST_CASE_FIXTURE(Fixture, "extra_table_indexer_recovery") parse(R"( local a : { [string] : number, [number] : string, count: number } )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ(1, e.getErrors().size()); } @@ -2124,14 +2256,14 @@ local a : { [string] : number, [number] : string, count: number } TEST_CASE_FIXTURE(Fixture, "recovery_error_limit_1") { - ScopedFastInt luauParseErrorLimit("LuauParseErrorLimit", 1); + ScopedFastInt lluzParseErrorLimit("lluzParseErrorLimit", 1); try { - parse("local a = "); - FAIL("Expected ParseErrors to be thrown"); + parse(XorStr("local a = ")); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ(1, e.getErrors().size()); CHECK_EQ(e.getErrors().front().getMessage(), e.what()); @@ -2140,14 +2272,14 @@ TEST_CASE_FIXTURE(Fixture, "recovery_error_limit_1") TEST_CASE_FIXTURE(Fixture, "recovery_error_limit_2") { - ScopedFastInt luauParseErrorLimit("LuauParseErrorLimit", 2); + ScopedFastInt lluzParseErrorLimit("lluzParseErrorLimit", 2); try { - parse("escape escape escape"); - FAIL("Expected ParseErrors to be thrown"); + parse(XorStr("escape escape escape")); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ(3, e.getErrors().size()); CHECK_EQ("3 parse errors", std::string(e.what())); @@ -2175,7 +2307,7 @@ TEST_CASE_FIXTURE(Fixture, "recovery_of_parenthesized_expressions") { parse(codeWithErrors); } - catch (const Luau::ParseErrors&) + catch (const lluz::ParseErrors&) { } @@ -2194,9 +2326,9 @@ TEST_CASE_FIXTURE(Fixture, "recovery_of_parenthesized_expressions") try { parse(codeWithErrors); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ(expectedErrorCount, e.getErrors().size()); checkAstEquivalence(codeWithErrors, code); @@ -2303,17 +2435,17 @@ TEST_CASE_FIXTURE(Fixture, "incomplete_method_call_still_yields_an_AstExprIndexN TEST_CASE_FIXTURE(Fixture, "recover_confusables") { // Binary - matchParseError("local a = 4 != 10", "Unexpected '!=', did you mean '~='?"); - matchParseError("local a = true && false", "Unexpected '&&', did you mean 'and'?"); - matchParseError("local a = false || true", "Unexpected '||', did you mean 'or'?"); + matchParseError(XorStr("local a = 4 != 10", "Unexpected '!=', did you mean '~='?")); + matchParseError(XorStr("local a = true && false", "Unexpected '&&', did you mean 'and'?")); + matchParseError(XorStr("local a = false || true", "Unexpected '||', did you mean 'or'?")); // Unary - matchParseError("local a = !false", "Unexpected '!', did you mean 'not'?"); + matchParseError(XorStr("local a = !false", "Unexpected '!', did you mean 'not'?")); // Check that separate tokens are not considered as a single one - matchParseError("local a = 4 ! = 10", "Expected identifier when parsing expression, got '!'"); - matchParseError("local a = true & & false", "Expected identifier when parsing expression, got '&'"); - matchParseError("local a = false | | true", "Expected identifier when parsing expression, got '|'"); + matchParseError(XorStr("local a = 4 ! = 10", "Expected identifier when parsing expression, got '!'")); + matchParseError(XorStr("local a = true & & false", "Expected identifier when parsing expression, got '&'")); + matchParseError(XorStr("local a = false | | true", "Expected identifier when parsing expression, got '|'")); } TEST_CASE_FIXTURE(Fixture, "capture_comments") @@ -2382,9 +2514,9 @@ type Fn = ( string | number | () ) -> any )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ("Expected '->' after '()' when parsing function type; did you mean 'nil'?", e.getErrors().front().getMessage()); } @@ -2392,30 +2524,30 @@ type Fn = ( // If we have arguments or generics, don't use special case try { - parse(R"(type Fn = (any, string | number | (number, number)) -> any)"); - FAIL("Expected ParseErrors to be thrown"); + parse(RXorStr("(type Fn = (any, string | number | (number, number)) -> any)")); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ("Expected '->' when parsing function type, got ')'", e.getErrors().front().getMessage()); } try { - parse(R"(type Fn = (any, string | number | ()) -> any)"); - FAIL("Expected ParseErrors to be thrown"); + parse(RXorStr("(type Fn = (any, string | number | ()) -> any)")); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ("Expected '->' when parsing function type, got ')'", e.getErrors().front().getMessage()); } try { - parse(R"(type Fn = (any, string | number | ()) -> any)"); - FAIL("Expected ParseErrors to be thrown"); + parse(RXorStr("(type Fn = (any, string | number | ()) -> any)")); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ("Expected '->' when parsing function type, got ')'", e.getErrors().front().getMessage()); } @@ -2439,9 +2571,9 @@ TEST_CASE_FIXTURE(Fixture, "generic_type_list_recovery") local function foo(a: U, ...: T...): (U, ...T) return a, ... end return foo(1, 2 -- to check for a second error after recovery )"); - FAIL("Expected ParseErrors to be thrown"); + FAIL(XorStr("Expected ParseErrors to be thrown")); } - catch (const Luau::ParseErrors& e) + catch (const lluz::ParseErrors& e) { CHECK_EQ(2, e.getErrors().size()); CHECK_EQ("Generic types come before generic type packs", e.getErrors().front().getMessage()); @@ -2516,6 +2648,7 @@ type Z = { a: string | T..., b: number } TEST_CASE_FIXTURE(Fixture, "recover_function_return_type_annotations") { + ScopedFastFlag sff{"lluzReturnTypeTokenConfusion", true}; ParseResult result = tryParse(R"( type Custom = { x: A, y: B, z: C } type Packed = { x: (A...) -> () } @@ -2525,14 +2658,14 @@ local function f(x: number) -> Custom end )"); REQUIRE_EQ(3, result.errors.size()); - CHECK_EQ(result.errors[0].getMessage(), "Return types in function type annotations are written after '->' instead of ':'"); - CHECK_EQ(result.errors[1].getMessage(), "Return types in function type annotations are written after '->' instead of ':'"); - CHECK_EQ(result.errors[2].getMessage(), "Function return type annotations are written after ':' instead of '->'"); + CHECK_EQ(result.errors[0].getMessage(), XorStr("Return types in function type annotations are written after '->' instead of ':'")); + CHECK_EQ(result.errors[1].getMessage(), XorStr("Return types in function type annotations are written after '->' instead of ':'")); + CHECK_EQ(result.errors[2].getMessage(), XorStr("Function return type annotations are written after ':' instead of '->'")); } TEST_CASE_FIXTURE(Fixture, "error_message_for_using_function_as_type_annotation") { - ScopedFastFlag sff{"LuauParserFunctionKeywordAsTypeHelp", true}; + ScopedFastFlag sff{"lluzParserFunctionKeywordAsTypeHelp", true}; ParseResult result = tryParse(R"( type Foo = function )"); diff --git a/tests/Repl.test.cpp b/tests/Repl.test.cpp index 87a1e1e2..745f9643 100644 --- a/tests/Repl.test.cpp +++ b/tests/Repl.test.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #include "lua.h" #include "lualib.h" @@ -41,7 +41,7 @@ public: // Returns all of the output captured from the pretty printer std::string getCapturedOutput() { - lua_getglobal(L, "capturedoutput"); + lua_getglobal(L, XorStr("capturedoutput")); const char* str = lua_tolstring(L, -1, nullptr); std::string result(str); lua_pop(L, 1); @@ -55,7 +55,7 @@ public: getCompletions(L, inputPrefix, [&result](const std::string& completion, const std::string& display) { result.insert(Completion{completion, display}); }); - // Ensure that generating completions doesn't change the position of luau's stack top. + // Ensure that generating completions doesn't change the position of lluz's stack top. CHECK(top == lua_gettop(L)); return result; @@ -84,14 +84,14 @@ capturedoutput = "" function arraytostring(arr) local strings = {} table.foreachi(arr, function(k,v) table.insert(strings, pptostring(v)) end ) - return "{" .. table.concat(strings, ", ") .. "}" + return XorStr("{") .. table.concat(strings, ", ") .. "}" end function pptostring(x) - if type(x) == "table" then + if type(x) == XorStr("table") then -- Just assume array-like tables for now. return arraytostring(x) - elseif type(x) == "string" then + elseif type(x) == XorStr("string") then return '"' .. x .. '"' else return tostring(x) @@ -116,41 +116,41 @@ end )"; }; -TEST_SUITE_BEGIN("ReplPrettyPrint"); +TEST_SUITE_BEGIN(XorStr("ReplPrettyPrint")); TEST_CASE_FIXTURE(ReplFixture, "AdditionStatement") { - runCode(L, "return 30 + 12"); - CHECK(getCapturedOutput() == "42"); + runCode(L, XorStr("return 30 + 12")); + CHECK(getCapturedOutput() == XorStr("42")); } TEST_CASE_FIXTURE(ReplFixture, "TableLiteral") { - runCode(L, "return {1, 2, 3, 4}"); - CHECK(getCapturedOutput() == "{1, 2, 3, 4}"); + runCode(L, XorStr("return {1, 2, 3, 4}")); + CHECK(getCapturedOutput() == XorStr("{1, 2, 3, 4}")); } TEST_CASE_FIXTURE(ReplFixture, "StringLiteral") { - runCode(L, "return 'str'"); - CHECK(getCapturedOutput() == "\"str\""); + runCode(L, XorStr("return 'str'")); + CHECK(getCapturedOutput() == XorStr("\"str\"")); } TEST_CASE_FIXTURE(ReplFixture, "TableWithStringLiterals") { - runCode(L, "return {1, 'two', 3, 'four'}"); - CHECK(getCapturedOutput() == "{1, \"two\", 3, \"four\"}"); + runCode(L, XorStr("return {1, 'two', 3, 'four'}")); + CHECK(getCapturedOutput() == XorStr("{1, \"two\", 3, \"four\"}")); } TEST_CASE_FIXTURE(ReplFixture, "MultipleArguments") { - runCode(L, "return 3, 'three'"); - CHECK(getCapturedOutput() == "3\t\"three\""); + runCode(L, XorStr("return 3, 'three'")); + CHECK(getCapturedOutput() == XorStr("3\t\"three\"")); } TEST_SUITE_END(); -TEST_SUITE_BEGIN("ReplCodeCompletion"); +TEST_SUITE_BEGIN(XorStr("ReplCodeCompletion")); TEST_CASE_FIXTURE(ReplFixture, "CompleteGlobalVariables") { @@ -160,7 +160,7 @@ TEST_CASE_FIXTURE(ReplFixture, "CompleteGlobalVariables") )"); { // Try to complete globals that are added by the user's script - CompletionSet completions = getCompletionSet("myvar"); + CompletionSet completions = getCompletionSet(XorStr("myvar")); std::string prefix = ""; CHECK(completions.size() == 2); @@ -169,7 +169,7 @@ TEST_CASE_FIXTURE(ReplFixture, "CompleteGlobalVariables") } { // Try completing some builtin functions - CompletionSet completions = getCompletionSet("math.m"); + CompletionSet completions = getCompletionSet(XorStr("math.m")); std::string prefix = "math."; CHECK(completions.size() == 3); @@ -185,7 +185,7 @@ TEST_CASE_FIXTURE(ReplFixture, "CompleteTableKeys") t = { color = "red", size = 1, shape = "circle" } )"); { - CompletionSet completions = getCompletionSet("t."); + CompletionSet completions = getCompletionSet(XorStr("t.")); std::string prefix = "t."; CHECK(completions.size() == 3); @@ -195,7 +195,7 @@ TEST_CASE_FIXTURE(ReplFixture, "CompleteTableKeys") } { - CompletionSet completions = getCompletionSet("t.s"); + CompletionSet completions = getCompletionSet(XorStr("t.s")); std::string prefix = "t."; CHECK(completions.size() == 2); @@ -210,7 +210,7 @@ TEST_CASE_FIXTURE(ReplFixture, "StringMethods") s = "" )"); { - CompletionSet completions = getCompletionSet("s:l"); + CompletionSet completions = getCompletionSet(XorStr("s:l")); std::string prefix = "s:"; CHECK(completions.size() == 2); @@ -236,7 +236,7 @@ TEST_CASE_FIXTURE(ReplFixture, "TableWithMetatableIndexTable") t.tkey2 = 4 )"); { - CompletionSet completions = getCompletionSet("t.t"); + CompletionSet completions = getCompletionSet(XorStr("t.t")); std::string prefix = "t."; CHECK(completions.size() == 2); @@ -244,7 +244,7 @@ TEST_CASE_FIXTURE(ReplFixture, "TableWithMetatableIndexTable") CHECK(checkCompletion(completions, prefix, "tkey2")); } { - CompletionSet completions = getCompletionSet("t.tkey1.data2:re"); + CompletionSet completions = getCompletionSet(XorStr("t.tkey1.data2:re")); std::string prefix = "t.tkey1.data2:"; CHECK(completions.size() == 2); @@ -252,7 +252,7 @@ TEST_CASE_FIXTURE(ReplFixture, "TableWithMetatableIndexTable") CHECK(checkCompletion(completions, prefix, "reverse(")); } { - CompletionSet completions = getCompletionSet("t.mtk"); + CompletionSet completions = getCompletionSet(XorStr("t.mtk")); std::string prefix = "t."; CHECK(completions.size() == 2); @@ -260,7 +260,7 @@ TEST_CASE_FIXTURE(ReplFixture, "TableWithMetatableIndexTable") CHECK(checkCompletion(completions, prefix, "mtkey2")); } { - CompletionSet completions = getCompletionSet("t.mtkey1."); + CompletionSet completions = getCompletionSet(XorStr("t.mtkey1.")); std::string prefix = "t.mtkey1."; CHECK(completions.size() == 2); @@ -276,10 +276,10 @@ TEST_CASE_FIXTURE(ReplFixture, "TableWithMetatableIndexFunction") mt = {} mt.__index = function(table, key) print("mt.__index called") - if key == "foo" then - return "FOO" - elseif key == "bar" then - return "BAR" + if key == XorStr("foo") then + return XorStr("FOO") + elseif key == XorStr("bar") then + return XorStr("BAR") else return nil end @@ -290,7 +290,7 @@ TEST_CASE_FIXTURE(ReplFixture, "TableWithMetatableIndexFunction") t.tkey = 0 )"); { - CompletionSet completions = getCompletionSet("t.t"); + CompletionSet completions = getCompletionSet(XorStr("t.t")); std::string prefix = "t."; CHECK(completions.size() == 1); @@ -298,13 +298,13 @@ TEST_CASE_FIXTURE(ReplFixture, "TableWithMetatableIndexFunction") } { // t.foo is a valid key, but should not be completed because it requires calling an __index function - CompletionSet completions = getCompletionSet("t.foo"); + CompletionSet completions = getCompletionSet(XorStr("t.foo")); CHECK(completions.size() == 0); } { // t.foo is a valid key, but should not be found because it requires calling an __index function - CompletionSet completions = getCompletionSet("t.foo:"); + CompletionSet completions = getCompletionSet(XorStr("t.foo:")); CHECK(completions.size() == 0); } @@ -329,7 +329,7 @@ TEST_CASE_FIXTURE(ReplFixture, "TableWithMultipleMetatableIndexTables") t.tkey = 3 )"); { - CompletionSet completions = getCompletionSet("t."); + CompletionSet completions = getCompletionSet(XorStr("t.")); std::string prefix = "t."; CHECK(completions.size() == 4); @@ -339,7 +339,7 @@ TEST_CASE_FIXTURE(ReplFixture, "TableWithMultipleMetatableIndexTables") CHECK(checkCompletion(completions, prefix, "mt2key")); } { - CompletionSet completions = getCompletionSet("t.__index."); + CompletionSet completions = getCompletionSet(XorStr("t.__index.")); std::string prefix = "t.__index."; CHECK(completions.size() == 3); @@ -348,7 +348,7 @@ TEST_CASE_FIXTURE(ReplFixture, "TableWithMultipleMetatableIndexTables") CHECK(checkCompletion(completions, prefix, "mt2key")); } { - CompletionSet completions = getCompletionSet("t.mt2key."); + CompletionSet completions = getCompletionSet(XorStr("t.mt2key.")); std::string prefix = "t.mt2key."; CHECK(completions.size() == 2); @@ -364,7 +364,7 @@ TEST_CASE_FIXTURE(ReplFixture, "TableWithDeepMetatableIndexTables") function makeChainedTable(count) local result = {} result.__index = result - result[string.format("entry%d", count)] = { count = count } + result[string.format(XorStr("entry%d"), count)] = { count = count } if count == 0 then return result else @@ -377,27 +377,27 @@ t60 = makeChainedTable(60) )"); { // Check if entry0 exists - CompletionSet completions = getCompletionSet("t30.entry0"); + CompletionSet completions = getCompletionSet(XorStr("t30.entry0")); std::string prefix = "t30."; CHECK(checkCompletion(completions, prefix, "entry0")); } { // Check if entry0.count exists - CompletionSet completions = getCompletionSet("t30.entry0.co"); + CompletionSet completions = getCompletionSet(XorStr("t30.entry0.co")); std::string prefix = "t30.entry0."; CHECK(checkCompletion(completions, prefix, "count")); } { // Check if entry0 exists. With the max traversal limit of 50 in the repl, this should fail. - CompletionSet completions = getCompletionSet("t60.entry0"); + CompletionSet completions = getCompletionSet(XorStr("t60.entry0")); CHECK(completions.size() == 0); } { // Check if entry0.count exists. With the max traversal limit of 50 in the repl, this should fail. - CompletionSet completions = getCompletionSet("t60.entry0.co"); + CompletionSet completions = getCompletionSet(XorStr("t60.entry0.co")); CHECK(completions.size() == 0); } diff --git a/tests/RequireTracer.test.cpp b/tests/RequireTracer.test.cpp index ba03f363..0295fd14 100644 --- a/tests/RequireTracer.test.cpp +++ b/tests/RequireTracer.test.cpp @@ -1,12 +1,12 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/RequireTracer.h" -#include "Luau/Parser.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/RequireTracer.h" +#include "lluz/Parser.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; namespace { @@ -44,14 +44,14 @@ struct RequireTracerFixture Allocator allocator; AstNameTable names; - Luau::TestFileResolver fileResolver; + lluz::TestFileResolver fileResolver; }; const std::vector roots = {"game", "Game", "workspace", "Workspace", "script"}; } // namespace -TEST_SUITE_BEGIN("RequireTracerTest"); +TEST_SUITE_BEGIN(XorStr("RequireTracerTest")); TEST_CASE_FIXTURE(RequireTracerFixture, "trace_local") { @@ -60,7 +60,7 @@ TEST_CASE_FIXTURE(RequireTracerFixture, "trace_local") require(m) )"); - RequireTraceResult result = traceRequires(&fileResolver, block, "ModuleName"); + RequireTraceResult result = traceRequires(&fileResolver, block, XorStr("ModuleName")); REQUIRE(!result.exprs.empty()); AstStatLocal* loc = block->body.data[0]->as(); @@ -99,7 +99,7 @@ TEST_CASE_FIXTURE(RequireTracerFixture, "trace_transitive_local") REQUIRE_EQ(3, block->body.size); - RequireTraceResult result = traceRequires(&fileResolver, block, "ModuleName"); + RequireTraceResult result = traceRequires(&fileResolver, block, XorStr("ModuleName")); AstStatLocal* local = block->body.data[1]->as(); REQUIRE(local); @@ -116,7 +116,7 @@ TEST_CASE_FIXTURE(RequireTracerFixture, "trace_function_arguments") )"); REQUIRE_EQ(1, block->body.size); - RequireTraceResult result = traceRequires(&fileResolver, block, "ModuleName"); + RequireTraceResult result = traceRequires(&fileResolver, block, XorStr("ModuleName")); AstStatLocal* local = block->body.data[0]->as(); REQUIRE(local != nullptr); @@ -138,7 +138,7 @@ TEST_CASE_FIXTURE(RequireTracerFixture, "follow_typeof") )"); REQUIRE_EQ(1, block->body.size); - RequireTraceResult result = traceRequires(&fileResolver, block, "ModuleName"); + RequireTraceResult result = traceRequires(&fileResolver, block, XorStr("ModuleName")); AstStatLocal* local = block->body.data[0]->as(); REQUIRE(local != nullptr); @@ -153,7 +153,7 @@ TEST_CASE_FIXTURE(RequireTracerFixture, "follow_typeof") AstExprIndexName* indexName = typeofAnnotation->expr->as(); REQUIRE(indexName != nullptr); - REQUIRE_EQ(indexName->index, "UsefulObject"); + REQUIRE_EQ(indexName->index, XorStr("UsefulObject")); AstExprCall* call = indexName->expr->as(); REQUIRE(call != nullptr); @@ -170,7 +170,7 @@ TEST_CASE_FIXTURE(RequireTracerFixture, "follow_string_indexexpr") )"); REQUIRE_EQ(2, block->body.size); - RequireTraceResult result = traceRequires(&fileResolver, block, "ModuleName"); + RequireTraceResult result = traceRequires(&fileResolver, block, XorStr("ModuleName")); AstStatLocal* local = block->body.data[0]->as(); REQUIRE(local != nullptr); diff --git a/tests/RuntimeLimits.test.cpp b/tests/RuntimeLimits.test.cpp index 6619147b..a2922c48 100644 --- a/tests/RuntimeLimits.test.cpp +++ b/tests/RuntimeLimits.test.cpp @@ -1,4 +1,4 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details /* Tests in this source file are meant to be a bellwether to verify that the numeric limits we've set are sufficient for * most real-world scripts. @@ -13,14 +13,14 @@ #include "doctest.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(LuauLowerBoundsCalculation); +lluz_FASTFLAG(LluLowerBoundsCalculation); struct LimitFixture : BuiltinsFixture { #if defined(_NOOPT) || defined(_DEBUG) - ScopedFastInt LuauTypeInferRecursionLimit{"LuauTypeInferRecursionLimit", 100}; + ScopedFastInt lluzTypeInferRecursionLimit{"lluzTypeInferRecursionLimit", 100}; #endif }; @@ -33,7 +33,7 @@ bool hasError(const CheckResult& result, T* = nullptr) return it != result.errors.end(); } -TEST_SUITE_BEGIN("RuntimeLimits"); +TEST_SUITE_BEGIN(XorStr("RuntimeLimits")); TEST_CASE_FIXTURE(LimitFixture, "typescript_port_of_Result_type") { @@ -48,22 +48,22 @@ TEST_CASE_FIXTURE(LimitFixture, "typescript_port_of_Result_type") local lazyGet = TS.import(script, script.Parent.Parent, "util", "lazyLoad").lazyGet local unit = TS.import(script, script.Parent.Parent, "util", "Unit").unit local Iterator - lazyGet("Iterator", function(c) + lazyGet(XorStr("Iterator"), function(c) Iterator = c end) local Option - lazyGet("Option", function(c) + lazyGet(XorStr("Option"), function(c) Option = c end) local Vec - lazyGet("Vec", function(c) + lazyGet(XorStr("Vec"), function(c) Vec = c end) local Result do Result = setmetatable({}, { __tostring = function() - return "Result" + return XorStr("Result") end, }) Result.__index = Result @@ -254,9 +254,9 @@ TEST_CASE_FIXTURE(LimitFixture, "typescript_port_of_Result_type") end resultMeta.__tostring = function(result) return result:match(function(ok) - return "Result.ok(" .. tostring(ok) .. ")" + return XorStr("Result.ok(") .. tostring(ok) .. ")" end, function(err) - return "Result.err(" .. tostring(err) .. ")" + return XorStr("Result.err(") .. tostring(err) .. ")" end) end return { @@ -267,8 +267,8 @@ TEST_CASE_FIXTURE(LimitFixture, "typescript_port_of_Result_type") CheckResult result = check(src); CodeTooComplex ctc; - if (FFlag::LuauLowerBoundsCalculation) - LUAU_REQUIRE_ERRORS(result); + if (FFlag::LluLowerBoundsCalculation) + lluz_REQUIRE_ERRORS(result); else CHECK(hasError(result, &ctc)); } diff --git a/tests/ScopedFlags.h b/tests/ScopedFlags.h index 9454307e..6ba8ba64 100644 --- a/tests/ScopedFlags.h +++ b/tests/ScopedFlags.h @@ -1,7 +1,7 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #pragma once -#include "Luau/Common.h" +#include "lluz/Common.h" #include @@ -9,13 +9,13 @@ template struct ScopedFValue { private: - Luau::FValue* value = nullptr; + lluz::FValue* value = nullptr; T oldValue = T(); public: ScopedFValue(const char* name, T newValue) { - for (Luau::FValue* v = Luau::FValue::list; v; v = v->next) + for (lluz::FValue* v = lluz::FValue::list; v; v = v->next) if (strcmp(v->name, name) == 0) { value = v; @@ -24,7 +24,7 @@ public: break; } - LUAU_ASSERT(value); + lluz_ASSERT(value); } ScopedFValue(const ScopedFValue&) = delete; diff --git a/tests/StringUtils.test.cpp b/tests/StringUtils.test.cpp index afef3b06..7f671bcd 100644 --- a/tests/StringUtils.test.cpp +++ b/tests/StringUtils.test.cpp @@ -1,5 +1,5 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/StringUtils.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/StringUtils.h" #include "doctest.h" @@ -11,7 +11,7 @@ using LevenshteinMatrix = std::vector>; std::string format(std::string_view a, std::string_view b, size_t expected, size_t actual) { - return "Distance of '" + std::string(a) + "' and '" + std::string(b) + "': expected " + std::to_string(expected) + ", got " + + return XorStr("Distance of '") + std::string(a) + "' and '" + std::string(b) + "': expected " + std::to_string(expected) + ", got " + std::to_string(actual); } @@ -25,7 +25,7 @@ void compareLevenshtein(LevenshteinMatrix distances, std::string_view a, std::st std::string_view currentA = a.substr(0, x); std::string_view currentB = b.substr(0, y); - size_t actual = Luau::editDistance(currentA, currentB); + size_t actual = lluz::editDistance(currentA, currentB); size_t expected = distances[x][y]; CHECK_MESSAGE(actual == expected, format(currentA, currentB, expected, actual)); } @@ -33,7 +33,7 @@ void compareLevenshtein(LevenshteinMatrix distances, std::string_view a, std::st } } // namespace -TEST_SUITE_BEGIN("StringUtilsTest"); +TEST_SUITE_BEGIN(XorStr("StringUtilsTest")); #if 0 // This unit test is only used to measure how performant the current levenshtein distance algorithm is. @@ -48,13 +48,13 @@ TEST_CASE("BenchmarkLevenshteinDistance") // - are real words, // - have common prefix and suffix, and // - are sufficiently long enough to stress test with - std::string_view a("Intercalate"); - std::string_view b("Interchangeable"); + std::string_view a(XorStr("Intercalate")); + std::string_view b(XorStr("Interchangeable")); auto start = std::chrono::steady_clock::now(); for (int i = 0; i < count; ++i) - Luau::editDistance(a, b); + lluz::editDistance(a, b); auto end = std::chrono::steady_clock::now(); auto time = std::chrono::duration_cast(end - start); @@ -75,7 +75,7 @@ TEST_CASE("LevenshteinDistanceKittenSitting") {6, 6, 5, 4, 3, 3, 2, 3}, // N }; - compareLevenshtein(distances, "kitten", "sitting"); + compareLevenshtein(distances, XorStr("kitten", "sitting")); } TEST_CASE("LevenshteinDistanceSaturdaySunday") @@ -92,17 +92,17 @@ TEST_CASE("LevenshteinDistanceSaturdaySunday") {8, 7, 6, 6, 5, 4, 3}, // Y }; - compareLevenshtein(distances, "saturday", "sunday"); + compareLevenshtein(distances, XorStr("saturday", "sunday")); } TEST_CASE("EditDistanceIsAgnosticOfArgumentOrdering") { - CHECK_EQ(Luau::editDistance("blox", "block"), Luau::editDistance("block", "blox")); + CHECK_EQ(lluz::editDistance("blox", "block"), lluz::editDistance("block", "blox")); } TEST_CASE("AreWeUsingDistanceWithAdjacentTranspositionsAndNotOptimalStringAlignment") { - size_t distance = Luau::editDistance("CA", "ABC"); + size_t distance = lluz::editDistance(XorStr("CA", "ABC")); CHECK_EQ(distance, 2); } diff --git a/tests/Symbol.test.cpp b/tests/Symbol.test.cpp index e7d2973b..b5fe1662 100644 --- a/tests/Symbol.test.cpp +++ b/tests/Symbol.test.cpp @@ -1,14 +1,14 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Symbol.h" -#include "Luau/Ast.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Symbol.h" +#include "lluz/Ast.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("SymbolTests"); +TEST_SUITE_BEGIN(XorStr("SymbolTests")); TEST_CASE("hashing_globals") { diff --git a/tests/ToDot.test.cpp b/tests/ToDot.test.cpp index 95dcd70a..befcdcf1 100644 --- a/tests/ToDot.test.cpp +++ b/tests/ToDot.test.cpp @@ -1,15 +1,15 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Scope.h" -#include "Luau/ToDot.h" +#include "lluz/Scope.h" +#include "lluz/ToDot.h" #include "Fixture.h" #include "doctest.h" -LUAU_FASTFLAG(LuauLowerBoundsCalculation) +lluz_FASTFLAG(LluLowerBoundsCalculation) -using namespace Luau; +using namespace lluz; struct ToDotClassFixture : Fixture { @@ -40,7 +40,7 @@ struct ToDotClassFixture : Fixture } }; -TEST_SUITE_BEGIN("ToDot"); +TEST_SUITE_BEGIN(XorStr("ToDot")); TEST_CASE_FIXTURE(Fixture, "primitive") { @@ -49,7 +49,7 @@ local a: nil local b: number local c: any )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_NE("nil", toDot(requireType("a"))); @@ -84,9 +84,9 @@ TEST_CASE_FIXTURE(Fixture, "bound") local a = 444 local b = a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - std::optional ty = getType("b"); + std::optional ty = getType(XorStr("b")); REQUIRE(bool(ty)); ToDotOptions opts; @@ -104,14 +104,14 @@ TEST_CASE_FIXTURE(Fixture, "function") CheckResult result = check(R"( local function f(a, ...: string) return a end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("(a, ...string) -> a", toString(requireType("f"))); ToDotOptions opts; opts.showPointers = false; - if (FFlag::LuauLowerBoundsCalculation) + if (FFlag::LluLowerBoundsCalculation) { CHECK_EQ(R"(digraph graphname { n1 [label="FunctionTypeVar 1"]; @@ -158,7 +158,7 @@ TEST_CASE_FIXTURE(Fixture, "union") CheckResult result = check(R"( local a: string | number )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToDotOptions opts; opts.showPointers = false; @@ -177,7 +177,7 @@ TEST_CASE_FIXTURE(Fixture, "intersection") CheckResult result = check(R"( local a: string & number -- uninhabited )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToDotOptions opts; opts.showPointers = false; @@ -197,7 +197,7 @@ TEST_CASE_FIXTURE(Fixture, "table") type A = { x: T, y: (U...) -> (), [string]: any } local a: A )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToDotOptions opts; opts.showPointers = false; @@ -232,7 +232,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "metatable") CheckResult result = check(R"( local a: typeof(setmetatable({}, {})) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToDotOptions opts; opts.showPointers = false; @@ -287,7 +287,7 @@ TEST_CASE_FIXTURE(ToDotClassFixture, "class") CheckResult result = check(R"( local a: ChildClass )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToDotOptions opts; opts.showPointers = false; @@ -375,9 +375,9 @@ local b b.x = 2 b = a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - std::optional ty = getType("b"); + std::optional ty = getType(XorStr("b")); REQUIRE(bool(ty)); ToDotOptions opts; diff --git a/tests/ToString.test.cpp b/tests/ToString.test.cpp index 8c03fe55..1a6a5586 100644 --- a/tests/ToString.test.cpp +++ b/tests/ToString.test.cpp @@ -1,23 +1,22 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Scope.h" -#include "Luau/ToString.h" +#include "lluz/Scope.h" +#include "lluz/ToString.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(LuauRecursiveTypeParameterRestriction); -LUAU_FASTFLAG(LuauSpecialTypesAsterisked); +lluz_FASTFLAG(LluRecursiveTypeParameterRestriction); -TEST_SUITE_BEGIN("ToString"); +TEST_SUITE_BEGIN(XorStr("ToString")); TEST_CASE_FIXTURE(Fixture, "primitive") { - CheckResult result = check("local a = nil local b = 44 local c = 'lalala' local d = true"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local a = nil local b = 44 local c = 'lalala' local d = true")); + lluz_REQUIRE_NO_ERRORS(result); // A variable without an annotation and with a nil literal should infer as 'free', not 'nil' CHECK_NE("nil", toString(requireType("a"))); @@ -29,16 +28,16 @@ TEST_CASE_FIXTURE(Fixture, "primitive") TEST_CASE_FIXTURE(Fixture, "bound_types") { - CheckResult result = check("local a = 444 local b = a"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local a = 444 local b = a")); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireType("b"))); } TEST_CASE_FIXTURE(Fixture, "free_types") { - CheckResult result = check("local a"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local a")); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("a", toString(requireType("a"))); } @@ -63,6 +62,7 @@ TEST_CASE_FIXTURE(Fixture, "named_table") TEST_CASE_FIXTURE(Fixture, "empty_table") { + ScopedFastFlag lluzToStringTableBracesNewlines("lluzToStringTableBracesNewlines", true); CheckResult result = check(R"( local a: {} )"); @@ -77,6 +77,7 @@ TEST_CASE_FIXTURE(Fixture, "empty_table") TEST_CASE_FIXTURE(Fixture, "table_respects_use_line_break") { + ScopedFastFlag lluzToStringTableBracesNewlines("lluzToStringTableBracesNewlines", true); CheckResult result = check(R"( local a: { prop: string, anotherProp: number, thirdProp: boolean } )"); @@ -120,7 +121,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "named_metatable_toStringNamedFunction") type NamedMetatable = typeof(createTbl()) )"); - TypeId ty = requireType("createTbl"); + TypeId ty = requireType(XorStr("createTbl")); const FunctionTypeVar* ftv = get(follow(ty)); REQUIRE(ftv); CHECK_EQ("createTbl(): NamedMetatable", toStringNamedFunction("createTbl", *ftv)); @@ -166,7 +167,7 @@ TEST_CASE_FIXTURE(Fixture, "intersection_parenthesized_only_if_needed") auto utv = TypeVar{UnionTypeVar{{typeChecker.numberType, typeChecker.stringType}}}; auto itv = TypeVar{IntersectionTypeVar{{&utv, typeChecker.booleanType}}}; - CHECK_EQ(toString(&itv), "(number | string) & boolean"); + CHECK_EQ(toString(&itv), XorStr("(number | string) & boolean")); } TEST_CASE_FIXTURE(Fixture, "union_parenthesized_only_if_needed") @@ -174,7 +175,7 @@ TEST_CASE_FIXTURE(Fixture, "union_parenthesized_only_if_needed") auto itv = TypeVar{IntersectionTypeVar{{typeChecker.numberType, typeChecker.stringType}}}; auto utv = TypeVar{UnionTypeVar{{&itv, typeChecker.booleanType}}}; - CHECK_EQ(toString(&utv), "(number & string) | boolean"); + CHECK_EQ(toString(&utv), XorStr("(number & string) | boolean")); } TEST_CASE_FIXTURE(Fixture, "functions_are_always_parenthesized_in_unions_or_intersections") @@ -188,8 +189,8 @@ TEST_CASE_FIXTURE(Fixture, "functions_are_always_parenthesized_in_unions_or_inte auto utv = TypeVar{UnionTypeVar{{&ns2sn, &sn2ns}}}; auto itv = TypeVar{IntersectionTypeVar{{&ns2sn, &sn2ns}}}; - CHECK_EQ(toString(&utv), "((number, string) -> (string, number)) | ((string, number) -> (number, string))"); - CHECK_EQ(toString(&itv), "((number, string) -> (string, number)) & ((string, number) -> (number, string))"); + CHECK_EQ(toString(&utv), XorStr("((number, string) -> (string, number)) | ((string, number) -> (number, string))")); + CHECK_EQ(toString(&itv), XorStr("((number, string) -> (string, number)) & ((string, number) -> (number, string))")); } TEST_CASE_FIXTURE(Fixture, "intersections_respects_use_line_breaks") @@ -236,7 +237,7 @@ TEST_CASE_FIXTURE(Fixture, "quit_stringifying_table_type_when_length_is_exceeded ToStringOptions o; o.exhaustive = false; o.maxTableLength = 40; - CHECK_EQ(toString(&tv, o), "{ a: number, b: number, c: number, d: number, e: number, ... 10 more ... }"); + CHECK_EQ(toString(&tv, o), XorStr("{ a: number, b: number, c: number, d: number, e: number, ... 10 more ... }")); } TEST_CASE_FIXTURE(Fixture, "stringifying_table_type_is_still_capped_when_exhaustive") @@ -250,7 +251,7 @@ TEST_CASE_FIXTURE(Fixture, "stringifying_table_type_is_still_capped_when_exhaust ToStringOptions o; o.exhaustive = true; o.maxTableLength = 40; - CHECK_EQ(toString(&tv, o), "{ a: number, b: number, c: number, d: number, e: number, ... 2 more ... }"); + CHECK_EQ(toString(&tv, o), XorStr("{ a: number, b: number, c: number, d: number, e: number, ... 2 more ... }")); } TEST_CASE_FIXTURE(Fixture, "quit_stringifying_type_when_length_is_exceeded") @@ -261,23 +262,15 @@ TEST_CASE_FIXTURE(Fixture, "quit_stringifying_type_when_length_is_exceeded") function f2(f) return f or f1 end function f3(f) return f or f2 end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions o; o.exhaustive = false; o.maxTypeLength = 40; - CHECK_EQ(toString(requireType("f0"), o), "() -> ()"); - CHECK_EQ(toString(requireType("f1"), o), "(() -> ()) -> () -> ()"); - if (FFlag::LuauSpecialTypesAsterisked) - { - CHECK_EQ(toString(requireType("f2"), o), "((() -> ()) -> () -> ()) -> (() -> ()) -> ... *TRUNCATED*"); - CHECK_EQ(toString(requireType("f3"), o), "(((() -> ()) -> () -> ()) -> (() -> ()) -> ... *TRUNCATED*"); - } - else - { - CHECK_EQ(toString(requireType("f2"), o), "((() -> ()) -> () -> ()) -> (() -> ()) -> ... "); - CHECK_EQ(toString(requireType("f3"), o), "(((() -> ()) -> () -> ()) -> (() -> ()) -> ... "); - } + CHECK_EQ(toString(requireType(XorStr("f0"), o), "() -> ()")); + CHECK_EQ(toString(requireType(XorStr("f1"), o), "(() -> ()) -> () -> ()")); + CHECK_EQ(toString(requireType(XorStr("f2"), o), "((() -> ()) -> () -> ()) -> (() -> ()) -> ... ")); + CHECK_EQ(toString(requireType(XorStr("f3"), o), "(((() -> ()) -> () -> ()) -> (() -> ()) -> ... ")); } TEST_CASE_FIXTURE(Fixture, "stringifying_type_is_still_capped_when_exhaustive") @@ -288,24 +281,15 @@ TEST_CASE_FIXTURE(Fixture, "stringifying_type_is_still_capped_when_exhaustive") function f2(f) return f or f1 end function f3(f) return f or f2 end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions o; o.exhaustive = true; o.maxTypeLength = 40; - CHECK_EQ(toString(requireType("f0"), o), "() -> ()"); - CHECK_EQ(toString(requireType("f1"), o), "(() -> ()) -> () -> ()"); - if (FFlag::LuauSpecialTypesAsterisked) - { - CHECK_EQ(toString(requireType("f2"), o), "((() -> ()) -> () -> ()) -> (() -> ()) -> ... *TRUNCATED*"); - CHECK_EQ(toString(requireType("f3"), o), "(((() -> ()) -> () -> ()) -> (() -> ()) -> ... *TRUNCATED*"); - } - else - { - CHECK_EQ(toString(requireType("f2"), o), "((() -> ()) -> () -> ()) -> (() -> ()) -> ... "); - CHECK_EQ(toString(requireType("f3"), o), "(((() -> ()) -> () -> ()) -> (() -> ()) -> ... "); - } - + CHECK_EQ(toString(requireType(XorStr("f0"), o), "() -> ()")); + CHECK_EQ(toString(requireType(XorStr("f1"), o), "(() -> ()) -> () -> ()")); + CHECK_EQ(toString(requireType(XorStr("f2"), o), "((() -> ()) -> () -> ()) -> (() -> ()) -> ... ")); + CHECK_EQ(toString(requireType(XorStr("f3"), o), "(((() -> ()) -> () -> ()) -> (() -> ()) -> ... ")); } TEST_CASE_FIXTURE(Fixture, "stringifying_table_type_correctly_use_matching_table_state_braces") @@ -318,7 +302,7 @@ TEST_CASE_FIXTURE(Fixture, "stringifying_table_type_correctly_use_matching_table ToStringOptions o; o.maxTableLength = 40; - CHECK_EQ(toString(&tv, o), "{| a: number, b: number, c: number, d: number, e: number, ... 5 more ... |}"); + CHECK_EQ(toString(&tv, o), XorStr("{| a: number, b: number, c: number, d: number, e: number, ... 5 more ... |}")); } TEST_CASE_FIXTURE(Fixture, "stringifying_cyclic_union_type_bails_early") @@ -360,16 +344,16 @@ TEST_CASE_FIXTURE(Fixture, "stringifying_array_uses_array_syntax") TEST_CASE_FIXTURE(Fixture, "generic_packs_are_stringified_differently_from_generic_types") { TypePackVar tpv{GenericTypePack{"a"}}; - CHECK_EQ(toString(&tpv), "a..."); + CHECK_EQ(toString(&tpv), XorStr("a...")); TypeVar tv{GenericTypeVar{"a"}}; - CHECK_EQ(toString(&tv), "a"); + CHECK_EQ(toString(&tv), XorStr("a")); } TEST_CASE_FIXTURE(Fixture, "function_type_with_argument_names") { - CheckResult result = check("type MyFunc = (a: number, string, c: number) -> string; local a : MyFunc"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("type MyFunc = (a: number, string, c: number) -> string; local a : MyFunc")); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions opts; opts.functionTypeArguments = true; @@ -378,8 +362,8 @@ TEST_CASE_FIXTURE(Fixture, "function_type_with_argument_names") TEST_CASE_FIXTURE(Fixture, "function_type_with_argument_names_generic") { - CheckResult result = check("local function f(n: number, ...: a...): (a...) return ... end"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local function f(n: number, ...: a...): (a...) return ... end")); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions opts; opts.functionTypeArguments = true; @@ -396,7 +380,7 @@ type Table = typeof(tbl) type Foo = typeof(tbl.foo) local u: Foo )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions opts; opts.functionTypeArguments = true; @@ -414,7 +398,7 @@ TEST_CASE_FIXTURE(Fixture, "generate_friendly_names_for_inferred_generics") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("(a) -> a", toString(requireType("id"))); @@ -432,9 +416,9 @@ TEST_CASE_FIXTURE(Fixture, "toStringDetailed") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId id3Type = requireType("id3"); + TypeId id3Type = requireType(XorStr("id3")); ToStringResult nameData = toStringDetailed(id3Type); REQUIRE_EQ(3, nameData.nameMap.typeVars.size()); @@ -456,7 +440,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringDetailed") TEST_CASE_FIXTURE(BuiltinsFixture, "toStringDetailed2") { - ScopedFastFlag sff2{"DebugLuauSharedSelf", true}; + ScopedFastFlag sff2{"DebuglluzSharedSelf", true}; CheckResult result = check(R"( local base = {} @@ -469,9 +453,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "toStringDetailed2") local inst = {} setmetatable(inst, {__index=child}) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId tType = requireType("inst"); + TypeId tType = requireType(XorStr("inst")); ToStringResult r = toStringDetailed(tType); CHECK_EQ("{ @metatable { __index: { @metatable {| __index: base |}, child } }, inst }", r.name); CHECK_EQ(0, r.nameMap.typeVars.size()); @@ -514,11 +498,8 @@ TEST_CASE_FIXTURE(Fixture, "toStringErrorPack") local function target(callback: nil) return callback(4, "hello") end )"); - LUAU_REQUIRE_ERRORS(result); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("(nil) -> (*error-type*)", toString(requireType("target"))); - else - CHECK_EQ("(nil) -> ()", toString(requireType("target"))); + lluz_REQUIRE_ERRORS(result); + CHECK_EQ("(nil) -> (*unknown*)", toString(requireType("target"))); } TEST_CASE_FIXTURE(Fixture, "toStringGenericPack") @@ -527,8 +508,8 @@ TEST_CASE_FIXTURE(Fixture, "toStringGenericPack") function foo(a, b) return a(b) end )"); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("foo")), "((a) -> (b...), a) -> (b...)"); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ(toString(requireType(XorStr("foo")), "((a) -> (b...), a) -> (b...)")); } TEST_CASE_FIXTURE(Fixture, "toString_the_boundTo_table_type_contained_within_a_TypePack") @@ -561,7 +542,7 @@ TEST_CASE_FIXTURE(Fixture, "no_parentheses_around_cyclic_function_type_in_union" local g: F = f )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("t1 where t1 = ((() -> number)?) -> t1?", toString(requireType("g"))); } @@ -573,7 +554,7 @@ TEST_CASE_FIXTURE(Fixture, "no_parentheses_around_cyclic_function_type_in_inters local a: ((number) -> ()) & typeof(f) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("((number) -> ()) & t1 where t1 = () -> t1", toString(requireType("a"))); } @@ -585,7 +566,7 @@ TEST_CASE_FIXTURE(Fixture, "self_recursive_instantiated_param") ttv->name = "Table"; ttv->instantiatedTypeParams.push_back(&tableTy); - CHECK_EQ(toString(tableTy), "Table"); + CHECK_EQ(toString(tableTy), XorStr("Table
")); } TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_id") @@ -594,7 +575,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_id") local function id(x) return x end )"); - TypeId ty = requireType("id"); + TypeId ty = requireType(XorStr("id")); const FunctionTypeVar* ftv = get(follow(ty)); CHECK_EQ("id(x: a): a", toStringNamedFunction("id", *ftv)); @@ -612,7 +593,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_map") end )"); - TypeId ty = requireType("map"); + TypeId ty = requireType(XorStr("map")); const FunctionTypeVar* ftv = get(follow(ty)); CHECK_EQ("map(arr: {a}, fn: (a) -> b): {b}", toStringNamedFunction("map", *ftv)); @@ -628,7 +609,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_generic_pack") end )"); - TypeId ty = requireType("test"); + TypeId ty = requireType(XorStr("test")); const FunctionTypeVar* ftv = get(follow(ty)); CHECK_EQ("test(...: T...): U...", toStringNamedFunction("test", *ftv)); @@ -649,7 +630,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_variadics") end )"); - TypeId ty = requireType("f"); + TypeId ty = requireType(XorStr("f")); auto ftv = get(follow(ty)); CHECK_EQ("f(x: a, ...: any): (a, a, b...)", toStringNamedFunction("f", *ftv)); @@ -663,7 +644,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_variadics2") end )"); - TypeId ty = requireType("f"); + TypeId ty = requireType(XorStr("f")); auto ftv = get(follow(ty)); CHECK_EQ("f(): ...number", toStringNamedFunction("f", *ftv)); @@ -677,7 +658,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_variadics3") end )"); - TypeId ty = requireType("f"); + TypeId ty = requireType(XorStr("f")); auto ftv = get(follow(ty)); CHECK_EQ("f(): (string, ...number)", toStringNamedFunction("f", *ftv)); @@ -689,7 +670,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_type_annotation_has_partial_ar local f: (number, y: number) -> number )"); - TypeId ty = requireType("f"); + TypeId ty = requireType(XorStr("f")); auto ftv = get(follow(ty)); CHECK_EQ("f(_: number, y: number): number", toStringNamedFunction("f", *ftv)); @@ -702,7 +683,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_hide_type_params") end )"); - TypeId ty = requireType("f"); + TypeId ty = requireType(XorStr("f")); auto ftv = get(follow(ty)); ToStringOptions opts; @@ -716,7 +697,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_overrides_param_names") local function test(a, b : string, ... : number) return a end )"); - TypeId ty = requireType("test"); + TypeId ty = requireType(XorStr("test")); const FunctionTypeVar* ftv = get(follow(ty)); ToStringOptions opts; @@ -727,7 +708,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_overrides_param_names") TEST_CASE_FIXTURE(Fixture, "pick_distinct_names_for_mixed_explicit_and_implicit_generics") { ScopedFastFlag sff[] = { - {"LuauAlwaysQuantify", true}, + {"lluzAlwaysQuantify", true}, }; CheckResult result = check(R"( @@ -740,7 +721,7 @@ TEST_CASE_FIXTURE(Fixture, "pick_distinct_names_for_mixed_explicit_and_implicit_ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_include_self_param") { ScopedFastFlag sff[]{ - {"DebugLuauSharedSelf", true}, + {"DebuglluzSharedSelf", true}, }; CheckResult result = check(R"( @@ -749,7 +730,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_include_self_param") end )"); - TypeId parentTy = requireType("foo"); + TypeId parentTy = requireType(XorStr("foo")); auto ttv = get(follow(parentTy)); auto ftv = get(ttv->props.at("method").type); @@ -759,7 +740,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_include_self_param") TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_hide_self_param") { ScopedFastFlag sff[]{ - {"DebugLuauSharedSelf", true}, + {"DebuglluzSharedSelf", true}, }; CheckResult result = check(R"( @@ -768,7 +749,7 @@ TEST_CASE_FIXTURE(Fixture, "toStringNamedFunction_hide_self_param") end )"); - TypeId parentTy = requireType("foo"); + TypeId parentTy = requireType(XorStr("foo")); auto ttv = get(follow(parentTy)); auto ftv = get(ttv->props.at("method").type); diff --git a/tests/TopoSort.test.cpp b/tests/TopoSort.test.cpp index 1f14ae88..62a0a570 100644 --- a/tests/TopoSort.test.cpp +++ b/tests/TopoSort.test.cpp @@ -1,23 +1,23 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/TopoSortStatements.h" -#include "Luau/Transpiler.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/TopoSortStatements.h" +#include "lluz/Transpiler.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; static std::vector toposort(AstStatBlock& block) { std::vector result{block.body.begin(), block.body.end()}; - Luau::toposort(result); + lluz::toposort(result); return result; } -TEST_SUITE_BEGIN("TopoSortTests"); +TEST_SUITE_BEGIN(XorStr("TopoSortTests")); TEST_CASE_FIXTURE(Fixture, "sorts") { @@ -345,7 +345,7 @@ TEST_CASE_FIXTURE(Fixture, "return_comes_last") local function confuseCompiler() return module.foo() end - module.foo = function() return "" end + module.foo = function() return XorStr("") end function module.bar(x:number) confuseCompiler() @@ -370,7 +370,7 @@ TEST_CASE_FIXTURE(Fixture, "break_comes_last") repeat local module = {} local function confuseCompiler() return module.foo() end -module.foo = function() return "" end +module.foo = function() return XorStr("") end break until true )"); @@ -394,7 +394,7 @@ TEST_CASE_FIXTURE(Fixture, "continue_comes_last") repeat local module = {} local function confuseCompiler() return module.foo() end -module.foo = function() return "" end +module.foo = function() return XorStr("") end continue until true )"); diff --git a/tests/Transpiler.test.cpp b/tests/Transpiler.test.cpp index d2ed9aef..9be1352b 100644 --- a/tests/Transpiler.test.cpp +++ b/tests/Transpiler.test.cpp @@ -1,17 +1,17 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Parser.h" -#include "Luau/TypeAttach.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" -#include "Luau/Transpiler.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Parser.h" +#include "lluz/TypeAttach.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" +#include "lluz/Transpiler.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("TranspilerTests"); +TEST_SUITE_BEGIN(XorStr("TranspilerTests")); TEST_CASE("test_1") { @@ -197,7 +197,7 @@ TEST_CASE("method_definitions") TEST_CASE("spaces_between_keywords_even_if_it_pushes_the_line_estimation_off") { - // Luau::Parser doesn't exactly preserve the string representation of numbers in Lua, so we can find ourselves + // lluz::Parser doesn't exactly preserve the string representation of numbers in Lua, so we can find ourselves // falling out of sync with the original code. We need to push keywords out so that there's at least one space between them. const std::string code = R"( if math.abs(raySlope) < .01 then return 0 end )"; const std::string expected = R"( if math.abs(raySlope) < 0.01 then return 0 end)"; diff --git a/tests/TypeInfer.aliases.test.cpp b/tests/TypeInfer.aliases.test.cpp index bdd4d6fd..25cde3a5 100644 --- a/tests/TypeInfer.aliases.test.cpp +++ b/tests/TypeInfer.aliases.test.cpp @@ -1,15 +1,15 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #include "Fixture.h" #include "doctest.h" -#include "Luau/BuiltinDefinitions.h" +#include "lluz/BuiltinDefinitions.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution) +lluz_FASTFLAG(DebugLluDeferredConstraintResolution) -TEST_SUITE_BEGIN("TypeAliases"); +TEST_SUITE_BEGIN(XorStr("TypeAliases")); TEST_CASE_FIXTURE(Fixture, "basic_alias") { @@ -18,7 +18,7 @@ TEST_CASE_FIXTURE(Fixture, "basic_alias") local x: T = 1 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireType("x"))); } @@ -33,7 +33,7 @@ TEST_CASE_FIXTURE(Fixture, "cyclic_function_type_in_type_alias") local g: F = f )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("t1 where t1 = () -> t1?", toString(requireType("g"))); } @@ -44,7 +44,7 @@ TEST_CASE_FIXTURE(Fixture, "names_are_ascribed") local x: T )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("T", toString(requireType("x"))); } @@ -69,8 +69,8 @@ TEST_CASE_FIXTURE(Fixture, "cannot_steal_hoisted_type_alias") type T = number )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - if (FFlag::DebugLuauDeferredConstraintResolution) + lluz_REQUIRE_ERROR_COUNT(1, result); + if (FFlag::DebugLluDeferredConstraintResolution) { CHECK(result.errors[0] == TypeError{ Location{{1, 21}, {1, 26}}, @@ -103,7 +103,7 @@ TEST_CASE_FIXTURE(Fixture, "cyclic_types_of_named_table_fields_do_not_expand_whe node.Parent = 1 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -123,7 +123,7 @@ TEST_CASE_FIXTURE(Fixture, "mutually_recursive_aliases") y.g.i = y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "mutually_recursive_generic_aliases") @@ -138,7 +138,7 @@ TEST_CASE_FIXTURE(Fixture, "mutually_recursive_generic_aliases") y.g.i = y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "mutually_recursive_types_errors") @@ -153,10 +153,10 @@ TEST_CASE_FIXTURE(Fixture, "mutually_recursive_types_errors") y.g.i = y )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); // We had a UAF in this example caused by not cloning type function arguments - ModulePtr module = frontend.moduleResolver.getModule("MainModule"); + ModulePtr module = frontend.moduleResolver.getModule(XorStr("MainModule")); unfreeze(module->interfaceTypes); copyErrors(module->errors, module->interfaceTypes); freeze(module->interfaceTypes); @@ -178,7 +178,7 @@ TEST_CASE_FIXTURE(Fixture, "use_table_name_and_generic_params_in_errors") a = b )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -195,7 +195,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_stop_typechecking_after_reporting_duplicate_typ local foo: string = 1 -- "Type 'number' could not be converted into 'string'" )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); } TEST_CASE_FIXTURE(Fixture, "stringify_type_alias_of_recursive_template_table_type") @@ -206,7 +206,7 @@ TEST_CASE_FIXTURE(Fixture, "stringify_type_alias_of_recursive_template_table_typ local l: Wrapped = 2 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -222,7 +222,7 @@ TEST_CASE_FIXTURE(Fixture, "stringify_type_alias_of_recursive_template_table_typ local l: Wrapped = 2 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -240,7 +240,7 @@ TEST_CASE_FIXTURE(Fixture, "cli_38393_recursive_intersection_oom") _(_) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "type_alias_fwd_declaration_is_precise") @@ -250,7 +250,7 @@ TEST_CASE_FIXTURE(Fixture, "type_alias_fwd_declaration_is_precise") type Id = T )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "corecursive_types_generic") @@ -272,7 +272,7 @@ TEST_CASE_FIXTURE(Fixture, "corecursive_types_generic") CHECK_EQ(expected, decorateWithTypes(code)); CheckResult result = check(code); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "corecursive_function_types") @@ -284,7 +284,7 @@ TEST_CASE_FIXTURE(Fixture, "corecursive_function_types") local b: B )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("t1 where t1 = () -> (number, () -> (string, t1))", toString(requireType("a"))); CHECK_EQ("t1 where t1 = () -> (string, () -> (number, t1))", toString(requireType("b"))); @@ -309,7 +309,7 @@ TEST_CASE_FIXTURE(Fixture, "generic_param_remap") CHECK_EQ(expected, decorateWithTypes(code)); CheckResult result = check(code); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "export_type_and_type_alias_are_duplicates") @@ -319,11 +319,11 @@ TEST_CASE_FIXTURE(Fixture, "export_type_and_type_alias_are_duplicates") type Foo = number )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto dtd = get(result.errors[0]); REQUIRE(dtd); - CHECK_EQ(dtd->name, "Foo"); + CHECK_EQ(dtd->name, XorStr("Foo")); } TEST_CASE_FIXTURE(Fixture, "reported_location_is_correct_when_type_alias_are_duplicates") @@ -335,11 +335,11 @@ TEST_CASE_FIXTURE(Fixture, "reported_location_is_correct_when_type_alias_are_dup type B = number )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto dtd = get(result.errors[0]); REQUIRE(dtd); - CHECK_EQ(dtd->name, "B"); + CHECK_EQ(dtd->name, XorStr("B")); CHECK_EQ(dtd->previousLocation.begin.line + 1, 3); } @@ -357,7 +357,7 @@ TEST_CASE_FIXTURE(Fixture, "stringify_optional_parameterized_alias") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto e = get(result.errors[0]); CHECK_EQ("Node?", toString(e->givenType)); @@ -383,32 +383,32 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "general_require_multi_assign") local b: Bar.myvec3 )"; - CheckResult result = frontend.check("workspace/C"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = frontend.check(XorStr("workspace/C")); + lluz_REQUIRE_NO_ERRORS(result); ModulePtr m = frontend.moduleResolver.modules["workspace/C"]; REQUIRE(m != nullptr); - std::optional aTypeId = lookupName(m->getModuleScope(), "a"); + std::optional aTypeId = lookupName(m->getModuleScope(), XorStr("a")); REQUIRE(aTypeId); - const Luau::TableTypeVar* aType = get(follow(*aTypeId)); + const lluz::TableTypeVar* aType = get(follow(*aTypeId)); REQUIRE(aType); REQUIRE(aType->props.size() == 2); - std::optional bTypeId = lookupName(m->getModuleScope(), "b"); + std::optional bTypeId = lookupName(m->getModuleScope(), XorStr("b")); REQUIRE(bTypeId); - const Luau::TableTypeVar* bType = get(follow(*bTypeId)); + const lluz::TableTypeVar* bType = get(follow(*bTypeId)); REQUIRE(bType); REQUIRE(bType->props.size() == 3); } TEST_CASE_FIXTURE(BuiltinsFixture, "type_alias_import_mutation") { - CheckResult result = check("type t10 = typeof(table)"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("type t10 = typeof(table)")); + lluz_REQUIRE_NO_ERRORS(result); - TypeId ty = getGlobalBinding(frontend.typeChecker, "table"); - CHECK_EQ(toString(ty), "table"); + TypeId ty = getGlobalBinding(frontend.typeChecker, XorStr("table")); + CHECK_EQ(toString(ty), XorStr("table")); const TableTypeVar* ttv = get(ty); REQUIRE(ttv); @@ -423,11 +423,11 @@ type Cool = { a: number, b: string } local c: Cool = { a = 1, b = "s" } type NotCool = Cool )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - std::optional ty = requireType("c"); + std::optional ty = requireType(XorStr("c")); REQUIRE(ty); - CHECK_EQ(toString(*ty), "Cool"); + CHECK_EQ(toString(*ty), XorStr("Cool")); const TableTypeVar* ttv = get(*ty); REQUIRE(ttv); @@ -443,15 +443,15 @@ type NotCool = Cool local c: Cool = { a = 1, b = "s" } local d: NotCool = { a = 1, b = "s" } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - std::optional ty = requireType("c"); + std::optional ty = requireType(XorStr("c")); REQUIRE(ty); - CHECK_EQ(toString(*ty), "Cool"); + CHECK_EQ(toString(*ty), XorStr("Cool")); - ty = requireType("d"); + ty = requireType(XorStr("d")); REQUIRE(ty); - CHECK_EQ(toString(*ty), "NotCool"); + CHECK_EQ(toString(*ty), XorStr("NotCool")); } TEST_CASE_FIXTURE(Fixture, "type_alias_local_synthetic_mutation") @@ -460,14 +460,14 @@ TEST_CASE_FIXTURE(Fixture, "type_alias_local_synthetic_mutation") local c = { a = 1, b = "s" } type Cool = typeof(c) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - std::optional ty = requireType("c"); + std::optional ty = requireType(XorStr("c")); REQUIRE(ty); const TableTypeVar* ttv = get(*ty); REQUIRE(ttv); - CHECK_EQ(ttv->name, "Cool"); + CHECK_EQ(ttv->name, XorStr("Cool")); } TEST_CASE_FIXTURE(BuiltinsFixture, "type_alias_of_an_imported_recursive_type") @@ -477,19 +477,19 @@ export type X = { a: number, b: X? } return {} )"; - CheckResult aResult = frontend.check("game/A"); - LUAU_REQUIRE_NO_ERRORS(aResult); + CheckResult aResult = frontend.check(XorStr("game/A")); + lluz_REQUIRE_NO_ERRORS(aResult); CheckResult bResult = check(R"( local Import = require(game.A) type X = Import.X )"); - LUAU_REQUIRE_NO_ERRORS(bResult); + lluz_REQUIRE_NO_ERRORS(bResult); - std::optional ty1 = lookupImportedType("Import", "X"); + std::optional ty1 = lookupImportedType(XorStr("Import", "X")); REQUIRE(ty1); - std::optional ty2 = lookupType("X"); + std::optional ty2 = lookupType(XorStr("X")); REQUIRE(ty2); CHECK_EQ(follow(*ty1), follow(*ty2)); @@ -502,19 +502,19 @@ export type X = { a: T, b: U, C: X? } return {} )"; - CheckResult aResult = frontend.check("game/A"); - LUAU_REQUIRE_NO_ERRORS(aResult); + CheckResult aResult = frontend.check(XorStr("game/A")); + lluz_REQUIRE_NO_ERRORS(aResult); CheckResult bResult = check(R"( local Import = require(game.A) type X = Import.X )"); - LUAU_REQUIRE_NO_ERRORS(bResult); + lluz_REQUIRE_NO_ERRORS(bResult); - std::optional ty1 = lookupImportedType("Import", "X"); + std::optional ty1 = lookupImportedType(XorStr("Import", "X")); REQUIRE(ty1); - std::optional ty2 = lookupType("X"); + std::optional ty2 = lookupType(XorStr("X")); REQUIRE(ty2); CHECK_EQ(toString(*ty1, {true}), toString(*ty2, {true})); @@ -523,16 +523,16 @@ type X = Import.X local Import = require(game.A) type X = Import.X )"); - LUAU_REQUIRE_NO_ERRORS(bResult); + lluz_REQUIRE_NO_ERRORS(bResult); - ty1 = lookupImportedType("Import", "X"); + ty1 = lookupImportedType(XorStr("Import", "X")); REQUIRE(ty1); - ty2 = lookupType("X"); + ty2 = lookupType(XorStr("X")); REQUIRE(ty2); - CHECK_EQ(toString(*ty1, {true}), "t1 where t1 = {| C: t1?, a: T, b: U |}"); - CHECK_EQ(toString(*ty2, {true}), "{| C: t1, a: U, b: T |} where t1 = {| C: t1, a: U, b: T |}?"); + CHECK_EQ(toString(*ty1, {true}), XorStr("t1 where t1 = {| C: t1?, a: T, b: U |}")); + CHECK_EQ(toString(*ty2, {true}), XorStr("{| C: t1, a: U, b: T |} where t1 = {| C: t1, a: U, b: T |}?")); } TEST_CASE_FIXTURE(Fixture, "module_export_free_type_leak") @@ -545,7 +545,7 @@ end export type f = typeof(get()) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "module_export_wrapped_free_type_leak") @@ -558,7 +558,7 @@ end export type f = typeof(get()) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } @@ -569,7 +569,7 @@ TEST_CASE_FIXTURE(Fixture, "mutually_recursive_types_restriction_ok") type Forest = {Tree} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "mutually_recursive_types_restriction_not_ok_1") @@ -580,7 +580,7 @@ TEST_CASE_FIXTURE(Fixture, "mutually_recursive_types_restriction_not_ok_1") type Forest = {Tree<{T}>} )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "mutually_recursive_types_restriction_not_ok_2") @@ -591,7 +591,7 @@ TEST_CASE_FIXTURE(Fixture, "mutually_recursive_types_restriction_not_ok_2") type Tree = { data: T, children: Forest } )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "mutually_recursive_types_swapsies_ok") @@ -601,7 +601,7 @@ TEST_CASE_FIXTURE(Fixture, "mutually_recursive_types_swapsies_ok") type Tree2 = { data: U, children: {Tree1} } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "mutually_recursive_types_swapsies_not_ok") @@ -611,7 +611,7 @@ TEST_CASE_FIXTURE(Fixture, "mutually_recursive_types_swapsies_not_ok") type Tree2 = { data: U, children: {Tree1} } )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "free_variables_from_typeof_in_aliases") @@ -624,7 +624,7 @@ TEST_CASE_FIXTURE(Fixture, "free_variables_from_typeof_in_aliases") type ContainsContainsFree = { that: ContainsFree } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "non_recursive_aliases_that_reuse_a_generic_name") @@ -636,7 +636,7 @@ TEST_CASE_FIXTURE(Fixture, "non_recursive_aliases_that_reuse_a_generic_name") local p: Tuple )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("{number | string}", toString(requireType("p"), {true})); } @@ -672,7 +672,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "do_not_quantify_unresolved_aliases") export type Key = typeof(newkey(newKeyPool(), 1)) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } /* @@ -688,7 +688,7 @@ TEST_CASE_FIXTURE(Fixture, "generic_typevars_are_not_considered_to_escape_their_ type Exclude = T )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } /* @@ -711,13 +711,13 @@ TEST_CASE_FIXTURE(Fixture, "forward_declared_alias_is_not_clobbered_by_prior_uni CHECK_EQ("{| foo: number |}", toString(requireType("d"), {true})); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "forward_declared_alias_is_not_clobbered_by_prior_unification_with_any_2") { ScopedFastFlag sff[] = { - {"DebugLuauSharedSelf", true}, + {"DebuglluzSharedSelf", true}, }; CheckResult result = check(R"( @@ -742,7 +742,7 @@ TEST_CASE_FIXTURE(Fixture, "forward_declared_alias_is_not_clobbered_by_prior_uni )"); // TODO: shared self causes this test to break in bizarre ways. - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "recursive_types_restriction_ok") @@ -751,7 +751,7 @@ TEST_CASE_FIXTURE(Fixture, "recursive_types_restriction_ok") type Tree = { data: T, children: {Tree} } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "recursive_types_restriction_not_ok") @@ -761,7 +761,7 @@ TEST_CASE_FIXTURE(Fixture, "recursive_types_restriction_not_ok") type Tree = { data: T, children: {Tree<{T}>} } )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_SUITE_END(); diff --git a/tests/TypeInfer.annotations.test.cpp b/tests/TypeInfer.annotations.test.cpp index 8a86ee5f..eab5057f 100644 --- a/tests/TypeInfer.annotations.test.cpp +++ b/tests/TypeInfer.annotations.test.cpp @@ -1,32 +1,32 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/BuiltinDefinitions.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/BuiltinDefinitions.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("AnnotationTests"); +TEST_SUITE_BEGIN(XorStr("AnnotationTests")); TEST_CASE_FIXTURE(Fixture, "check_against_annotations") { - CheckResult result = check("local a: number = \"Hello Types!\""); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("local a: number = \"Hello Types!\"")); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "check_multi_assign") { - CheckResult result = check("local a: number, b: string = \"994\", 888"); + CheckResult result = check(XorStr("local a: number, b: string = \"994\", 888")); CHECK_EQ(2, result.errors.size()); } TEST_CASE_FIXTURE(Fixture, "successful_check") { - CheckResult result = check("local a: number, b: string = 994, \"eight eighty eight\""); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local a: number, b: string = 994, \"eight eighty eight\"")); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); } @@ -37,7 +37,7 @@ TEST_CASE_FIXTURE(Fixture, "variable_type_is_supertype") local y: number? = x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "function_parameters_can_have_annotations") @@ -50,7 +50,7 @@ TEST_CASE_FIXTURE(Fixture, "function_parameters_can_have_annotations") local four = double(2) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "function_parameter_annotations_are_checked") @@ -63,7 +63,7 @@ TEST_CASE_FIXTURE(Fixture, "function_parameter_annotations_are_checked") local four = double("two") )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "function_return_annotations_are_checked") @@ -74,9 +74,9 @@ TEST_CASE_FIXTURE(Fixture, "function_return_annotations_are_checked") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId fiftyType = requireType("fifty"); + TypeId fiftyType = requireType(XorStr("fifty")); const FunctionTypeVar* ftv = get(fiftyType); REQUIRE(ftv != nullptr); @@ -97,7 +97,7 @@ TEST_CASE_FIXTURE(Fixture, "function_return_multret_annotations_are_checked") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "function_return_annotation_should_disambiguate_into_function_type_return_and_checked") @@ -108,7 +108,7 @@ TEST_CASE_FIXTURE(Fixture, "function_return_annotation_should_disambiguate_into_ end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "function_return_annotation_should_continuously_parse_return_annotation_and_checked") @@ -123,7 +123,7 @@ TEST_CASE_FIXTURE(Fixture, "function_return_annotation_should_continuously_parse end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "unknown_type_reference_generates_error") @@ -132,7 +132,7 @@ TEST_CASE_FIXTURE(Fixture, "unknown_type_reference_generates_error") local x: IDoNotExist )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK(result.errors[0] == TypeError{ Location{{1, 17}, {1, 28}}, getMainSourceModule()->name, @@ -153,7 +153,7 @@ TEST_CASE_FIXTURE(Fixture, "typeof_variable_type_annotation_should_return_its_ty local foo2: Foo )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(requireType("foo"), requireType("foo2")); } @@ -169,7 +169,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_type_of_value_a_via_typeof_with_assignment") CHECK_EQ(*typeChecker.numberType, *requireType("a")); CHECK_EQ(*typeChecker.numberType, *requireType("b")); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(result.errors[0], (TypeError{Location{Position{4, 12}, Position{4, 17}}, TypeMismatch{typeChecker.numberType, typeChecker.stringType}})); } @@ -180,7 +180,7 @@ TEST_CASE_FIXTURE(Fixture, "table_annotation") local y = x.a local z = x.b )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(PrimitiveTypeVar::Number, getPrimitiveType(follow(requireType("y")))); CHECK_EQ(PrimitiveTypeVar::String, getPrimitiveType(follow(requireType("z")))); @@ -191,11 +191,11 @@ TEST_CASE_FIXTURE(Fixture, "function_annotation") CheckResult result = check(R"( local f: (number, string) -> number )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); - TypeId fType = requireType("f"); + TypeId fType = requireType(XorStr("f")); const FunctionTypeVar* ftv = get(follow(fType)); REQUIRE(ftv != nullptr); @@ -204,19 +204,19 @@ TEST_CASE_FIXTURE(Fixture, "function_annotation") TEST_CASE_FIXTURE(Fixture, "function_annotation_with_a_defined_function") { CheckResult result = check(R"( - local f: (number, number) -> string = function(a: number, b: number) return "" end + local f: (number, number) -> string = function(a: number, b: number) return XorStr("") end )"); - TypeId fType = requireType("f"); + TypeId fType = requireType(XorStr("f")); const FunctionTypeVar* ftv = get(follow(fType)); REQUIRE(ftv != nullptr); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "type_assertion_expr") { - CheckResult result = check("local a = 55 :: any"); + CheckResult result = check(XorStr("local a = 55 :: any")); REQUIRE_EQ("any", toString(requireType("a"))); } @@ -227,7 +227,7 @@ TEST_CASE_FIXTURE(Fixture, "as_expr_does_not_propagate_type_info") local b = a :: number )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("a"))); CHECK_EQ("number", toString(requireType("b"))); @@ -240,7 +240,7 @@ TEST_CASE_FIXTURE(Fixture, "as_expr_is_bidirectional") local b = a :: number )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number?", toString(requireType("a"))); CHECK_EQ("number", toString(requireType("b"))); @@ -252,7 +252,7 @@ TEST_CASE_FIXTURE(Fixture, "as_expr_warns_on_unrelated_cast") local a = 55 :: string )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Cannot cast 'number' into 'string' because the types are unrelated", toString(result.errors[0])); CHECK_EQ("string", toString(requireType("a"))); @@ -267,19 +267,19 @@ TEST_CASE_FIXTURE(Fixture, "type_annotations_inside_function_bodies") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); } TEST_CASE_FIXTURE(Fixture, "for_loop_counter_annotation") { - CheckResult result1 = check(R"( for i: number = 0, 50 do end )"); - LUAU_REQUIRE_NO_ERRORS(result1); + CheckResult result1 = check(RXorStr("( for i: number = 0, 50 do end )")); + lluz_REQUIRE_NO_ERRORS(result1); } TEST_CASE_FIXTURE(Fixture, "for_loop_counter_annotation_is_checked") { - CheckResult result2 = check(R"( for i: string = 0, 10 do end )"); + CheckResult result2 = check(RXorStr("( for i: string = 0, 10 do end )")); CHECK_EQ(1, result2.errors.size()); } @@ -289,7 +289,7 @@ TEST_CASE_FIXTURE(Fixture, "type_alias_should_alias_to_number") type A = number local a: A = 10 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "type_alias_B_should_check_with_another_aliases_until_a_non_aliased_type") @@ -299,7 +299,7 @@ TEST_CASE_FIXTURE(Fixture, "type_alias_B_should_check_with_another_aliases_until type B = A local b: B = 10 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "type_aliasing_to_number_should_not_check_given_a_string") @@ -308,7 +308,7 @@ TEST_CASE_FIXTURE(Fixture, "type_aliasing_to_number_should_not_check_given_a_str type A = number local a: A = "fail" )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "self_referential_type_alias") @@ -317,16 +317,16 @@ TEST_CASE_FIXTURE(Fixture, "self_referential_type_alias") type O = { x: number, incr: (O) -> number } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - std::optional res = getMainModule()->getModuleScope()->lookupType("O"); + std::optional res = getMainModule()->getModuleScope()->lookupType(XorStr("O")); REQUIRE(res); TypeId oType = follow(res->type); const TableTypeVar* oTable = get(oType); REQUIRE(oTable); - std::optional incr = get(oTable->props, "incr"); + std::optional incr = get(oTable->props, XorStr("incr")); REQUIRE(incr); const FunctionTypeVar* incrFunc = get(incr->type); @@ -344,11 +344,11 @@ TEST_CASE_FIXTURE(Fixture, "define_generic_type_alias") type Array = {[number]: T} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ModulePtr mainModule = getMainModule(); - auto it = mainModule->getModuleScope()->privateTypeBindings.find("Array"); + auto it = mainModule->getModuleScope()->privateTypeBindings.find(XorStr("Array")); REQUIRE(it != mainModule->getModuleScope()->privateTypeBindings.end()); TypeFun& tf = it->second; @@ -364,7 +364,7 @@ TEST_CASE_FIXTURE(Fixture, "use_generic_type_alias") p[2] = 'hello' -- 4 Error. )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(4, result.errors[0].location.begin.line); CHECK(nullptr != get(result.errors[0])); @@ -379,11 +379,11 @@ TEST_CASE_FIXTURE(Fixture, "two_type_params") local b = m[9] -- error here )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(4, result.errors[0].location.begin.line); - CHECK_EQ(toString(requireType("a")), "number"); + CHECK_EQ(toString(requireType(XorStr("a")), "number")); } TEST_CASE_FIXTURE(Fixture, "too_many_type_params") @@ -393,7 +393,7 @@ TEST_CASE_FIXTURE(Fixture, "too_many_type_params") local a: Callback = function(i) return true, 4 end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(2, result.errors[0].location.begin.line); IncorrectGenericParameterCount* igpc = get(result.errors[0]); @@ -412,10 +412,10 @@ TEST_CASE_FIXTURE(Fixture, "duplicate_type_param_name") type Oopsies = {a: T, b: T} )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto dgp = get(result.errors[0]); REQUIRE(dgp); - CHECK_EQ(dgp->parameterName, "T"); + CHECK_EQ(dgp->parameterName, XorStr("T")); } TEST_CASE_FIXTURE(Fixture, "typeof_expr") @@ -426,7 +426,7 @@ TEST_CASE_FIXTURE(Fixture, "typeof_expr") local m: typeof(id(77)) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireType("m"))); } @@ -440,7 +440,7 @@ TEST_CASE_FIXTURE(Fixture, "corecursive_types_error_on_tight_loop") local bb:B )"); - TypeId fType = requireType("aa"); + TypeId fType = requireType(XorStr("aa")); const AnyTypeVar* ftv = get(follow(fType)); REQUIRE(ftv != nullptr); REQUIRE(!result.errors.empty()); @@ -456,9 +456,9 @@ TEST_CASE_FIXTURE(Fixture, "type_alias_always_resolve_to_a_real_type") local aa:A )"); - TypeId fType = requireType("aa"); + TypeId fType = requireType(XorStr("aa")); REQUIRE(follow(fType) == typeChecker.numberType); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "interface_types_belong_to_interface_arena") @@ -471,7 +471,7 @@ TEST_CASE_FIXTURE(Fixture, "interface_types_belong_to_interface_arena") return {n=n} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); Module& mod = *getMainModule(); @@ -497,13 +497,13 @@ TEST_CASE_FIXTURE(Fixture, "generic_aliases_are_cloned_properly") CheckResult result = check(R"( export type Array = { [number]: T } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); Module& mod = *getMainModule(); const auto& typeBindings = mod.getModuleScope()->exportedTypeBindings; - auto it = typeBindings.find("Array"); + auto it = typeBindings.find(XorStr("Array")); REQUIRE(typeBindings.end() != it); const TypeFun& array = it->second; @@ -529,7 +529,7 @@ TEST_CASE_FIXTURE(Fixture, "cloned_interface_maintains_pointers_between_definiti return {a=a, b=b} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); Module& mod = *getMainModule(); @@ -557,7 +557,7 @@ TEST_CASE_FIXTURE(Fixture, "cloned_interface_maintains_pointers_between_definiti TEST_CASE_FIXTURE(BuiltinsFixture, "use_type_required_from_another_file") { - addGlobalBinding(frontend.typeChecker, "script", frontend.typeChecker.anyType, "@test"); + addGlobalBinding(frontend.typeChecker, XorStr("script", frontend.typeChecker.anyType, "@test")); fileResolver.source["Modules/Main"] = R"( --!strict @@ -576,14 +576,14 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "use_type_required_from_another_file") return {} )"; - CheckResult result = frontend.check("Modules/Main"); + CheckResult result = frontend.check(XorStr("Modules/Main")); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "cannot_use_nonexported_type") { - addGlobalBinding(frontend.typeChecker, "script", frontend.typeChecker.anyType, "@test"); + addGlobalBinding(frontend.typeChecker, XorStr("script", frontend.typeChecker.anyType, "@test")); fileResolver.source["Modules/Main"] = R"( --!strict @@ -602,14 +602,14 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "cannot_use_nonexported_type") return {} )"; - CheckResult result = frontend.check("Modules/Main"); + CheckResult result = frontend.check(XorStr("Modules/Main")); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(BuiltinsFixture, "builtin_types_are_not_exported") { - addGlobalBinding(frontend.typeChecker, "script", frontend.typeChecker.anyType, "@test"); + addGlobalBinding(frontend.typeChecker, XorStr("script", frontend.typeChecker.anyType, "@test")); fileResolver.source["Modules/Main"] = R"( --!strict @@ -626,9 +626,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "builtin_types_are_not_exported") return {} )"; - CheckResult result = frontend.check("Modules/Main"); + CheckResult result = frontend.check(XorStr("Modules/Main")); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } namespace @@ -638,8 +638,8 @@ struct AssertionCatcher AssertionCatcher() { tripped = 0; - oldhook = Luau::assertHandler(); - Luau::assertHandler() = [](const char* expr, const char* file, int line, const char* function) -> int { + oldhook = lluz::assertHandler(); + lluz::assertHandler() = [](const char* expr, const char* file, int line, const char* function) -> int { ++tripped; return 0; }; @@ -647,38 +647,38 @@ struct AssertionCatcher ~AssertionCatcher() { - Luau::assertHandler() = oldhook; + lluz::assertHandler() = oldhook; } static int tripped; - Luau::AssertHandler oldhook; + lluz::AssertHandler oldhook; }; int AssertionCatcher::tripped; } // namespace -TEST_CASE_FIXTURE(Fixture, "luau_ice_triggers_an_ice") +TEST_CASE_FIXTURE(Fixture, "lluz_ice_triggers_an_ice") { ScopedFastFlag sffs[] = { - {"DebugLuauMagicTypes", true}, - {"LuauUseInternalCompilerErrorException", false}, + {"DebuglluzMagicTypes", true}, + {"lluzUseInternalCompilerErrorException", false}, }; AssertionCatcher ac; CHECK_THROWS_AS(check(R"( - local a: _luau_ice = 55 + local a: _lluz_ice = 55 )"), std::runtime_error); - LUAU_ASSERT(1 == AssertionCatcher::tripped); + lluz_ASSERT(1 == AssertionCatcher::tripped); } -TEST_CASE_FIXTURE(Fixture, "luau_ice_triggers_an_ice_handler") +TEST_CASE_FIXTURE(Fixture, "lluz_ice_triggers_an_ice_handler") { ScopedFastFlag sffs[] = { - {"DebugLuauMagicTypes", true}, - {"LuauUseInternalCompilerErrorException", false}, + {"DebuglluzMagicTypes", true}, + {"lluzUseInternalCompilerErrorException", false}, }; bool caught = false; @@ -688,35 +688,35 @@ TEST_CASE_FIXTURE(Fixture, "luau_ice_triggers_an_ice_handler") }; CHECK_THROWS_AS(check(R"( - local a: _luau_ice = 55 + local a: _lluz_ice = 55 )"), std::runtime_error); CHECK_EQ(true, caught); } -TEST_CASE_FIXTURE(Fixture, "luau_ice_triggers_an_ice_exception_with_flag") +TEST_CASE_FIXTURE(Fixture, "lluz_ice_triggers_an_ice_exception_with_flag") { ScopedFastFlag sffs[] = { - {"DebugLuauMagicTypes", true}, - {"LuauUseInternalCompilerErrorException", true}, + {"DebuglluzMagicTypes", true}, + {"lluzUseInternalCompilerErrorException", true}, }; AssertionCatcher ac; CHECK_THROWS_AS(check(R"( - local a: _luau_ice = 55 + local a: _lluz_ice = 55 )"), InternalCompilerError); - LUAU_ASSERT(1 == AssertionCatcher::tripped); + lluz_ASSERT(1 == AssertionCatcher::tripped); } -TEST_CASE_FIXTURE(Fixture, "luau_ice_triggers_an_ice_exception_with_flag_handler") +TEST_CASE_FIXTURE(Fixture, "lluz_ice_triggers_an_ice_exception_with_flag_handler") { ScopedFastFlag sffs[] = { - {"DebugLuauMagicTypes", true}, - {"LuauUseInternalCompilerErrorException", true}, + {"DebuglluzMagicTypes", true}, + {"lluzUseInternalCompilerErrorException", true}, }; bool caught = false; @@ -726,44 +726,44 @@ TEST_CASE_FIXTURE(Fixture, "luau_ice_triggers_an_ice_exception_with_flag_handler }; CHECK_THROWS_AS(check(R"( - local a: _luau_ice = 55 + local a: _lluz_ice = 55 )"), InternalCompilerError); CHECK_EQ(true, caught); } -TEST_CASE_FIXTURE(Fixture, "luau_ice_is_not_special_without_the_flag") +TEST_CASE_FIXTURE(Fixture, "lluz_ice_is_not_special_without_the_flag") { - ScopedFastFlag sffs{"DebugLuauMagicTypes", false}; + ScopedFastFlag sffs{"DebuglluzMagicTypes", false}; // We only care that this does not throw check(R"( - local a: _luau_ice = 55 + local a: _lluz_ice = 55 )"); } -TEST_CASE_FIXTURE(BuiltinsFixture, "luau_print_is_magic_if_the_flag_is_set") +TEST_CASE_FIXTURE(BuiltinsFixture, "lluz_print_is_magic_if_the_flag_is_set") { - // Luau::resetPrintLine(); - ScopedFastFlag sffs{"DebugLuauMagicTypes", true}; + // lluz::resetPrintLine(); + ScopedFastFlag sffs{"DebuglluzMagicTypes", true}; CheckResult result = check(R"( - local a: _luau_print + local a: _lluz_print )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } -TEST_CASE_FIXTURE(Fixture, "luau_print_is_not_special_without_the_flag") +TEST_CASE_FIXTURE(Fixture, "lluz_print_is_not_special_without_the_flag") { - ScopedFastFlag sffs{"DebugLuauMagicTypes", false}; + ScopedFastFlag sffs{"DebuglluzMagicTypes", false}; CheckResult result = check(R"( - local a: _luau_print + local a: _lluz_print )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "instantiate_type_fun_should_not_trip_rbxassert") @@ -773,7 +773,7 @@ TEST_CASE_FIXTURE(Fixture, "instantiate_type_fun_should_not_trip_rbxassert") local foo: Foo )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } #if 0 @@ -788,7 +788,7 @@ TEST_CASE_FIXTURE(Fixture, "pulling_a_type_from_value_dont_falsely_create_occurs end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } #endif @@ -798,7 +798,7 @@ TEST_CASE_FIXTURE(Fixture, "occurs_check_on_cyclic_union_typevar") type T = T | T )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); OccursCheckFailed* ocf = get(result.errors[0]); REQUIRE(ocf); @@ -810,7 +810,7 @@ TEST_CASE_FIXTURE(Fixture, "occurs_check_on_cyclic_intersection_typevar") type T = T & T )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); OccursCheckFailed* ocf = get(result.errors[0]); REQUIRE(ocf); @@ -823,7 +823,7 @@ TEST_CASE_FIXTURE(Fixture, "instantiation_clone_has_to_follow") export type t0 = ({})&({_:{[any]:number},}) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_SUITE_END(); diff --git a/tests/TypeInfer.anyerror.test.cpp b/tests/TypeInfer.anyerror.test.cpp index f4766104..afe59bb0 100644 --- a/tests/TypeInfer.anyerror.test.cpp +++ b/tests/TypeInfer.anyerror.test.cpp @@ -1,21 +1,19 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/AstQuery.h" -#include "Luau/BuiltinDefinitions.h" -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" -#include "Luau/VisitTypeVar.h" +#include "lluz/AstQuery.h" +#include "lluz/BuiltinDefinitions.h" +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" +#include "lluz/VisitTypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(LuauSpecialTypesAsterisked) - -TEST_SUITE_BEGIN("TypeInferAnyError"); +TEST_SUITE_BEGIN(XorStr("TypeInferAnyError")); TEST_CASE_FIXTURE(Fixture, "for_in_loop_iterator_returns_any") { @@ -30,7 +28,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_iterator_returns_any") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(typeChecker.anyType, requireType("a")); } @@ -48,7 +46,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_iterator_returns_any2") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("a"))); } @@ -64,7 +62,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_iterator_is_any") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("a"))); } @@ -80,7 +78,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_iterator_is_any2") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("a"))); } @@ -94,12 +92,9 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_iterator_is_error") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(requireType("a"))); - else - CHECK_EQ("", toString(requireType("a"))); + CHECK_EQ("*unknown*", toString(requireType("a"))); } TEST_CASE_FIXTURE(Fixture, "for_in_loop_iterator_is_error2") @@ -113,12 +108,9 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_iterator_is_error2") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(requireType("a"))); - else - CHECK_EQ("", toString(requireType("a"))); + CHECK_EQ("*unknown*", toString(requireType("a"))); } TEST_CASE_FIXTURE(Fixture, "length_of_error_type_does_not_produce_an_error") @@ -127,7 +119,7 @@ TEST_CASE_FIXTURE(Fixture, "length_of_error_type_does_not_produce_an_error") local l = #this_is_not_defined )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "indexing_error_type_does_not_produce_an_error") @@ -136,7 +128,7 @@ TEST_CASE_FIXTURE(Fixture, "indexing_error_type_does_not_produce_an_error") local originalReward = unknown.Parent.Reward:GetChildren()[1] )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "dot_on_error_type_does_not_produce_an_error") @@ -146,7 +138,7 @@ TEST_CASE_FIXTURE(Fixture, "dot_on_error_type_does_not_produce_an_error") foo.x = foo.y )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "any_type_propagates") @@ -156,7 +148,7 @@ TEST_CASE_FIXTURE(Fixture, "any_type_propagates") local bar = foo:method("argument") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("bar"))); } @@ -168,7 +160,7 @@ TEST_CASE_FIXTURE(Fixture, "can_subscript_any") local bar = foo[5] )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("bar"))); } @@ -181,7 +173,7 @@ TEST_CASE_FIXTURE(Fixture, "can_get_length_of_any") local bar = #foo )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(PrimitiveTypeVar::Number, getPrimitiveType(requireType("bar"))); } @@ -197,7 +189,7 @@ TEST_CASE_FIXTURE(Fixture, "assign_prop_to_table_by_calling_any_yields_any") return T )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); TableTypeVar* ttv = getMutable(requireType("T")); REQUIRE(ttv); @@ -214,9 +206,9 @@ TEST_CASE_FIXTURE(Fixture, "quantify_any_does_not_bind_to_itself") A:C() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId aType = requireType("A"); + TypeId aType = requireType(XorStr("A")); CHECK_EQ(aType, typeChecker.anyType); } @@ -226,17 +218,14 @@ TEST_CASE_FIXTURE(Fixture, "calling_error_type_yields_error") local a = unknown.Parent.Reward.GetChildren() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); UnknownSymbol* err = get(result.errors[0]); REQUIRE(err != nullptr); CHECK_EQ("unknown", err->name); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(requireType("a"))); - else - CHECK_EQ("", toString(requireType("a"))); + CHECK_EQ("*unknown*", toString(requireType("a"))); } TEST_CASE_FIXTURE(Fixture, "chain_calling_error_type_yields_error") @@ -245,10 +234,7 @@ TEST_CASE_FIXTURE(Fixture, "chain_calling_error_type_yields_error") local a = Utility.Create "Foo" {} )"); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(requireType("a"))); - else - CHECK_EQ("", toString(requireType("a"))); + CHECK_EQ("*unknown*", toString(requireType("a"))); } TEST_CASE_FIXTURE(BuiltinsFixture, "replace_every_free_type_when_unifying_a_complex_function_with_any") @@ -261,7 +247,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "replace_every_free_type_when_unifying_a_comp end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("b"))); } @@ -284,7 +270,7 @@ function x:y(z: number) end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "CheckMethodsOfError") @@ -296,7 +282,7 @@ function x:y(z: number) end )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "metatable_of_any_can_be_a_table") @@ -316,7 +302,7 @@ function T:construct(index) end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "type_error_addition") @@ -327,7 +313,7 @@ local foo = makesandwich() local bar = foo.nutrition + 100 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); // We should definitely get this error CHECK_EQ("Unknown global 'makesandwich'", toString(result.errors[0])); @@ -343,7 +329,7 @@ TEST_CASE_FIXTURE(Fixture, "prop_access_on_any_with_other_options") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_SUITE_END(); diff --git a/tests/TypeInfer.builtins.test.cpp b/tests/TypeInfer.builtins.test.cpp index 0c878023..c014b7a8 100644 --- a/tests/TypeInfer.builtins.test.cpp +++ b/tests/TypeInfer.builtins.test.cpp @@ -1,17 +1,16 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/TypeInfer.h" -#include "Luau/BuiltinDefinitions.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/TypeInfer.h" +#include "lluz/BuiltinDefinitions.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(LuauLowerBoundsCalculation); -LUAU_FASTFLAG(LuauSpecialTypesAsterisked); +lluz_FASTFLAG(LluLowerBoundsCalculation); -TEST_SUITE_BEGIN("BuiltinTests"); +TEST_SUITE_BEGIN(XorStr("BuiltinTests")); TEST_CASE_FIXTURE(BuiltinsFixture, "math_things_are_defined") { @@ -48,7 +47,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "math_things_are_defined") local a31 = math.random )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "next_iterator_should_infer_types_and_type_check") @@ -61,7 +60,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "next_iterator_should_infer_types_and_type_ch local c: string, d: number = next(t) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(BuiltinsFixture, "pairs_iterator_should_infer_types_and_type_check") @@ -73,7 +72,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "pairs_iterator_should_infer_types_and_type_c local it: (Map, string | nil) -> (string, number), t: Map, i: nil = pairs(map) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "ipairs_iterator_should_infer_types_and_type_check") @@ -85,7 +84,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "ipairs_iterator_should_infer_types_and_type_ local it: (Map, number) -> (number, string), t: Map, i: number = ipairs(array) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "table_dot_remove_optionally_returns_generic") @@ -95,8 +94,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_dot_remove_optionally_returns_generic" local n = table.remove(t, 7) )"); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("n")), "number?"); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ(toString(requireType(XorStr("n")), "number?")); } TEST_CASE_FIXTURE(BuiltinsFixture, "table_concat_returns_string") @@ -105,7 +104,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_concat_returns_string") local r = table.concat({1,2,3,4}, ",", 2); )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.stringType, *requireType("r")); } @@ -116,7 +115,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "sort") table.sort(t) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "sort_with_predicate") @@ -128,7 +127,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "sort_with_predicate") table.sort(t, p) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "sort_with_bad_predicate") @@ -140,7 +139,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "sort_with_bad_predicate") table.sort(t, p) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_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' @@ -152,10 +151,10 @@ caused by: TEST_CASE_FIXTURE(Fixture, "strings_have_methods") { CheckResult result = check(R"LUA( - local s = ("RoactHostChangeEvent(%s)"):format("hello") + local s = ("RoactHostChangeEvent(%s)"):format(XorStr("hello")) )LUA"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.stringType, *requireType("s")); } @@ -165,7 +164,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "math_max_variatic") local n = math.max(1,2,3,4,5,6,7,8,9,0) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.numberType, *requireType("n")); } @@ -184,7 +183,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "builtin_tables_sealed") CheckResult result = check(R"LUA( local b = bit32 )LUA"); - TypeId bit32 = requireType("b"); + TypeId bit32 = requireType(XorStr("b")); REQUIRE(bit32 != nullptr); const TableTypeVar* bit32t = get(bit32); REQUIRE(bit32t != nullptr); @@ -345,7 +344,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "lua_51_exported_globals_all_exist") )"); dumpErrors(result); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "setmetatable_unpacks_arg_types_correctly") @@ -353,7 +352,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "setmetatable_unpacks_arg_types_correctly") CheckResult result = check(R"( setmetatable({}, setmetatable({}, {})) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_correctly_infers_type_of_array_2_args_overload") @@ -364,7 +363,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_correctly_infers_type_of_array_ local s = t[1] )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(typeChecker.stringType, requireType("s")); } @@ -376,7 +375,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_correctly_infers_type_of_array_ local s = t[1] )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("string", toString(requireType("s"))); } @@ -386,7 +385,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_pack") local t = table.pack(1, "foo", true) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("{| [number]: boolean | number | string, n: number |}", toString(requireType("t"))); } @@ -395,13 +394,13 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_pack_variadic") CheckResult result = check(R"( --!strict function f(): (string, ...number) - return "str", 2, 3, 4 + return XorStr("str"), 2, 3, 4 end local t = table.pack(f()) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("{| [number]: number | string, n: number |}", toString(requireType("t"))); } @@ -411,14 +410,14 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_pack_reduce") local t = table.pack(1, 2, true) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("{| [number]: boolean | number, n: number |}", toString(requireType("t"))); result = check(R"( local t = table.pack("a", "b", "c") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("{| [number]: string, n: number |}", toString(requireType("t"))); } @@ -428,13 +427,13 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "gcinfo") local n = gcinfo() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.numberType, *requireType("n")); } TEST_CASE_FIXTURE(BuiltinsFixture, "getfenv") { - LUAU_REQUIRE_NO_ERRORS(check("getfenv(1)")); + lluz_REQUIRE_NO_ERRORS(check("getfenv(1)")); } TEST_CASE_FIXTURE(BuiltinsFixture, "os_time_takes_optional_date_table") @@ -445,7 +444,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "os_time_takes_optional_date_table") local n3 = os.time({ year = 2020, month = 4, day = 20, hour = 0, min = 0, sec = 0, isdst = true }) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.numberType, *requireType("n1")); CHECK_EQ(*typeChecker.numberType, *requireType("n2")); CHECK_EQ(*typeChecker.numberType, *requireType("n3")); @@ -457,7 +456,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "thread_is_a_type") local co = coroutine.create(function() end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.threadType, *requireType("co")); } @@ -476,7 +475,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "coroutine_resume_anything_goes") local answer = coroutine.resume(co, 3) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "coroutine_wrap_anything_goes") @@ -495,7 +494,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "coroutine_wrap_anything_goes") local answer = f(3) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "setmetatable_should_not_mutate_persisted_types") @@ -506,9 +505,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "setmetatable_should_not_mutate_persisted_typ setmetatable(string, {}) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); - auto stringType = requireType("string"); + auto stringType = requireType(XorStr("string")); auto ttv = get(stringType); REQUIRE(ttv); } @@ -518,7 +517,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "string_format_arg_types_inference") CheckResult result = check(R"( --!strict function f(a, b, c) - return string.format("%f %d %s", a, b, c) + return string.format(XorStr("%f %d %s"), a, b, c) end )"); @@ -530,13 +529,13 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "string_format_arg_count_mismatch") { CheckResult result = check(R"( --!strict - string.format("%f %d %s") - string.format("%s", "hi", 42) - string.format("%s", "hi", 42, ...) - string.format("%s", "hi", ...) + string.format(XorStr("%f %d %s")) + string.format(XorStr("%s"), "hi", 42) + string.format(XorStr("%s"), "hi", 42, ...) + string.format(XorStr("%s"), "hi", ...) )"); - LUAU_REQUIRE_ERROR_COUNT(3, result); + lluz_REQUIRE_ERROR_COUNT(3, result); CHECK_EQ(result.errors[0].location.begin.line, 2); CHECK_EQ(result.errors[1].location.begin.line, 3); CHECK_EQ(result.errors[2].location.begin.line, 4); @@ -546,10 +545,10 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "string_format_correctly_ordered_types") { CheckResult result = check(R"( --!strict - string.format("%s", 123) + string.format(XorStr("%s"), 123) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); CHECK_EQ(tm->wantedType, typeChecker.stringType); @@ -566,7 +565,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "xpcall") ) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("boolean", toString(requireType("a"))); CHECK_EQ("number", toString(requireType("b"))); CHECK_EQ("boolean", toString(requireType("c"))); @@ -578,7 +577,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "see_thru_select") local a:number, b:boolean = select(2,"hi", 10, true) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "see_thru_select_count") @@ -588,7 +587,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "see_thru_select_count") )"); dumpErrors(result); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "select_with_decimal_argument_is_rounded_down") @@ -597,7 +596,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "select_with_decimal_argument_is_rounded_down local a: number, b: boolean = select(2.9, "foo", 1, true) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } // Could be flaky if the fix has regressed. @@ -613,7 +612,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "bad_select_should_not_crash") end )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ("Argument count mismatch. Function expects at least 1 argument, but none are specified", toString(result.errors[0])); CHECK_EQ("Argument count mismatch. Function expects 1 argument, but none are specified", toString(result.errors[1])); } @@ -624,7 +623,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "select_way_out_of_range") select(5432598430953240958) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); REQUIRE(get(result.errors[0])); CHECK_EQ("bad argument #1 to select (index out of range)", toString(result.errors[0])); } @@ -635,7 +634,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "select_slightly_out_of_range") select(3, "a", 1) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); REQUIRE(get(result.errors[0])); CHECK_EQ("bad argument #1 to select (index out of range)", toString(result.errors[0])); } @@ -651,7 +650,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "select_with_variadic_typepack_tail") local foo, bar, baz, quux = select(1, f("foo", true)) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("foo"))); CHECK_EQ("any", toString(requireType("bar"))); @@ -670,7 +669,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "select_with_variadic_typepack_tail_and_strin local foo, bar, baz, quux = select(1, "foo", f("bar", true)) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("foo"))); CHECK_EQ("any", toString(requireType("bar"))); @@ -680,9 +679,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "select_with_variadic_typepack_tail_and_strin TEST_CASE_FIXTURE(Fixture, "string_format_as_method") { - CheckResult result = check("local _ = ('%s'):format(5)"); + CheckResult result = check(XorStr("local _ = ('%s'):format(5)")); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -693,10 +692,10 @@ TEST_CASE_FIXTURE(Fixture, "string_format_as_method") TEST_CASE_FIXTURE(Fixture, "string_format_use_correct_argument") { CheckResult result = check(R"( - local _ = ("%s"):format("%d", "hello") + local _ = ("%s"):format(XorStr("%d"), "hello") )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Argument count mismatch. Function expects 1 argument, but 2 are specified", toString(result.errors[0])); } @@ -704,10 +703,10 @@ TEST_CASE_FIXTURE(Fixture, "string_format_use_correct_argument") TEST_CASE_FIXTURE(Fixture, "string_format_use_correct_argument2") { CheckResult result = check(R"( - local _ = ("%s %d").format("%d %s", "A type error", 2) + local _ = ("%s %d").format(XorStr("%d %s"), "A type error", 2) )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ("Type 'string' could not be converted into 'number'", toString(result.errors[0])); CHECK_EQ("Type 'number' could not be converted into 'string'", toString(result.errors[1])); @@ -727,7 +726,7 @@ debug.traceback(co, "msg") debug.traceback(co, "msg", 1) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "debug_info_is_crazy") @@ -741,7 +740,7 @@ debug.info(co, 1, "n") debug.info(f, "n") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "aliased_string_format") @@ -751,7 +750,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "aliased_string_format") local s = fmt("%d", "oops") )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'string' could not be converted into 'number'", toString(result.errors[0])); } @@ -771,7 +770,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "string_lib_self_noself") local a0 = string.packsize("ff") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "gmatch_definition") @@ -784,7 +783,7 @@ for c in ("hey"):gmatch("(.)") do end )_"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "select_on_variadic") @@ -797,7 +796,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "select_on_variadic") local a, b, c = select(f()) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("a"))); CHECK_EQ("any", toString(requireType("b"))); CHECK_EQ("any", toString(requireType("c"))); @@ -807,14 +806,14 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "string_format_report_all_type_errors_at_corr { CheckResult result = check(R"( ("%s%d%s"):format(1, "hello", true) - string.format("%s%d%s", 1, "hello", true) + string.format(XorStr("%s%d%s"), 1, "hello", true) )"); TypeId stringType = typeChecker.stringType; TypeId numberType = typeChecker.numberType; TypeId booleanType = typeChecker.booleanType; - LUAU_REQUIRE_ERROR_COUNT(6, result); + lluz_REQUIRE_ERROR_COUNT(6, result); CHECK_EQ(Location(Position{1, 26}, Position{1, 27}), result.errors[0].location); CHECK_EQ(TypeErrorData(TypeMismatch{stringType, numberType}), result.errors[0].data); @@ -842,7 +841,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "tonumber_returns_optional_number_type") local b: number = tonumber('asdf') )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'number?' could not be converted into 'number'", toString(result.errors[0])); } @@ -853,7 +852,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "tonumber_returns_optional_number_type2") local b: number = tonumber('asdf') or 1 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "dont_add_definitions_to_persistent_types") @@ -863,15 +862,15 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "dont_add_definitions_to_persistent_types") local function g(x) return math.sin(x) end f = g )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId fType = requireType("f"); + TypeId fType = requireType(XorStr("f")); const FunctionTypeVar* ftv = get(fType); REQUIRE(fType); REQUIRE(fType->persistent); REQUIRE(!ftv->definition); - TypeId gType = requireType("g"); + TypeId gType = requireType(XorStr("g")); const FunctionTypeVar* gtv = get(gType); REQUIRE(gType); REQUIRE(!gType->persistent); @@ -886,8 +885,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "assert_removes_falsy_types") end )"); - LUAU_REQUIRE_NO_ERRORS(result); - if (FFlag::LuauLowerBoundsCalculation) + lluz_REQUIRE_NO_ERRORS(result); + if (FFlag::LluLowerBoundsCalculation) CHECK_EQ("((boolean | number)?) -> number | true", toString(requireType("f"))); else CHECK_EQ("((boolean | number)?) -> boolean | number", toString(requireType("f"))); @@ -901,7 +900,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "assert_removes_falsy_types2") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("((boolean | number)?) -> number | true", toString(requireType("f"))); } @@ -913,7 +912,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "assert_removes_falsy_types_even_from_type_pa end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("(...number?) -> (number, ...number?)", toString(requireType("f"))); } @@ -925,8 +924,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "assert_returns_false_and_string_iff_it_knows end )"); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ("(nil) -> (never, ...never)", toString(requireType("f"))); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ("(nil) -> nil", toString(requireType("f"))); } TEST_CASE_FIXTURE(BuiltinsFixture, "table_freeze_is_generic") @@ -947,30 +946,27 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_freeze_is_generic") local d = tf1.b )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Key 'b' not found in table '{| a: number |}'", toString(result.errors[0])); CHECK_EQ("number", toString(requireType("a"))); CHECK_EQ("string", toString(requireType("b"))); CHECK_EQ("boolean", toString(requireType("c"))); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(requireType("d"))); - else - CHECK_EQ("", toString(requireType("d"))); + CHECK_EQ("*unknown*", toString(requireType("d"))); } TEST_CASE_FIXTURE(BuiltinsFixture, "set_metatable_needs_arguments") { - ScopedFastFlag sff{"LuauSetMetaTableArgsCheck", true}; + ScopedFastFlag sff{"lluzSetMetaTableArgsCheck", true}; CheckResult result = check(R"( local a = {b=setmetatable} a.b() a:b() a:b({}) )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); - CHECK_EQ(toString(result.errors[0]), "Argument count mismatch. Function expects 2 arguments, but none are specified"); - CHECK_EQ(toString(result.errors[1]), "Argument count mismatch. Function expects 2 arguments, but only 1 is specified"); + lluz_REQUIRE_ERROR_COUNT(2, result); + CHECK_EQ(result.errors[0], (TypeError{Location{{2, 0}, {2, 5}}, CountMismatch{2, 0}})); + CHECK_EQ(result.errors[1], (TypeError{Location{{3, 0}, {3, 5}}, CountMismatch{2, 1}})); } TEST_CASE_FIXTURE(Fixture, "typeof_unresolved_function") @@ -978,13 +974,13 @@ TEST_CASE_FIXTURE(Fixture, "typeof_unresolved_function") CheckResult result = check(R"( local function f(a: typeof(f)) end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Unknown global 'f'", toString(result.errors[0])); } TEST_CASE_FIXTURE(BuiltinsFixture, "no_persistent_typelevel_change") { - TypeId mathTy = requireType(typeChecker.globalScope, "math"); + TypeId mathTy = requireType(typeChecker.globalScope, XorStr("math")); REQUIRE(mathTy); TableTypeVar* ttv = getMutable(mathTy); REQUIRE(ttv); @@ -992,9 +988,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "no_persistent_typelevel_change") REQUIRE(ftv); auto original = ftv->level; - CheckResult result = check("local a = math.frexp"); + CheckResult result = check(XorStr("local a = math.frexp")); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK(ftv->level.level == original.level); CHECK(ftv->level.subLevel == original.subLevel); } @@ -1009,252 +1005,7 @@ local function f(x: string) end )"); - LUAU_REQUIRE_NO_ERRORS(result); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "gmatch_capture_types") -{ - ScopedFastFlag sffs{"LuauDeduceGmatchReturnTypes", true}; - CheckResult result = check(R"END( - local a, b, c = string.gmatch("This is a string", "(.()(%a+))")() - )END"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK_EQ(toString(requireType("a")), "string"); - CHECK_EQ(toString(requireType("b")), "number"); - CHECK_EQ(toString(requireType("c")), "string"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "gmatch_capture_types2") -{ - ScopedFastFlag sffs{"LuauDeduceGmatchReturnTypes", true}; - CheckResult result = check(R"END( - local a, b, c = ("This is a string"):gmatch("(.()(%a+))")() - )END"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK_EQ(toString(requireType("a")), "string"); - CHECK_EQ(toString(requireType("b")), "number"); - CHECK_EQ(toString(requireType("c")), "string"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "gmatch_capture_types_default_capture") -{ - ScopedFastFlag sffs{"LuauDeduceGmatchReturnTypes", true}; - CheckResult result = check(R"END( - local a, b, c, d = string.gmatch("T(his)() is a string", ".")() - )END"); - - LUAU_REQUIRE_ERROR_COUNT(1, result); - - CountMismatch* acm = get(result.errors[0]); - REQUIRE(acm); - CHECK_EQ(acm->context, CountMismatch::Result); - CHECK_EQ(acm->expected, 1); - CHECK_EQ(acm->actual, 4); - - CHECK_EQ(toString(requireType("a")), "string"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "gmatch_capture_types_balanced_escaped_parens") -{ - ScopedFastFlag sffs{"LuauDeduceGmatchReturnTypes", true}; - CheckResult result = check(R"END( - local a, b, c, d = string.gmatch("T(his) is a string", "((.)%b()())")() - )END"); - - LUAU_REQUIRE_ERROR_COUNT(1, result); - - CountMismatch* acm = get(result.errors[0]); - REQUIRE(acm); - CHECK_EQ(acm->context, CountMismatch::Result); - CHECK_EQ(acm->expected, 3); - CHECK_EQ(acm->actual, 4); - - CHECK_EQ(toString(requireType("a")), "string"); - CHECK_EQ(toString(requireType("b")), "string"); - CHECK_EQ(toString(requireType("c")), "number"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "gmatch_capture_types_parens_in_sets_are_ignored") -{ - ScopedFastFlag sffs{"LuauDeduceGmatchReturnTypes", true}; - CheckResult result = check(R"END( - local a, b, c = string.gmatch("T(his)() is a string", "(T[()])()")() - )END"); - - LUAU_REQUIRE_ERROR_COUNT(1, result); - - CountMismatch* acm = get(result.errors[0]); - REQUIRE(acm); - CHECK_EQ(acm->context, CountMismatch::Result); - CHECK_EQ(acm->expected, 2); - CHECK_EQ(acm->actual, 3); - - CHECK_EQ(toString(requireType("a")), "string"); - CHECK_EQ(toString(requireType("b")), "number"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "gmatch_capture_types_set_containing_lbracket") -{ - ScopedFastFlag sffs{"LuauDeduceGmatchReturnTypes", true}; - CheckResult result = check(R"END( - local a, b = string.gmatch("[[[", "()([[])")() - )END"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK_EQ(toString(requireType("a")), "number"); - CHECK_EQ(toString(requireType("b")), "string"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "gmatch_capture_types_leading_end_bracket_is_part_of_set") -{ - CheckResult result = check(R"END( - -- An immediate right-bracket following a left-bracket is included within the set; - -- thus, '[]]'' is the set containing ']', and '[]' is an invalid set missing an enclosing - -- right-bracket. We detect an invalid set in this case and fall back to to default gmatch - -- typing. - local foo = string.gmatch("T[hi%]s]]]() is a string", "([]s)") - )END"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK_EQ(toString(requireType("foo")), "() -> (...string)"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "gmatch_capture_types_invalid_pattern_fallback_to_builtin") -{ - CheckResult result = check(R"END( - local foo = string.gmatch("T(his)() is a string", ")") - )END"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK_EQ(toString(requireType("foo")), "() -> (...string)"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "gmatch_capture_types_invalid_pattern_fallback_to_builtin2") -{ - CheckResult result = check(R"END( - local foo = string.gmatch("T(his)() is a string", "[") - )END"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK_EQ(toString(requireType("foo")), "() -> (...string)"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "match_capture_types") -{ - ScopedFastFlag sffs{"LuauDeduceFindMatchReturnTypes", true}; - CheckResult result = check(R"END( - local a, b, c = string.match("This is a string", "(.()(%a+))") - )END"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK_EQ(toString(requireType("a")), "string"); - CHECK_EQ(toString(requireType("b")), "number"); - CHECK_EQ(toString(requireType("c")), "string"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "match_capture_types2") -{ - ScopedFastFlag sffs{"LuauDeduceFindMatchReturnTypes", true}; - CheckResult result = check(R"END( - local a, b, c = string.match("This is a string", "(.()(%a+))", "this should be a number") - )END"); - - LUAU_REQUIRE_ERROR_COUNT(1, result); - - TypeMismatch* tm = get(result.errors[0]); - REQUIRE(tm); - CHECK_EQ(toString(tm->wantedType), "number?"); - CHECK_EQ(toString(tm->givenType), "string"); - - CHECK_EQ(toString(requireType("a")), "string"); - CHECK_EQ(toString(requireType("b")), "number"); - CHECK_EQ(toString(requireType("c")), "string"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "find_capture_types") -{ - ScopedFastFlag sffs{"LuauDeduceFindMatchReturnTypes", true}; - CheckResult result = check(R"END( - local d, e, a, b, c = string.find("This is a string", "(.()(%a+))") - )END"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK_EQ(toString(requireType("a")), "string"); - CHECK_EQ(toString(requireType("b")), "number"); - CHECK_EQ(toString(requireType("c")), "string"); - CHECK_EQ(toString(requireType("d")), "number?"); - CHECK_EQ(toString(requireType("e")), "number?"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "find_capture_types2") -{ - ScopedFastFlag sffs{"LuauDeduceFindMatchReturnTypes", true}; - CheckResult result = check(R"END( - local d, e, a, b, c = string.find("This is a string", "(.()(%a+))", "this should be a number") - )END"); - - LUAU_REQUIRE_ERROR_COUNT(1, result); - - TypeMismatch* tm = get(result.errors[0]); - REQUIRE(tm); - CHECK_EQ(toString(tm->wantedType), "number?"); - CHECK_EQ(toString(tm->givenType), "string"); - - CHECK_EQ(toString(requireType("a")), "string"); - CHECK_EQ(toString(requireType("b")), "number"); - CHECK_EQ(toString(requireType("c")), "string"); - CHECK_EQ(toString(requireType("d")), "number?"); - CHECK_EQ(toString(requireType("e")), "number?"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "find_capture_types3") -{ - ScopedFastFlag sffs{"LuauDeduceFindMatchReturnTypes", true}; - CheckResult result = check(R"END( - local d, e, a, b, c = string.find("This is a string", "(.()(%a+))", 1, "this should be a bool") - )END"); - - LUAU_REQUIRE_ERROR_COUNT(1, result); - - TypeMismatch* tm = get(result.errors[0]); - REQUIRE(tm); - CHECK_EQ(toString(tm->wantedType), "boolean?"); - CHECK_EQ(toString(tm->givenType), "string"); - - CHECK_EQ(toString(requireType("a")), "string"); - CHECK_EQ(toString(requireType("b")), "number"); - CHECK_EQ(toString(requireType("c")), "string"); - CHECK_EQ(toString(requireType("d")), "number?"); - CHECK_EQ(toString(requireType("e")), "number?"); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "find_capture_types3") -{ - ScopedFastFlag sffs{"LuauDeduceFindMatchReturnTypes", true}; - CheckResult result = check(R"END( - local d, e, a, b = string.find("This is a string", "(.()(%a+))", 1, true) - )END"); - - LUAU_REQUIRE_ERROR_COUNT(1, result); - - CountMismatch* acm = get(result.errors[0]); - REQUIRE(acm); - CHECK_EQ(acm->context, CountMismatch::Result); - CHECK_EQ(acm->expected, 2); - CHECK_EQ(acm->actual, 4); - - CHECK_EQ(toString(requireType("d")), "number?"); - CHECK_EQ(toString(requireType("e")), "number?"); + lluz_REQUIRE_NO_ERRORS(result); } TEST_SUITE_END(); diff --git a/tests/TypeInfer.classes.test.cpp b/tests/TypeInfer.classes.test.cpp index 6f4191e3..ace2010f 100644 --- a/tests/TypeInfer.classes.test.cpp +++ b/tests/TypeInfer.classes.test.cpp @@ -1,13 +1,13 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/BuiltinDefinitions.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/BuiltinDefinitions.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; using std::nullopt; struct ClassFixture : BuiltinsFixture @@ -32,7 +32,7 @@ struct ClassFixture : BuiltinsFixture {"New", {makeFunction(arena, nullopt, {}, {baseClassInstanceType})}}, }; typeChecker.globalScope->exportedTypeBindings["BaseClass"] = TypeFun{{}, baseClassInstanceType}; - addGlobalBinding(typeChecker, "BaseClass", baseClassType, "@test"); + addGlobalBinding(typeChecker, XorStr("BaseClass", baseClassType, "@test")); TypeId childClassInstanceType = arena.addType(ClassTypeVar{"ChildClass", {}, baseClassInstanceType, nullopt, {}, {}, "Test"}); @@ -45,7 +45,7 @@ struct ClassFixture : BuiltinsFixture {"New", {makeFunction(arena, nullopt, {}, {childClassInstanceType})}}, }; typeChecker.globalScope->exportedTypeBindings["ChildClass"] = TypeFun{{}, childClassInstanceType}; - addGlobalBinding(typeChecker, "ChildClass", childClassType, "@test"); + addGlobalBinding(typeChecker, XorStr("ChildClass", childClassType, "@test")); TypeId grandChildInstanceType = arena.addType(ClassTypeVar{"GrandChild", {}, childClassInstanceType, nullopt, {}, {}, "Test"}); @@ -58,7 +58,7 @@ struct ClassFixture : BuiltinsFixture {"New", {makeFunction(arena, nullopt, {}, {grandChildInstanceType})}}, }; typeChecker.globalScope->exportedTypeBindings["GrandChild"] = TypeFun{{}, grandChildInstanceType}; - addGlobalBinding(typeChecker, "GrandChild", childClassType, "@test"); + addGlobalBinding(typeChecker, XorStr("GrandChild", childClassType, "@test")); TypeId anotherChildInstanceType = arena.addType(ClassTypeVar{"AnotherChild", {}, baseClassInstanceType, nullopt, {}, {}, "Test"}); @@ -71,7 +71,7 @@ struct ClassFixture : BuiltinsFixture {"New", {makeFunction(arena, nullopt, {}, {anotherChildInstanceType})}}, }; typeChecker.globalScope->exportedTypeBindings["AnotherChild"] = TypeFun{{}, anotherChildInstanceType}; - addGlobalBinding(typeChecker, "AnotherChild", childClassType, "@test"); + addGlobalBinding(typeChecker, XorStr("AnotherChild", childClassType, "@test")); TypeId vector2MetaType = arena.addType(TableTypeVar{}); @@ -89,7 +89,7 @@ struct ClassFixture : BuiltinsFixture {"__add", {makeFunction(arena, nullopt, {vector2InstanceType, vector2InstanceType}, {vector2InstanceType})}}, }; typeChecker.globalScope->exportedTypeBindings["Vector2"] = TypeFun{{}, vector2InstanceType}; - addGlobalBinding(typeChecker, "Vector2", vector2Type, "@test"); + addGlobalBinding(typeChecker, XorStr("Vector2", vector2Type, "@test")); for (const auto& [name, tf] : typeChecker.globalScope->exportedTypeBindings) persist(tf.type); @@ -98,7 +98,7 @@ struct ClassFixture : BuiltinsFixture } }; -TEST_SUITE_BEGIN("TypeInferClasses"); +TEST_SUITE_BEGIN(XorStr("TypeInferClasses")); TEST_CASE_FIXTURE(ClassFixture, "call_method_of_a_class") { @@ -106,7 +106,7 @@ TEST_CASE_FIXTURE(ClassFixture, "call_method_of_a_class") local m = BaseClass.StaticMethod() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); REQUIRE_EQ("number", toString(requireType("m"))); } @@ -117,7 +117,7 @@ TEST_CASE_FIXTURE(ClassFixture, "call_method_of_a_child_class") local m = ChildClass.StaticMethod() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); REQUIRE_EQ("number", toString(requireType("m"))); } @@ -129,7 +129,7 @@ TEST_CASE_FIXTURE(ClassFixture, "call_instance_method") local result = i:Method() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("string", toString(requireType("result"))); } @@ -141,7 +141,7 @@ TEST_CASE_FIXTURE(ClassFixture, "call_base_method") i:BaseMethod(41) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(ClassFixture, "cannot_call_unknown_method_of_a_class") @@ -150,7 +150,7 @@ TEST_CASE_FIXTURE(ClassFixture, "cannot_call_unknown_method_of_a_class") local m = BaseClass.Nope() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(ClassFixture, "cannot_call_method_of_child_on_base_instance") @@ -160,7 +160,7 @@ TEST_CASE_FIXTURE(ClassFixture, "cannot_call_method_of_child_on_base_instance") i:Method() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(ClassFixture, "we_can_infer_that_a_parameter_must_be_a_particular_class") @@ -194,7 +194,7 @@ TEST_CASE_FIXTURE(ClassFixture, "we_can_report_when_someone_is_trying_to_use_a_t makeClone(oopsies) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm != nullptr); @@ -209,7 +209,7 @@ TEST_CASE_FIXTURE(ClassFixture, "assign_to_prop_of_class") v.X = 55 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(ClassFixture, "can_read_prop_of_base_class") @@ -219,7 +219,7 @@ TEST_CASE_FIXTURE(ClassFixture, "can_read_prop_of_base_class") local x = 1 + c.BaseField )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(ClassFixture, "can_assign_to_prop_of_base_class") @@ -229,7 +229,7 @@ TEST_CASE_FIXTURE(ClassFixture, "can_assign_to_prop_of_base_class") c.BaseField = 444 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(ClassFixture, "can_read_prop_of_base_class_using_string") @@ -239,7 +239,7 @@ TEST_CASE_FIXTURE(ClassFixture, "can_read_prop_of_base_class_using_string") local x = 1 + c["BaseField"] )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(ClassFixture, "can_assign_to_prop_of_base_class_using_string") @@ -249,7 +249,7 @@ TEST_CASE_FIXTURE(ClassFixture, "can_assign_to_prop_of_base_class_using_string") c["BaseField"] = 444 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(ClassFixture, "cannot_unify_class_instance_with_primitive") @@ -259,7 +259,7 @@ TEST_CASE_FIXTURE(ClassFixture, "cannot_unify_class_instance_with_primitive") v = 444 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(ClassFixture, "warn_when_prop_almost_matches") @@ -268,7 +268,7 @@ TEST_CASE_FIXTURE(ClassFixture, "warn_when_prop_almost_matches") Vector2.new(0, 0) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto err = get(result.errors[0]); REQUIRE(err != nullptr); @@ -285,7 +285,7 @@ TEST_CASE_FIXTURE(ClassFixture, "classes_can_have_overloaded_operators") local c = a + b )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("Vector2", toString(requireType("c"))); } @@ -298,7 +298,7 @@ TEST_CASE_FIXTURE(ClassFixture, "classes_without_overloaded_operators_cannot_be_ local c = a + b )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(ClassFixture, "function_arguments_are_covariant") @@ -309,7 +309,7 @@ TEST_CASE_FIXTURE(ClassFixture, "function_arguments_are_covariant") f(ChildClass.New()) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(ClassFixture, "higher_order_function_arguments_are_contravariant") @@ -322,7 +322,7 @@ TEST_CASE_FIXTURE(ClassFixture, "higher_order_function_arguments_are_contravaria apply(function (c: ChildClass) end) -- 5 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(ClassFixture, "higher_order_function_return_values_are_covariant") @@ -337,7 +337,7 @@ TEST_CASE_FIXTURE(ClassFixture, "higher_order_function_return_values_are_covaria end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(ClassFixture, "higher_order_function_return_type_is_not_contravariant") @@ -352,7 +352,7 @@ TEST_CASE_FIXTURE(ClassFixture, "higher_order_function_return_type_is_not_contra end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(ClassFixture, "table_properties_are_invariant") @@ -373,7 +373,7 @@ TEST_CASE_FIXTURE(ClassFixture, "table_properties_are_invariant") g(t2) -- line 13. Breaks soundness )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ(6, result.errors[0].location.begin.line); CHECK_EQ(13, result.errors[1].location.begin.line); } @@ -396,7 +396,7 @@ TEST_CASE_FIXTURE(ClassFixture, "table_indexers_are_invariant") g(t2) -- line 13. Breaks soundness )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ(6, result.errors[0].location.begin.line); CHECK_EQ(13, result.errors[1].location.begin.line); } @@ -414,7 +414,7 @@ TEST_CASE_FIXTURE(ClassFixture, "table_class_unification_reports_sane_errors_for foo(a) )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); REQUIRE_EQ("Key 'w' not found in class 'Vector2'", toString(result.errors[0])); REQUIRE_EQ("Key 'x' not found in class 'Vector2'. Did you mean 'X'?", toString(result.errors[1])); } @@ -427,7 +427,7 @@ TEST_CASE_FIXTURE(ClassFixture, "class_unification_type_mismatch_is_correct_orde local foo2: BaseClass = 1 )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); REQUIRE_EQ("Type 'BaseClass' could not be converted into 'number'", toString(result.errors[0])); REQUIRE_EQ("Type 'number' could not be converted into 'BaseClass'", toString(result.errors[1])); @@ -442,7 +442,7 @@ local a = b.X + b.Z b.X = 2 -- real Vector2.X is also read-only )"); - LUAU_REQUIRE_ERROR_COUNT(4, result); + lluz_REQUIRE_ERROR_COUNT(4, result); CHECK_EQ("Value of type 'Vector2?' could be nil", toString(result.errors[0])); CHECK_EQ("Value of type 'Vector2?' could be nil", toString(result.errors[1])); CHECK_EQ("Key 'Z' not found in class 'Vector2'", toString(result.errors[2])); @@ -461,7 +461,7 @@ local b = foo b(a) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(R"(Type 'Vector2' could not be converted into '{- X: a, Y: string -}' caused by: Property 'Y' is not compatible. Type 'number' could not be converted into 'string')", @@ -476,7 +476,7 @@ type ChildClass = { x: number } local a: ChildClass = i )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'ChildClass' from 'Test' could not be converted into 'ChildClass' from 'MainModule'", toString(result.errors[0])); } diff --git a/tests/TypeInfer.definitions.test.cpp b/tests/TypeInfer.definitions.test.cpp index 4545b8db..bdf14c13 100644 --- a/tests/TypeInfer.definitions.test.cpp +++ b/tests/TypeInfer.definitions.test.cpp @@ -1,15 +1,15 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/BuiltinDefinitions.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/BuiltinDefinitions.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("DefinitionTests"); +TEST_SUITE_BEGIN(XorStr("DefinitionTests")); TEST_CASE_FIXTURE(Fixture, "definition_file_loading") { @@ -21,22 +21,22 @@ TEST_CASE_FIXTURE(Fixture, "definition_file_loading") declare function var(...: any): string )"); - TypeId globalFooTy = getGlobalBinding(frontend.typeChecker, "foo"); - CHECK_EQ(toString(globalFooTy), "number"); + TypeId globalFooTy = getGlobalBinding(frontend.typeChecker, XorStr("foo")); + CHECK_EQ(toString(globalFooTy), XorStr("number")); - std::optional globalAsdfTy = frontend.typeChecker.globalScope->lookupType("Asdf"); + std::optional globalAsdfTy = frontend.typeChecker.globalScope->lookupType(XorStr("Asdf")); REQUIRE(bool(globalAsdfTy)); - CHECK_EQ(toString(globalAsdfTy->type), "number | string"); + CHECK_EQ(toString(globalAsdfTy->type), XorStr("number | string")); - TypeId globalBarTy = getGlobalBinding(frontend.typeChecker, "bar"); - CHECK_EQ(toString(globalBarTy), "(number) -> string"); + TypeId globalBarTy = getGlobalBinding(frontend.typeChecker, XorStr("bar")); + CHECK_EQ(toString(globalBarTy), XorStr("(number) -> string")); - TypeId globalFoo2Ty = getGlobalBinding(frontend.typeChecker, "foo2"); - CHECK_EQ(toString(globalFoo2Ty), "number"); + TypeId globalFoo2Ty = getGlobalBinding(frontend.typeChecker, XorStr("foo2")); + CHECK_EQ(toString(globalFoo2Ty), XorStr("number")); - TypeId globalVarTy = getGlobalBinding(frontend.typeChecker, "var"); + TypeId globalVarTy = getGlobalBinding(frontend.typeChecker, XorStr("var")); - CHECK_EQ(toString(globalVarTy), "(...any) -> string"); + CHECK_EQ(toString(globalVarTy), XorStr("(...any) -> string")); CheckResult result = check(R"( local x: number = foo + 1 @@ -45,7 +45,7 @@ TEST_CASE_FIXTURE(Fixture, "definition_file_loading") z = y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "load_definition_file_errors_do_not_pollute_global_scope") @@ -54,21 +54,21 @@ TEST_CASE_FIXTURE(Fixture, "load_definition_file_errors_do_not_pollute_global_sc LoadDefinitionFileResult parseFailResult = loadDefinitionFile(typeChecker, typeChecker.globalScope, R"( declare foo )", - "@test"); + XorStr("@test")); freeze(typeChecker.globalTypes); REQUIRE(!parseFailResult.success); - std::optional fooTy = tryGetGlobalBinding(typeChecker, "foo"); + std::optional fooTy = tryGetGlobalBinding(typeChecker, XorStr("foo")); CHECK(!fooTy.has_value()); LoadDefinitionFileResult checkFailResult = loadDefinitionFile(typeChecker, typeChecker.globalScope, R"( local foo: string = 123 declare bar: typeof(foo) )", - "@test"); + XorStr("@test")); REQUIRE(!checkFailResult.success); - std::optional barTy = tryGetGlobalBinding(typeChecker, "bar"); + std::optional barTy = tryGetGlobalBinding(typeChecker, XorStr("bar")); CHECK(!barTy.has_value()); } @@ -101,13 +101,13 @@ TEST_CASE_FIXTURE(Fixture, "definition_file_classes") local inheritedMethod: number = x:inheritance() )"); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("prop")), "number"); - CHECK_EQ(toString(requireType("inheritedProp")), "number"); - CHECK_EQ(toString(requireType("method")), "number"); - CHECK_EQ(toString(requireType("method2")), "string"); - CHECK_EQ(toString(requireType("metamethod")), "Bar"); - CHECK_EQ(toString(requireType("inheritedMethod")), "number"); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ(toString(requireType(XorStr("prop")), "number")); + CHECK_EQ(toString(requireType(XorStr("inheritedProp")), "number")); + CHECK_EQ(toString(requireType(XorStr("method")), "number")); + CHECK_EQ(toString(requireType(XorStr("method2")), "string")); + CHECK_EQ(toString(requireType(XorStr("metamethod")), "Bar")); + CHECK_EQ(toString(requireType(XorStr("inheritedMethod")), "number")); } TEST_CASE_FIXTURE(Fixture, "class_definitions_cannot_overload_non_function") @@ -119,7 +119,7 @@ TEST_CASE_FIXTURE(Fixture, "class_definitions_cannot_overload_non_function") X: string end )", - "@test"); + XorStr("@test")); freeze(typeChecker.globalTypes); REQUIRE(!result.success); @@ -140,7 +140,7 @@ TEST_CASE_FIXTURE(Fixture, "class_definitions_cannot_extend_non_class") declare class Foo extends NotAClass end )", - "@test"); + XorStr("@test")); freeze(typeChecker.globalTypes); REQUIRE(!result.success); @@ -162,7 +162,7 @@ TEST_CASE_FIXTURE(Fixture, "no_cyclic_defined_classes") declare class Bar extends Foo end )", - "@test"); + XorStr("@test")); freeze(typeChecker.globalTypes); REQUIRE(!result.success); @@ -186,13 +186,13 @@ TEST_CASE_FIXTURE(Fixture, "declaring_generic_functions") local h = h )"); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("x")), "string"); - CHECK_EQ(toString(requireType("w")), "boolean"); - CHECK_EQ(toString(requireType("u")), "number"); - CHECK_EQ(toString(requireType("f")), "(a, b) -> string"); - CHECK_EQ(toString(requireType("g")), "(a...) -> (b...)"); - CHECK_EQ(toString(requireType("h")), "(a, b) -> (b, a)"); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ(toString(requireType(XorStr("x")), "string")); + CHECK_EQ(toString(requireType(XorStr("w")), "boolean")); + CHECK_EQ(toString(requireType(XorStr("u")), "number")); + CHECK_EQ(toString(requireType(XorStr("f")), "(a, b) -> string")); + CHECK_EQ(toString(requireType(XorStr("g")), "(a...) -> (b...)")); + CHECK_EQ(toString(requireType(XorStr("h")), "(a, b) -> (b, a)")); } TEST_CASE_FIXTURE(Fixture, "class_definition_function_prop") @@ -208,8 +208,8 @@ TEST_CASE_FIXTURE(Fixture, "class_definition_function_prop") local prop = x.X )"); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("prop")), "(number) -> string"); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ(toString(requireType(XorStr("prop")), "(number) -> string")); } TEST_CASE_FIXTURE(Fixture, "definition_file_class_function_args") @@ -230,12 +230,12 @@ TEST_CASE_FIXTURE(Fixture, "definition_file_class_function_args") local prop = x.y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions opts; opts.functionTypeArguments = true; - CHECK_EQ(toString(requireType("methodRef1"), opts), "(self: Foo, x: number) -> number"); - CHECK_EQ(toString(requireType("methodRef2"), opts), "(self: Foo, x: number, y: string) -> number"); - CHECK_EQ(toString(requireType("prop"), opts), "(a: number, b: string) -> string"); + CHECK_EQ(toString(requireType(XorStr("methodRef1"), opts), "(self: Foo, x: number) -> number")); + CHECK_EQ(toString(requireType(XorStr("methodRef2"), opts), "(self: Foo, x: number, y: string) -> number")); + CHECK_EQ(toString(requireType(XorStr("prop"), opts), "(a: number, b: string) -> string")); } TEST_CASE_FIXTURE(Fixture, "definitions_documentation_symbols") @@ -254,32 +254,32 @@ TEST_CASE_FIXTURE(Fixture, "definitions_documentation_symbols") } )"); - std::optional xBinding = typeChecker.globalScope->linearSearchForBinding("x"); + std::optional xBinding = typeChecker.globalScope->linearSearchForBinding(XorStr("x")); REQUIRE(bool(xBinding)); // note: loadDefinition uses the @test package name. - CHECK_EQ(xBinding->documentationSymbol, "@test/global/x"); + CHECK_EQ(xBinding->documentationSymbol, XorStr("@test/global/x")); - std::optional fooTy = typeChecker.globalScope->lookupType("Foo"); + std::optional fooTy = typeChecker.globalScope->lookupType(XorStr("Foo")); REQUIRE(bool(fooTy)); - CHECK_EQ(fooTy->type->documentationSymbol, "@test/globaltype/Foo"); + CHECK_EQ(fooTy->type->documentationSymbol, XorStr("@test/globaltype/Foo")); - std::optional barTy = typeChecker.globalScope->lookupType("Bar"); + std::optional barTy = typeChecker.globalScope->lookupType(XorStr("Bar")); REQUIRE(bool(barTy)); - CHECK_EQ(barTy->type->documentationSymbol, "@test/globaltype/Bar"); + CHECK_EQ(barTy->type->documentationSymbol, XorStr("@test/globaltype/Bar")); ClassTypeVar* barClass = getMutable(barTy->type); REQUIRE(bool(barClass)); REQUIRE_EQ(barClass->props.count("prop"), 1); - CHECK_EQ(barClass->props["prop"].documentationSymbol, "@test/globaltype/Bar.prop"); + CHECK_EQ(barClass->props[XorStr("prop"].documentationSymbol, "@test/globaltype/Bar.prop")); - std::optional yBinding = typeChecker.globalScope->linearSearchForBinding("y"); + std::optional yBinding = typeChecker.globalScope->linearSearchForBinding(XorStr("y")); REQUIRE(bool(yBinding)); - CHECK_EQ(yBinding->documentationSymbol, "@test/global/y"); + CHECK_EQ(yBinding->documentationSymbol, XorStr("@test/global/y")); TableTypeVar* yTtv = getMutable(yBinding->typeId); REQUIRE(bool(yTtv)); REQUIRE_EQ(yTtv->props.count("x"), 1); - CHECK_EQ(yTtv->props["x"].documentationSymbol, "@test/global/y.x"); + CHECK_EQ(yTtv->props[XorStr("x"].documentationSymbol, "@test/global/y.x")); } TEST_CASE_FIXTURE(Fixture, "documentation_symbols_dont_attach_to_persistent_types") @@ -288,7 +288,7 @@ TEST_CASE_FIXTURE(Fixture, "documentation_symbols_dont_attach_to_persistent_type export type Evil = string )"); - std::optional ty = typeChecker.globalScope->lookupType("Evil"); + std::optional ty = typeChecker.globalScope->lookupType(XorStr("Evil")); REQUIRE(bool(ty)); CHECK_EQ(ty->type->documentationSymbol, std::nullopt); } @@ -306,7 +306,7 @@ declare GetCls: () -> (Cls) local s : Cls = GetCls() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_SUITE_END(); diff --git a/tests/TypeInfer.functions.test.cpp b/tests/TypeInfer.functions.test.cpp index 70773d95..1852c41c 100644 --- a/tests/TypeInfer.functions.test.cpp +++ b/tests/TypeInfer.functions.test.cpp @@ -1,27 +1,26 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/AstQuery.h" -#include "Luau/BuiltinDefinitions.h" -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" -#include "Luau/VisitTypeVar.h" +#include "lluz/AstQuery.h" +#include "lluz/BuiltinDefinitions.h" +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" +#include "lluz/VisitTypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(LuauLowerBoundsCalculation); -LUAU_FASTFLAG(LuauSpecialTypesAsterisked); +lluz_FASTFLAG(LluLowerBoundsCalculation); -TEST_SUITE_BEGIN("TypeInferFunctions"); +TEST_SUITE_BEGIN(XorStr("TypeInferFunctions")); TEST_CASE_FIXTURE(Fixture, "tc_function") { - CheckResult result = check("function five() return 5 end"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("function five() return 5 end")); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* fiveType = get(requireType("five")); REQUIRE(fiveType != nullptr); @@ -29,8 +28,8 @@ TEST_CASE_FIXTURE(Fixture, "tc_function") TEST_CASE_FIXTURE(Fixture, "check_function_bodies") { - CheckResult result = check("function myFunction() local a = 0 a = true end"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("function myFunction() local a = 0 a = true end")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(result.errors[0], (TypeError{Location{Position{0, 44}, Position{0, 48}}, TypeMismatch{ typeChecker.numberType, @@ -51,7 +50,7 @@ TEST_CASE_FIXTURE(Fixture, "cannot_hoist_interior_defns_into_signature") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK(result.errors[0] == TypeError{Location{{1, 28}, {1, 29}}, getMainSourceModule()->name, UnknownSymbol{ "T", @@ -61,8 +60,8 @@ TEST_CASE_FIXTURE(Fixture, "cannot_hoist_interior_defns_into_signature") TEST_CASE_FIXTURE(Fixture, "infer_return_type") { - CheckResult result = check("function take_five() return 5 end"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("function take_five() return 5 end")); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* takeFiveType = get(requireType("take_five")); REQUIRE(takeFiveType != nullptr); @@ -75,8 +74,8 @@ TEST_CASE_FIXTURE(Fixture, "infer_return_type") TEST_CASE_FIXTURE(Fixture, "infer_from_function_return_type") { - CheckResult result = check("function take_five() return 5 end local five = take_five()"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("function take_five() return 5 end local five = take_five()")); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.numberType, *follow(requireType("five"))); } @@ -91,7 +90,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_that_function_does_not_return_a_table") take_five().prop = 888 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(result.errors[0], (TypeError{Location{Position{5, 8}, Position{5, 24}}, NotATable{typeChecker.numberType}})); } @@ -104,7 +103,7 @@ TEST_CASE_FIXTURE(Fixture, "vararg_functions_should_allow_calls_of_any_types_and f("foo", 2) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "vararg_function_is_quantified") @@ -136,7 +135,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "vararg_function_is_quantified") TypeId k = ttv->props["f"].type; REQUIRE(k); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "list_only_alternative_overloads_that_match_argument_count") @@ -146,7 +145,7 @@ TEST_CASE_FIXTURE(Fixture, "list_only_alternative_overloads_that_match_argument_ multiply("") )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -165,7 +164,7 @@ TEST_CASE_FIXTURE(Fixture, "list_all_overloads_if_no_overload_takes_given_argume multiply() )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); GenericError* ge = get(result.errors[0]); REQUIRE(ge); @@ -183,7 +182,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_give_other_overloads_message_if_only_one_argume multiply(1, "") )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -201,7 +200,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_return_type_from_selected_overload") local b = T.method(5) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireType("a"))); CHECK_EQ("string", toString(requireType("b"))); } @@ -217,7 +216,7 @@ TEST_CASE_FIXTURE(Fixture, "too_many_arguments") )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto err = result.errors[0]; auto acm = get(err); @@ -239,7 +238,7 @@ TEST_CASE_FIXTURE(Fixture, "recursive_function") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "lambda_form_of_local_function_cannot_be_recursive") @@ -248,7 +247,7 @@ TEST_CASE_FIXTURE(Fixture, "lambda_form_of_local_function_cannot_be_recursive") local f = function() return f() end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "recursive_local_function") @@ -263,7 +262,7 @@ TEST_CASE_FIXTURE(Fixture, "recursive_local_function") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } // FIXME: This and the above case get handled very differently. It's pretty dumb. @@ -281,7 +280,7 @@ TEST_CASE_FIXTURE(Fixture, "another_recursive_local_function") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "cyclic_function_type_in_rets") @@ -292,14 +291,14 @@ TEST_CASE_FIXTURE(Fixture, "cyclic_function_type_in_rets") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("t1 where t1 = () -> t1", toString(requireType("f"))); } TEST_CASE_FIXTURE(Fixture, "cyclic_function_type_in_args") { ScopedFastFlag sff[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( @@ -308,7 +307,7 @@ TEST_CASE_FIXTURE(Fixture, "cyclic_function_type_in_args") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("t1 where t1 = (t1) -> (a...)", toString(requireType("f"))); } @@ -329,7 +328,7 @@ TEST_CASE_FIXTURE(Fixture, "another_higher_order_function") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "another_other_higher_order_function") @@ -340,7 +339,7 @@ TEST_CASE_FIXTURE(Fixture, "another_other_higher_order_function") d:foo() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "local_function") @@ -360,7 +359,7 @@ TEST_CASE_FIXTURE(Fixture, "local_function") local h = g() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); TypeId h = follow(requireType("h")); @@ -380,8 +379,8 @@ TEST_CASE_FIXTURE(Fixture, "func_expr_doesnt_leak_free") local p = function(x) return x end )"); - LUAU_REQUIRE_NO_ERRORS(result); - const Luau::FunctionTypeVar* fn = get(requireType("p")); + lluz_REQUIRE_NO_ERRORS(result); + const lluz::FunctionTypeVar* fn = get(requireType("p")); REQUIRE(fn); auto ret = first(fn->retTypes); REQUIRE(ret); @@ -396,7 +395,7 @@ TEST_CASE_FIXTURE(Fixture, "first_argument_can_be_optional") local m = T.new() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); } @@ -408,7 +407,7 @@ TEST_CASE_FIXTURE(Fixture, "it_is_ok_not_to_supply_enough_retvals") local a = get_two() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); } @@ -422,7 +421,7 @@ TEST_CASE_FIXTURE(Fixture, "duplicate_functions2") end )"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + lluz_REQUIRE_ERROR_COUNT(0, result); } TEST_CASE_FIXTURE(Fixture, "duplicate_functions_allowed_in_nonstrict") @@ -438,7 +437,7 @@ TEST_CASE_FIXTURE(Fixture, "duplicate_functions_allowed_in_nonstrict") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "duplicate_functions_with_different_signatures_not_allowed_in_nonstrict") @@ -456,7 +455,7 @@ TEST_CASE_FIXTURE(Fixture, "duplicate_functions_with_different_signatures_not_al foo() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -478,7 +477,7 @@ TEST_CASE_FIXTURE(Fixture, "complicated_return_types_require_an_explicit_annotat end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* functionType = get(requireType("most_of_the_natural_numbers")); @@ -495,7 +494,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_higher_order_function") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* ftv = get(requireType("apply")); REQUIRE(ftv != nullptr); @@ -532,7 +531,7 @@ TEST_CASE_FIXTURE(Fixture, "higher_order_function_2") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* ftv = get(requireType("bottomupmerge")); REQUIRE(ftv != nullptr); @@ -562,7 +561,7 @@ TEST_CASE_FIXTURE(Fixture, "higher_order_function_3") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* ftv = get(requireType("swapTwice")); REQUIRE(ftv != nullptr); @@ -612,7 +611,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "higher_order_function_4") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); /* @@ -657,7 +656,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "mutual_recursion") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); } @@ -672,12 +671,17 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "toposort_doesnt_break_mutual_recursion") print(x) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); } TEST_CASE_FIXTURE(Fixture, "check_function_before_lambda_that_uses_it") { + ScopedFastFlag sff[]{ + {"lluzReturnTypeInferenceInNonstrict", true}, + {"lluzLowerBoundsCalculation", true}, + }; + CheckResult result = check(R"( --!nonstrict @@ -686,11 +690,11 @@ TEST_CASE_FIXTURE(Fixture, "check_function_before_lambda_that_uses_it") end return function() - return f():andThen() + return f() end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "it_is_ok_to_oversaturate_a_higher_order_function_argument") @@ -701,7 +705,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "it_is_ok_to_oversaturate_a_higher_order_func xpcall(foo, onerror) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "another_indirect_function_case_where_it_is_ok_to_provide_too_many_arguments") @@ -714,7 +718,7 @@ TEST_CASE_FIXTURE(Fixture, "another_indirect_function_case_where_it_is_ok_to_pro mycb = f )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "report_exiting_without_return_nonstrict") @@ -747,7 +751,7 @@ TEST_CASE_FIXTURE(Fixture, "report_exiting_without_return_nonstrict") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); FunctionExitsWithoutReturning* err = get(result.errors[0]); CHECK(err); } @@ -782,7 +786,7 @@ TEST_CASE_FIXTURE(Fixture, "report_exiting_without_return_strict") end )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); FunctionExitsWithoutReturning* annotatedErr = get(result.errors[0]); CHECK(annotatedErr); @@ -798,7 +802,7 @@ TEST_CASE_FIXTURE(Fixture, "calling_function_with_incorrect_argument_type_yields foo("Test", 123) )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ(result.errors[0], (TypeError{Location{Position{3, 12}, Position{3, 18}}, TypeMismatch{ typeChecker.numberType, @@ -813,19 +817,23 @@ TEST_CASE_FIXTURE(Fixture, "calling_function_with_incorrect_argument_type_yields TEST_CASE_FIXTURE(BuiltinsFixture, "calling_function_with_anytypepack_doesnt_leak_free_types") { + ScopedFastFlag sff[]{ + {"lluzReturnTypeInferenceInNonstrict", true}, + {"lluzLowerBoundsCalculation", true}, + }; + CheckResult result = check(R"( --!nonstrict - function Test(a) + function Test(a): ...any return 1, "" end - local tab = {} table.insert(tab, Test(1)); )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions opts; opts.exhaustive = true; @@ -846,7 +854,7 @@ TEST_CASE_FIXTURE(Fixture, "too_many_return_values") local a, b = f() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CountMismatch* acm = get(result.errors[0]); REQUIRE(acm); @@ -867,7 +875,7 @@ TEST_CASE_FIXTURE(Fixture, "ignored_return_values") local a = f() )"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + lluz_REQUIRE_ERROR_COUNT(0, result); } TEST_CASE_FIXTURE(Fixture, "function_does_not_return_enough_values") @@ -880,7 +888,7 @@ TEST_CASE_FIXTURE(Fixture, "function_does_not_return_enough_values") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CountMismatch* acm = get(result.errors[0]); REQUIRE(acm); @@ -902,25 +910,19 @@ TEST_CASE_FIXTURE(Fixture, "function_cast_error_uses_correct_language") local c: (string, number)->number = foo -- no error )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); auto tm1 = get(result.errors[0]); REQUIRE(tm1); CHECK_EQ("(string) -> number", toString(tm1->wantedType)); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("(string, *error-type*) -> number", toString(tm1->givenType)); - else - CHECK_EQ("(string, ) -> number", toString(tm1->givenType)); + CHECK_EQ("(string, *unknown*) -> number", toString(tm1->givenType)); auto tm2 = get(result.errors[1]); REQUIRE(tm2); CHECK_EQ("(number, number) -> (number, number)", toString(tm2->wantedType)); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("(string, *error-type*) -> number", toString(tm2->givenType)); - else - CHECK_EQ("(string, ) -> number", toString(tm2->givenType)); + CHECK_EQ("(string, *unknown*) -> number", toString(tm2->givenType)); } TEST_CASE_FIXTURE(Fixture, "no_lossy_function_type") @@ -935,7 +937,7 @@ TEST_CASE_FIXTURE(Fixture, "no_lossy_function_type") -- | Column 14 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); TypeId type = requireTypeAtPosition(Position(6, 14)); CHECK_EQ("(tbl, number, number) -> number", toString(type)); auto ftv = get(type); @@ -951,7 +953,7 @@ TEST_CASE_FIXTURE(Fixture, "record_matching_overload") abc(1) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // AstExprCall is the node that has the overload stored on it. // findTypeAtPosition will look at the AstExprLocal, but this is not what @@ -965,7 +967,7 @@ TEST_CASE_FIXTURE(Fixture, "record_matching_overload") ModulePtr module = getMainModule(); auto it = module->astOverloadResolvedTypes.find(parentExpr); REQUIRE(it); - CHECK_EQ(toString(*it), "(number) -> number"); + CHECK_EQ(toString(*it), XorStr("(number) -> number")); } TEST_CASE_FIXTURE(Fixture, "return_type_by_overload") @@ -978,7 +980,7 @@ TEST_CASE_FIXTURE(Fixture, "return_type_by_overload") local z = abc(true,true,true) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ("string", toString(requireType("x"))); CHECK_EQ("number", toString(requireType("y"))); // Should this be string|number? @@ -994,7 +996,7 @@ local function f(a: (Table) -> number) return a({x = 1, y = 2}) end f(function(a) return a.x + a.y end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // An optional function is accepted, but since we already provide a function, nil can be ignored result = check(R"( @@ -1003,7 +1005,7 @@ local function f(a: ((Table) -> number)?) if a then return a({x = 1, y = 2}) els f(function(a) return a.x + a.y end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // Make sure self calls match correct index result = check(R"( @@ -1014,7 +1016,7 @@ function x:f(a: (Table) -> number) return a(self.b) end x:f(function(a) return a.x + a.y end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // Mix inferred and explicit argument types result = check(R"( @@ -1022,7 +1024,7 @@ function f(a: (a: number, b: number, c: boolean) -> number) return a(1, 2, true) f(function(a: number, b, c) return c and a + b or b - a end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // Anonymous function has a variadic pack result = check(R"( @@ -1031,7 +1033,7 @@ local function f(a: (Table) -> number) return a({x = 1, y = 2}) end f(function(...) return select(1, ...).z end) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ("Key 'z' not found in table 'Table'", toString(result.errors[0])); // Can't accept more arguments than provided @@ -1040,7 +1042,7 @@ function f(a: (a: number, b: number) -> number) return a(1, 2) end f(function(a, b, c, ...) return a + b end) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ(R"(Type '(number, number, a) -> number' could not be converted into '(number, number) -> number' caused by: @@ -1053,7 +1055,7 @@ function f(a: (...number) -> number) return a(1, 2) end f(function(a, b) return a + b end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // Infer from variadic packs into variadic packs result = check(R"( @@ -1062,7 +1064,7 @@ function f(a: (...Table) -> number) return a({x = 1, y = 2}, {x = 3, y = 4}) end f(function(a, ...) local b = ... return b.z end) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ("Key 'z' not found in table 'Table'", toString(result.errors[0])); // Return type inference @@ -1072,10 +1074,10 @@ function f(a: (number) -> Table) return a(4) end f(function(x) return x * 2 end) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'number' could not be converted into 'Table'", toString(result.errors[0])); - if (!FFlag::LuauLowerBoundsCalculation) + if (!FFlag::LluLowerBoundsCalculation) { // Return type doesn't inference 'nil' result = check(R"( @@ -1083,7 +1085,7 @@ f(function(x) return x * 2 end) f(function(x) print(x) end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } } @@ -1096,7 +1098,7 @@ local function f(a: (Table) -> number) return a({x = 1, y = 2}) end f(function(a) return a.x + a.y end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // An optional function is accepted, but since we already provide a function, nil can be ignored result = check(R"( @@ -1105,7 +1107,7 @@ local function f(a: ((Table) -> number)?) if a then return a({x = 1, y = 2}) els f(function(a) return a.x + a.y end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // Make sure self calls match correct index result = check(R"( @@ -1116,7 +1118,7 @@ function x:f(a: (Table) -> number) return a(self.b) end x:f(function(a) return a.x + a.y end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // Mix inferred and explicit argument types result = check(R"( @@ -1124,7 +1126,7 @@ function f(a: (a: number, b: number, c: boolean) -> number) return a(1, 2, true) f(function(a: number, b, c) return c and a + b or b - a end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // Anonymous function has a variadic pack result = check(R"( @@ -1133,7 +1135,7 @@ local function f(a: (Table) -> number) return a({x = 1, y = 2}) end f(function(...) return select(1, ...).z end) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ("Key 'z' not found in table 'Table'", toString(result.errors[0])); // Can't accept more arguments than provided @@ -1142,7 +1144,7 @@ function f(a: (a: number, b: number) -> number) return a(1, 2) end f(function(a, b, c, ...) return a + b end) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ(R"(Type '(number, number, a) -> number' could not be converted into '(number, number) -> number' caused by: @@ -1155,7 +1157,7 @@ function f(a: (...number) -> number) return a(1, 2) end f(function(a, b) return a + b end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // Infer from variadic packs into variadic packs result = check(R"( @@ -1164,7 +1166,7 @@ function f(a: (...Table) -> number) return a({x = 1, y = 2}, {x = 3, y = 4}) end f(function(a, ...) local b = ... return b.z end) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ("Key 'z' not found in table 'Table'", toString(result.errors[0])); // Return type inference @@ -1174,10 +1176,10 @@ function f(a: (number) -> Table) return a(4) end f(function(x) return x * 2 end) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'number' could not be converted into 'Table'", toString(result.errors[0])); - if (!FFlag::LuauLowerBoundsCalculation) + if (!FFlag::LluLowerBoundsCalculation) { // Return type doesn't inference 'nil' result = check(R"( @@ -1185,7 +1187,7 @@ f(function(x) return x * 2 end) f(function(x) print(x) end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } } @@ -1199,7 +1201,7 @@ type TableWithFunc = { x: number, y: number, f: (number, number) -> number } local a: TableWithFunc = { x = 3, y = 4, f = function(a, b) return a + b end } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "infer_return_value_type") @@ -1222,7 +1224,7 @@ local function i(): ...{string|number} end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "error_detailed_function_mismatch_arg_count") @@ -1235,7 +1237,7 @@ local a: A local b: B = a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type '(number, number) -> string' could not be converted into '(number) -> string' caused by: Argument count mismatch. Function expects 2 arguments, but only 1 is specified)"); @@ -1251,7 +1253,7 @@ local a: A local b: B = a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type '(number, number) -> string' could not be converted into '(number, string) -> string' caused by: Argument #2 type is not compatible. Type 'string' could not be converted into 'number')"); @@ -1267,7 +1269,7 @@ local a: A local b: B = a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type '(number, number) -> number' could not be converted into '(number, number) -> (number, boolean)' caused by: Function only returns 1 value. 2 are required here)"); @@ -1283,7 +1285,7 @@ local a: A local b: B = a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type '(number, number) -> string' could not be converted into '(number, number) -> number' caused by: Return type is not compatible. Type 'string' could not be converted into 'number')"); @@ -1299,7 +1301,7 @@ local a: A local b: B = a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type '(number, number) -> (number, string)' could not be converted into '(number, number) -> (number, boolean)' caused by: @@ -1325,7 +1327,7 @@ function MagicMock.is(value) end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "function_decl_non_self_sealed_overwrite") @@ -1336,7 +1338,7 @@ function string.len(): number end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // if 'string' library property was replaced with an internal module type, it will be freed and the next check will crash frontend.clear(); @@ -1345,7 +1347,7 @@ end print(string.len('hello')) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "function_decl_non_self_sealed_overwrite_2") @@ -1364,15 +1366,15 @@ t.f = function(x) end )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); - CHECK_EQ(toString(result.errors[0]), R"(Type 'string' could not be converted into 'number')"); - CHECK_EQ(toString(result.errors[1]), R"(Type 'string' could not be converted into 'number')"); + lluz_REQUIRE_ERROR_COUNT(2, result); + CHECK_EQ(toString(result.errors[0]), RXorStr("(Type 'string' could not be converted into 'number')")); + CHECK_EQ(toString(result.errors[1]), RXorStr("(Type 'string' could not be converted into 'number')")); } TEST_CASE_FIXTURE(Fixture, "inconsistent_return_types") { const ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( @@ -1385,7 +1387,7 @@ TEST_CASE_FIXTURE(Fixture, "inconsistent_return_types") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("(boolean, number) -> number?", toString(requireType("foo"))); // TODO: Test multiple returns @@ -1396,7 +1398,7 @@ TEST_CASE_FIXTURE(Fixture, "inconsistent_return_types") TEST_CASE_FIXTURE(Fixture, "inconsistent_higher_order_function") { const ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( @@ -1406,7 +1408,7 @@ TEST_CASE_FIXTURE(Fixture, "inconsistent_higher_order_function") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("((number | string) -> (a...)) -> ()", toString(requireType("foo"))); } @@ -1424,7 +1426,7 @@ TEST_CASE_FIXTURE(Fixture, "inconsistent_higher_order_function") TEST_CASE_FIXTURE(Fixture, "inferred_higher_order_functions_are_quantified_at_the_right_time") { ScopedFastFlag sff[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( @@ -1439,7 +1441,7 @@ TEST_CASE_FIXTURE(Fixture, "inferred_higher_order_functions_are_quantified_at_th end )"); - // LUAU_REQUIRE_NO_ERRORS is particularly unhelpful when this test is broken. + // lluz_REQUIRE_NO_ERRORS is particularly unhelpful when this test is broken. // You get a TypeMismatch error where both types stringify the same. CHECK(result.errors.empty()); @@ -1465,7 +1467,7 @@ TEST_CASE_FIXTURE(Fixture, "inferred_higher_order_functions_are_quantified_at_th end )"); - // LUAU_REQUIRE_NO_ERRORS is particularly unhelpful when this test is broken. + // lluz_REQUIRE_NO_ERRORS is particularly unhelpful when this test is broken. // You get a TypeMismatch error where both types stringify the same. CHECK(result.errors.empty()); @@ -1486,7 +1488,7 @@ TEST_CASE_FIXTURE(Fixture, "inferred_higher_order_functions_are_quantified_at_th end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "function_decl_non_self_unsealed_overwrite") @@ -1504,13 +1506,13 @@ t.f = function(x) end )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ(toString(result.errors[0]), R"(Type '(string) -> string' could not be converted into '((number) -> number)?' caused by: None of the union options are compatible. For example: Type '(string) -> string' could not be converted into '(number) -> number' caused by: Argument #1 type is not compatible. Type 'number' could not be converted into 'string')"); - CHECK_EQ(toString(result.errors[1]), R"(Type 'string' could not be converted into 'number')"); + CHECK_EQ(toString(result.errors[1]), RXorStr("(Type 'string' could not be converted into 'number')")); } TEST_CASE_FIXTURE(Fixture, "strict_mode_ok_with_missing_arguments") @@ -1520,7 +1522,7 @@ TEST_CASE_FIXTURE(Fixture, "strict_mode_ok_with_missing_arguments") f() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "function_statement_sealed_table_assignment_through_indexer") @@ -1532,22 +1534,11 @@ function t.a() return 1 end -- OK function t:b() return 2 end -- not OK )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - if (FFlag::LuauSpecialTypesAsterisked) - { - CHECK_EQ(R"(Type '(*error-type*) -> number' could not be converted into '() -> number' + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(R"(Type '(*unknown*) -> number' could not be converted into '() -> number' caused by: Argument count mismatch. Function expects 1 argument, but none are specified)", - toString(result.errors[0])); - } - else - { - CHECK_EQ(R"(Type '() -> number' could not be converted into '() -> number' -caused by: - Argument count mismatch. Function expects 1 argument, but none are specified)", - toString(result.errors[0])); - } - + toString(result.errors[0])); } TEST_CASE_FIXTURE(Fixture, "too_few_arguments_variadic") @@ -1559,7 +1550,7 @@ TEST_CASE_FIXTURE(Fixture, "too_few_arguments_variadic") test(1) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto err = result.errors[0]; auto acm = get(err); @@ -1584,7 +1575,7 @@ end wrapper(test) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto err = result.errors[0]; auto acm = get(err); @@ -1609,7 +1600,7 @@ end pcall(wrapper, test) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto err = result.errors[0]; auto acm = get(err); @@ -1629,16 +1620,31 @@ TEST_CASE_FIXTURE(Fixture, "occurs_check_failure_in_function_return_type") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK(nullptr != get(result.errors[0])); } +TEST_CASE_FIXTURE(Fixture, "weird_fail_to_unify_type_pack") +{ + ScopedFastFlag sff[]{ + {"lluzReturnTypeInferenceInNonstrict", true}, + {"lluzLowerBoundsCalculation", true}, + }; + + CheckResult result = check(R"( + local function f() return end + local g = function() return f() end + )"); + + lluz_REQUIRE_NO_ERRORS(result); +} + TEST_CASE_FIXTURE(Fixture, "quantify_constrained_types") { ScopedFastFlag sff[]{ - {"LuauLowerBoundsCalculation", true}, - {"LuauQuantifyConstrained", true}, + {"lluzLowerBoundsCalculation", true}, + {"lluzQuantifyConstrained", true}, }; CheckResult result = check(R"( @@ -1654,7 +1660,7 @@ TEST_CASE_FIXTURE(Fixture, "quantify_constrained_types") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("((boolean | number | string) -> (a...)) -> ()", toString(requireType("foo"))); } @@ -1662,8 +1668,8 @@ TEST_CASE_FIXTURE(Fixture, "quantify_constrained_types") TEST_CASE_FIXTURE(Fixture, "call_o_with_another_argument_after_foo_was_quantified") { ScopedFastFlag sff[]{ - {"LuauLowerBoundsCalculation", true}, - {"LuauQuantifyConstrained", true}, + {"lluzLowerBoundsCalculation", true}, + {"lluzQuantifyConstrained", true}, }; CheckResult result = check(R"( @@ -1682,56 +1688,8 @@ TEST_CASE_FIXTURE(Fixture, "call_o_with_another_argument_after_foo_was_quantifie end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // TODO: check the normalized type of f } -TEST_CASE_FIXTURE(Fixture, "free_is_not_bound_to_unknown") -{ - CheckResult result = check(R"( - local function foo(f: (unknown) -> (), x) - f(x) - end - )"); - - CHECK_EQ("((unknown) -> (), a) -> ()", toString(requireType("foo"))); -} - -TEST_CASE_FIXTURE(Fixture, "dont_infer_parameter_types_for_functions_from_their_call_site") -{ - CheckResult result = check(R"( - local t = {} - - function t.f(x) - return x - end - - t.__index = t - - function g(s) - local q = s.p and s.p.q or nil - return q and t.f(q) or nil - end - - local f = t.f - )"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK_EQ("(a) -> a", toString(requireType("f"))); -} - -TEST_CASE_FIXTURE(Fixture, "dont_mutate_the_underlying_head_of_typepack_when_calling_with_self") -{ - CheckResult result = check(R"( - local t = {} - function t:m(x) end - function f(): never return 5 :: never end - t:m(f()) - t:m(f()) - )"); - - LUAU_REQUIRE_NO_ERRORS(result); -} - TEST_SUITE_END(); diff --git a/tests/TypeInfer.generics.test.cpp b/tests/TypeInfer.generics.test.cpp index 7a1af164..bbde3fd6 100644 --- a/tests/TypeInfer.generics.test.cpp +++ b/tests/TypeInfer.generics.test.cpp @@ -1,7 +1,7 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" -#include "Luau/Scope.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" +#include "lluz/Scope.h" #include @@ -9,12 +9,9 @@ #include "doctest.h" -LUAU_FASTFLAG(LuauCheckGenericHOFTypes) -LUAU_FASTFLAG(LuauSpecialTypesAsterisked) +using namespace lluz; -using namespace Luau; - -TEST_SUITE_BEGIN("GenericsTests"); +TEST_SUITE_BEGIN(XorStr("GenericsTests")); TEST_CASE_FIXTURE(Fixture, "check_generic_function") { @@ -25,7 +22,7 @@ TEST_CASE_FIXTURE(Fixture, "check_generic_function") local x: string = id("hi") local y: number = id(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "check_generic_local_function") @@ -37,7 +34,7 @@ TEST_CASE_FIXTURE(Fixture, "check_generic_local_function") local x: string = id("hi") local y: number = id(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "check_generic_typepack_function") @@ -48,7 +45,7 @@ TEST_CASE_FIXTURE(Fixture, "check_generic_typepack_function") local z: number = id(37) id() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "types_before_typepacks") @@ -56,7 +53,7 @@ TEST_CASE_FIXTURE(Fixture, "types_before_typepacks") CheckResult result = check(R"( function f() end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "local_vars_can_be_polytypes") @@ -67,7 +64,7 @@ TEST_CASE_FIXTURE(Fixture, "local_vars_can_be_polytypes") local x: string = f("hi") local y: number = f(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "inferred_local_vars_can_be_polytypes") @@ -79,7 +76,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "inferred_local_vars_can_be_polytypes") local x: string = f("hi") local y: number = f(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "local_vars_can_be_instantiated_polytypes") @@ -90,7 +87,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "local_vars_can_be_instantiated_polytypes") local f: (number)->number = id local g: (string)->string = id )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "properties_can_be_polytypes") @@ -101,7 +98,7 @@ TEST_CASE_FIXTURE(Fixture, "properties_can_be_polytypes") local x: string = t.m("hi") local y: number = t.m(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "properties_can_be_instantiated_polytypes") @@ -111,7 +108,7 @@ TEST_CASE_FIXTURE(Fixture, "properties_can_be_instantiated_polytypes") local function id(x:a):a return x end t.m = id )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "check_nested_generic_function") @@ -125,7 +122,7 @@ TEST_CASE_FIXTURE(Fixture, "check_nested_generic_function") local y: number = id(37) end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "check_recursive_generic_function") @@ -137,7 +134,7 @@ TEST_CASE_FIXTURE(Fixture, "check_recursive_generic_function") return x end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "check_mutual_generic_functions") @@ -155,7 +152,7 @@ TEST_CASE_FIXTURE(Fixture, "check_mutual_generic_functions") return x end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "generic_functions_in_types") @@ -166,7 +163,7 @@ TEST_CASE_FIXTURE(Fixture, "generic_functions_in_types") local y: string = x.id("hi") local z: number = x.id(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "generic_factories") @@ -187,7 +184,7 @@ TEST_CASE_FIXTURE(Fixture, "generic_factories") local y: string = f.build().id("hi") local z: number = f.build().id(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "factories_of_generics") @@ -209,7 +206,7 @@ TEST_CASE_FIXTURE(Fixture, "factories_of_generics") local y: string = x.id("hi") local z: number = x.id(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "infer_generic_function") @@ -221,9 +218,9 @@ TEST_CASE_FIXTURE(Fixture, "infer_generic_function") local x: string = id("hi") local y: number = id(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId idType = requireType("id"); + TypeId idType = requireType(XorStr("id")); const FunctionTypeVar* idFun = get(idType); REQUIRE(idFun); auto [args, varargs] = flatten(idFun->argTypes); @@ -244,9 +241,9 @@ TEST_CASE_FIXTURE(Fixture, "infer_generic_local_function") local x: string = id("hi") local y: number = id(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId idType = requireType("id"); + TypeId idType = requireType(XorStr("id")); const FunctionTypeVar* idFun = get(idType); REQUIRE(idFun); auto [args, varargs] = flatten(idFun->argTypes); @@ -269,12 +266,12 @@ TEST_CASE_FIXTURE(Fixture, "infer_nested_generic_function") local y: number = id(37) end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "infer_generic_methods") { - ScopedFastFlag sff{"DebugLuauSharedSelf", true}; + ScopedFastFlag sff{"DebuglluzSharedSelf", true}; CheckResult result = check(R"( local x = {} @@ -283,7 +280,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_generic_methods") function x:g(): number return self:id(37) end )"); // TODO: Quantification should be doing the conversion, not normalization. - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "calling_self_generic_methods") @@ -297,7 +294,7 @@ TEST_CASE_FIXTURE(Fixture, "calling_self_generic_methods") end )"); // TODO: Should typecheck but currently errors CLI-39916 - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "infer_generic_property") @@ -308,7 +305,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_generic_property") local x: string = t.m("hi") local y: number = t.m(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "function_arguments_can_be_polytypes") @@ -319,7 +316,7 @@ TEST_CASE_FIXTURE(Fixture, "function_arguments_can_be_polytypes") local y: string = g("hi") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "function_results_can_be_polytypes") @@ -330,7 +327,7 @@ TEST_CASE_FIXTURE(Fixture, "function_results_can_be_polytypes") return id end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "type_parameters_can_be_polytypes") @@ -339,7 +336,7 @@ TEST_CASE_FIXTURE(Fixture, "type_parameters_can_be_polytypes") local function id(x:a):a return x end local f: (a)->a = id(id) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "dont_leak_generic_types") @@ -360,7 +357,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_leak_generic_types") -- so this assignment should fail local b: boolean = f(true) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "dont_leak_inferred_generic_types") @@ -376,7 +373,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_leak_inferred_generic_types") local y: number = id(37) end )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "dont_substitute_bound_types") @@ -387,7 +384,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_substitute_bound_types") local x: T = t.m(37) end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "dont_unify_bound_types") @@ -410,12 +407,12 @@ TEST_CASE_FIXTURE(Fixture, "dont_unify_bound_types") local a : string = g("not a number", "hi") local b : number = g(5, 37) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "mutable_state_polymorphism") { - // Replaying the classic problem with polymorphism and mutable state in Luau + // Replaying the classic problem with polymorphism and mutable state in lluz // See, e.g. Tofte (1990) // https://www.sciencedirect.com/science/article/pii/089054019090018D. CheckResult result = check(R"( @@ -450,7 +447,7 @@ TEST_CASE_FIXTURE(Fixture, "mutable_state_polymorphism") -- so b has value "not a number" at run time local b: number = f(37) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "rank_N_types_via_typeof") @@ -472,7 +469,7 @@ TEST_CASE_FIXTURE(Fixture, "rank_N_types_via_typeof") local a: string = f("hi") local b: number = f(37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "duplicate_generic_types") @@ -480,7 +477,7 @@ TEST_CASE_FIXTURE(Fixture, "duplicate_generic_types") CheckResult result = check(R"( function f(x:a):a return x end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "duplicate_generic_type_packs") @@ -488,7 +485,7 @@ TEST_CASE_FIXTURE(Fixture, "duplicate_generic_type_packs") CheckResult result = check(R"( function f() end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "typepacks_before_types") @@ -496,7 +493,7 @@ TEST_CASE_FIXTURE(Fixture, "typepacks_before_types") CheckResult result = check(R"( function f() end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "variadic_generics") @@ -507,7 +504,7 @@ TEST_CASE_FIXTURE(Fixture, "variadic_generics") type F = (...a) -> ...a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "generic_type_pack_syntax") @@ -516,8 +513,8 @@ TEST_CASE_FIXTURE(Fixture, "generic_type_pack_syntax") function f(...: a...): (a...) return ... end )"); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("f")), "(a...) -> (a...)"); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ(toString(requireType(XorStr("f")), "(a...) -> (a...)")); } TEST_CASE_FIXTURE(Fixture, "generic_type_pack_parentheses") @@ -526,7 +523,7 @@ TEST_CASE_FIXTURE(Fixture, "generic_type_pack_parentheses") function f(...: a...): any return (...) end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "better_mismatch_error_messages") @@ -541,15 +538,15 @@ TEST_CASE_FIXTURE(Fixture, "better_mismatch_error_messages") end )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); SwappedGenericTypeParameter* fErr = get(result.errors[0]); REQUIRE(fErr); - CHECK_EQ(fErr->name, "T"); + CHECK_EQ(fErr->name, XorStr("T")); CHECK_EQ(fErr->kind, SwappedGenericTypeParameter::Pack); SwappedGenericTypeParameter* gErr = get(result.errors[1]); REQUIRE(gErr); - CHECK_EQ(gErr->name, "T"); + CHECK_EQ(gErr->name, XorStr("T")); CHECK_EQ(gErr->kind, SwappedGenericTypeParameter::Type); } @@ -559,10 +556,10 @@ TEST_CASE_FIXTURE(Fixture, "reject_clashing_generic_and_pack_names") function f() end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); DuplicateGenericParameter* err = get(result.errors[0]); REQUIRE(err != nullptr); - CHECK_EQ(err->parameterName, "a"); + CHECK_EQ(err->parameterName, XorStr("a")); } TEST_CASE_FIXTURE(Fixture, "instantiation_sharing_types") @@ -581,7 +578,7 @@ TEST_CASE_FIXTURE(Fixture, "instantiation_sharing_types") local x2, y2, z2 = o2.x, o2.y, o2.z )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK(requireType("x1") != requireType("x2")); CHECK(requireType("y1") == requireType("y2")); CHECK(requireType("z1") != requireType("z2")); @@ -596,7 +593,7 @@ TEST_CASE_FIXTURE(Fixture, "quantification_sharing_types") local z2 = g(true, "hi") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK(requireType("z1") == requireType("z2")); } @@ -610,7 +607,7 @@ TEST_CASE_FIXTURE(Fixture, "typefuns_sharing_types") local x2, y2 = o2.x, o2.y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK(requireType("x1") != requireType("x2")); CHECK(requireType("y1") == requireType("y2")); } @@ -630,7 +627,7 @@ exports.nested = nested return exports )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "instantiated_function_argument_names") @@ -641,13 +638,13 @@ local function f(a: T, ...: U...) end f(1, 2, 3) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); auto ty = findTypeAtPosition(Position(3, 0)); REQUIRE(ty); ToStringOptions opts; opts.functionTypeArguments = true; - CHECK_EQ(toString(*ty, opts), "(a: number, number, number) -> ()"); + CHECK_EQ(toString(*ty, opts), XorStr("(a: number, number, number) -> ()")); } TEST_CASE_FIXTURE(Fixture, "error_detailed_function_mismatch_generic_types") @@ -660,9 +657,9 @@ local c: C local d: D = c )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), R"(Type '() -> ()' could not be converted into '() -> ()'; different number of generic type parameters)"); + CHECK_EQ(toString(result.errors[0]), RXorStr("(Type '() -> ()' could not be converted into '() -> ()'; different number of generic type parameters)")); } TEST_CASE_FIXTURE(Fixture, "error_detailed_function_mismatch_generic_pack") @@ -675,16 +672,16 @@ local c: C local d: D = c )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), - R"(Type '() -> ()' could not be converted into '() -> ()'; different number of generic type pack parameters)"); + RXorStr("(Type '() -> ()' could not be converted into '() -> ()'; different number of generic type pack parameters)")); } TEST_CASE_FIXTURE(BuiltinsFixture, "generic_functions_dont_cache_type_parameters") { CheckResult result = check(R"( --- See https://github.com/Roblox/luau/issues/332 +-- See https://github.com/Roblox/lluz/issues/332 -- This function has a type parameter with the same name as clones, -- so if we cache type parameter names for functions these get confused. -- function id(x : Z) : Z @@ -701,7 +698,7 @@ function clone(dict: {[X]:Y}): {[X]:Y} end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "generic_functions_should_be_memory_safe") @@ -717,7 +714,7 @@ local y: T = { a = { c = nil, d = 5 }, b = 37 } y.a.c = y )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ(toString(result.errors[0]), R"(Type 'y' could not be converted into 'T' caused by: @@ -741,7 +738,7 @@ local TheDispatcher: Dispatcher = { } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "generic_type_pack_unification2") @@ -759,7 +756,7 @@ local TheDispatcher: Dispatcher = { } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "generic_type_pack_unification3") @@ -777,7 +774,7 @@ local TheDispatcher: Dispatcher = { } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "generic_argument_count_too_few") @@ -793,8 +790,8 @@ end wrapper(test) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), R"(Argument count mismatch. Function expects 2 arguments, but only 1 is specified)"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), RXorStr("(Argument count mismatch. Function expects 2 arguments, but only 1 is specified)")); } TEST_CASE_FIXTURE(Fixture, "generic_argument_count_too_many") @@ -810,8 +807,8 @@ end wrapper(test2, 1, "", 3) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), R"(Argument count mismatch. Function expects 3 arguments, but 4 are specified)"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), RXorStr("(Argument count mismatch. Function expects 3 arguments, but 4 are specified)")); } TEST_CASE_FIXTURE(Fixture, "generic_function") @@ -822,7 +819,7 @@ TEST_CASE_FIXTURE(Fixture, "generic_function") local b = id(nil) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("(a) -> a", toString(requireType("id"))); CHECK_EQ(*typeChecker.numberType, *requireType("a")); @@ -839,9 +836,9 @@ TEST_CASE_FIXTURE(Fixture, "generic_table_method") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId tType = requireType("T"); + TypeId tType = requireType(XorStr("T")); TableTypeVar* tTable = getMutable(tType); REQUIRE(tTable != nullptr); @@ -871,13 +868,13 @@ TEST_CASE_FIXTURE(Fixture, "correctly_instantiate_polymorphic_member_functions") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); const TableTypeVar* t = get(requireType("T")); REQUIRE(t != nullptr); - std::optional fooProp = get(t->props, "foo"); + std::optional fooProp = get(t->props, XorStr("foo")); REQUIRE(bool(fooProp)); const FunctionTypeVar* foo = get(follow(fooProp->type)); @@ -913,7 +910,7 @@ TEST_CASE_FIXTURE(Fixture, "instantiate_cyclic_generic_function") end )"); - TypeId g = requireType("g"); + TypeId g = requireType(XorStr("g")); const FunctionTypeVar* gFun = get(g); REQUIRE(gFun != nullptr); @@ -924,7 +921,7 @@ TEST_CASE_FIXTURE(Fixture, "instantiate_cyclic_generic_function") const TableTypeVar* argTable = get(arg); REQUIRE(argTable != nullptr); - std::optional methodProp = get(argTable->props, "method"); + std::optional methodProp = get(argTable->props, XorStr("method")); REQUIRE(bool(methodProp)); const FunctionTypeVar* methodFunction = get(methodProp->type); @@ -950,7 +947,7 @@ TEST_CASE_FIXTURE(Fixture, "instantiate_generic_function_in_assignments") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -970,7 +967,7 @@ TEST_CASE_FIXTURE(Fixture, "instantiate_generic_function_in_assignments2") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -987,8 +984,8 @@ type Self = T local a: Self
)"); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Table"); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ(toString(requireType(XorStr("a")), "Table")); } TEST_CASE_FIXTURE(Fixture, "no_stack_overflow_from_quantifying") @@ -1000,14 +997,11 @@ TEST_CASE_FIXTURE(Fixture, "no_stack_overflow_from_quantifying") type t0 = t0 | {} )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); - std::optional t0 = getMainModule()->getModuleScope()->lookupType("t0"); + std::optional t0 = getMainModule()->getModuleScope()->lookupType(XorStr("t0")); REQUIRE(t0); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(t0->type)); - else - CHECK_EQ("", toString(t0->type)); + CHECK_EQ("*unknown*", toString(t0->type)); auto it = std::find_if(result.errors.begin(), result.errors.end(), [](TypeError& err) { return get(err); @@ -1024,7 +1018,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "infer_generic_function_function_argument") return sum(2, 3, function(a, b) return a + b end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); result = check(R"( local function map(arr: {a}, f: (a) -> b) @@ -1038,7 +1032,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "infer_generic_function_function_argument") local r = map(a, function(a) return a + a > 100 end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); REQUIRE_EQ("{boolean}", toString(requireType("r"))); check(R"( @@ -1053,7 +1047,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "infer_generic_function_function_argument") local r = foldl(a, {s=0,c=0}, function(a, b) return {s = a.s + b, c = a.c + 1} end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); REQUIRE_EQ("{ c: number, s: number }", toString(requireType("r"))); } @@ -1066,7 +1060,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_generic_function_function_argument_overloaded" g12(1, 2, function(x, y) return x + y end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); result = check(R"( local g12: ((T, (T) -> T) -> T) & ((T, T, (T, T) -> T) -> T) @@ -1075,7 +1069,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_generic_function_function_argument_overloaded" g12({x=1}, {x=2}, function(x, y) return {x=x.x + y.x} end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "infer_generic_lib_function_function_argument") @@ -1085,7 +1079,7 @@ local a = {{x=4}, {x=7}, {x=1}} table.sort(a, function(x, y) return x.x < y.x end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "do_not_infer_generic_functions") @@ -1101,18 +1095,10 @@ local b = sumrec(sum) -- ok local c = sumrec(function(x, y, f) return f(x, y) end) -- type binders are not inferred )"); - if (FFlag::LuauCheckGenericHOFTypes) - { - LUAU_REQUIRE_NO_ERRORS(result); - } - else - { - LUAU_REQUIRE_ERRORS(result); - CHECK_EQ( - "Type '(a, b, (a, b) -> (c...)) -> (c...)' could not be converted into '(a, a, (a, a) -> a) -> a'; different number of generic type " - "parameters", - toString(result.errors[0])); - } + lluz_REQUIRE_ERRORS(result); + CHECK_EQ("Type '(a, b, (a, b) -> (c...)) -> (c...)' could not be converted into '(a, a, (a, a) -> a) -> a'; different number of generic type " + "parameters", + toString(result.errors[0])); } TEST_CASE_FIXTURE(Fixture, "substitution_with_bound_table") @@ -1126,12 +1112,12 @@ TEST_CASE_FIXTURE(Fixture, "substitution_with_bound_table") local c: X )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "apply_type_function_nested_generics1") { - // https://github.com/Roblox/luau/issues/484 + // https://github.com/Roblox/lluz/issues/484 CheckResult result = check(R"( --!strict type MyObject = { @@ -1154,12 +1140,12 @@ local complex: ComplexObject = { } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "apply_type_function_nested_generics2") { - // https://github.com/Roblox/luau/issues/484 + // https://github.com/Roblox/lluz/issues/484 CheckResult result = check(R"( --!strict type MyObject = { @@ -1173,7 +1159,7 @@ type ComplexObject = { local complex2: ComplexObject = nil local x = complex2.nested.getReturnValue(function(): string - return "" + return XorStr("") end) local y = complex2.nested.getReturnValue(function() @@ -1181,13 +1167,13 @@ local y = complex2.nested.getReturnValue(function() end) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "quantify_functions_even_if_they_have_an_explicit_generic") { ScopedFastFlag sff[] = { - {"LuauAlwaysQuantify", true}, + {"lluzAlwaysQuantify", true}, }; CheckResult result = check(R"( @@ -1199,23 +1185,4 @@ TEST_CASE_FIXTURE(Fixture, "quantify_functions_even_if_they_have_an_explicit_gen CHECK("((X) -> (a...), X) -> (a...)" == toString(requireType("foo"))); } -TEST_CASE_FIXTURE(Fixture, "do_not_always_instantiate_generic_intersection_types") -{ - ScopedFastFlag sff[] = { - {"LuauMaybeGenericIntersectionTypes", true}, - }; - - CheckResult result = check(R"( - --!strict - type Array = { [number]: T } - - type Array_Statics = { - new: () -> Array, - } - - local _Arr : Array & Array_Statics = {} :: Array_Statics - )"); - LUAU_REQUIRE_NO_ERRORS(result); -} - TEST_SUITE_END(); diff --git a/tests/TypeInfer.intersectionTypes.test.cpp b/tests/TypeInfer.intersectionTypes.test.cpp index 818d0124..5962cb97 100644 --- a/tests/TypeInfer.intersectionTypes.test.cpp +++ b/tests/TypeInfer.intersectionTypes.test.cpp @@ -1,16 +1,16 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(LuauLowerBoundsCalculation); +lluz_FASTFLAG(LluLowerBoundsCalculation); -TEST_SUITE_BEGIN("IntersectionTypes"); +TEST_SUITE_BEGIN(XorStr("IntersectionTypes")); TEST_CASE_FIXTURE(Fixture, "select_correct_union_fn") { @@ -22,7 +22,7 @@ TEST_CASE_FIXTURE(Fixture, "select_correct_union_fn") local c = f("a") -- c is a number )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(requireType("b"), typeChecker.stringType); CHECK_EQ(requireType("c"), typeChecker.numberType); } @@ -35,7 +35,7 @@ TEST_CASE_FIXTURE(Fixture, "table_combines") local c:A & B = {a=10, b="s"} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "table_combines_missing") @@ -67,7 +67,7 @@ TEST_CASE_FIXTURE(Fixture, "table_extra_ok") local d:A = c )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "fx_intersection_as_argument") @@ -81,7 +81,7 @@ TEST_CASE_FIXTURE(Fixture, "fx_intersection_as_argument") local b = g(f) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "fx_union_as_argument_fails") @@ -108,7 +108,7 @@ TEST_CASE_FIXTURE(Fixture, "argument_is_intersection") f(true) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "should_still_pick_an_overload_whose_arguments_are_unions") @@ -122,7 +122,7 @@ TEST_CASE_FIXTURE(Fixture, "should_still_pick_an_overload_whose_arguments_are_un local b1, b2 = f("foo"), f(nil) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*requireType("a1"), *typeChecker.numberType); CHECK_EQ(*requireType("a2"), *typeChecker.numberType); @@ -161,7 +161,7 @@ TEST_CASE_FIXTURE(Fixture, "index_on_an_intersection_type_with_property_guarante local r = t.x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const IntersectionTypeVar* r = get(requireType("r")); REQUIRE(r); @@ -185,7 +185,7 @@ TEST_CASE_FIXTURE(Fixture, "index_on_an_intersection_type_works_at_arbitrary_dep local r = t.x.y.z.thing )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("string & string", toString(requireType("r"))); } @@ -199,7 +199,7 @@ TEST_CASE_FIXTURE(Fixture, "index_on_an_intersection_type_with_mixed_types") local r = t.x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number & string", toString(requireType("r"))); // TODO(amccord): This should be an error. } @@ -213,7 +213,7 @@ TEST_CASE_FIXTURE(Fixture, "index_on_an_intersection_type_with_one_part_missing_ local r = t.x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireType("r"))); } @@ -227,7 +227,7 @@ TEST_CASE_FIXTURE(Fixture, "index_on_an_intersection_type_with_one_property_of_t local r = t.x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.anyType, *requireType("r")); } @@ -242,11 +242,11 @@ TEST_CASE_FIXTURE(Fixture, "index_on_an_intersection_type_with_all_parts_missing end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); UnknownProperty* up = get(result.errors[0]); REQUIRE_MESSAGE(up, result.errors[0].data); - CHECK_EQ(up->key, "x"); + CHECK_EQ(up->key, XorStr("x")); } TEST_CASE_FIXTURE(Fixture, "table_intersection_write") @@ -259,7 +259,7 @@ TEST_CASE_FIXTURE(Fixture, "table_intersection_write") a.x = 10 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); result = check(R"( type X = {} @@ -269,7 +269,7 @@ TEST_CASE_FIXTURE(Fixture, "table_intersection_write") a.x = 10 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); result = check(R"( type X = { x: number } @@ -280,7 +280,7 @@ TEST_CASE_FIXTURE(Fixture, "table_intersection_write") a.x = 10 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); result = check(R"( type A = { x: {y: number} } @@ -291,7 +291,7 @@ TEST_CASE_FIXTURE(Fixture, "table_intersection_write") t.x.y = 40 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "table_intersection_write_sealed") @@ -305,11 +305,11 @@ TEST_CASE_FIXTURE(Fixture, "table_intersection_write_sealed") a.z = 10 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - if (FFlag::LuauLowerBoundsCalculation) - CHECK_EQ(toString(result.errors[0]), "Cannot add property 'z' to table '{| x: number, y: number |}'"); + lluz_REQUIRE_ERROR_COUNT(1, result); + if (FFlag::LluLowerBoundsCalculation) + CHECK_EQ(toString(result.errors[0]), XorStr("Cannot add property 'z' to table '{| x: number, y: number |}'")); else - CHECK_EQ(toString(result.errors[0]), "Cannot add property 'z' to table 'X & Y'"); + CHECK_EQ(toString(result.errors[0]), XorStr("Cannot add property 'z' to table 'X & Y'")); } TEST_CASE_FIXTURE(Fixture, "table_intersection_write_sealed_indirect") @@ -329,20 +329,20 @@ TEST_CASE_FIXTURE(Fixture, "table_intersection_write_sealed_indirect") function xy:w(a:number) return a * 10 end )"); - LUAU_REQUIRE_ERROR_COUNT(4, result); + lluz_REQUIRE_ERROR_COUNT(4, result); CHECK_EQ(toString(result.errors[0]), R"(Type '(string, number) -> string' could not be converted into '(string) -> string' caused by: Argument count mismatch. Function expects 2 arguments, but only 1 is specified)"); - if (FFlag::LuauLowerBoundsCalculation) - CHECK_EQ(toString(result.errors[1]), "Cannot add property 'z' to table '{| x: (number) -> number, y: (string) -> string |}'"); + if (FFlag::LluLowerBoundsCalculation) + CHECK_EQ(toString(result.errors[1]), XorStr("Cannot add property 'z' to table '{| x: (number) -> number, y: (string) -> string |}'")); else - CHECK_EQ(toString(result.errors[1]), "Cannot add property 'z' to table 'X & Y'"); - CHECK_EQ(toString(result.errors[2]), "Type 'number' could not be converted into 'string'"); + CHECK_EQ(toString(result.errors[1]), XorStr("Cannot add property 'z' to table 'X & Y'")); + CHECK_EQ(toString(result.errors[2]), XorStr("Type 'number' could not be converted into 'string'")); - if (FFlag::LuauLowerBoundsCalculation) - CHECK_EQ(toString(result.errors[3]), "Cannot add property 'w' to table '{| x: (number) -> number, y: (string) -> string |}'"); + if (FFlag::LluLowerBoundsCalculation) + CHECK_EQ(toString(result.errors[3]), XorStr("Cannot add property 'w' to table '{| x: (number) -> number, y: (string) -> string |}'")); else - CHECK_EQ(toString(result.errors[3]), "Cannot add property 'w' to table 'X & Y'"); + CHECK_EQ(toString(result.errors[3]), XorStr("Cannot add property 'w' to table 'X & Y'")); } TEST_CASE_FIXTURE(Fixture, "table_write_sealed_indirect") @@ -360,13 +360,13 @@ TEST_CASE_FIXTURE(Fixture, "table_write_sealed_indirect") function xy:w(a:number) return a * 10 end )"); - LUAU_REQUIRE_ERROR_COUNT(4, result); + lluz_REQUIRE_ERROR_COUNT(4, result); CHECK_EQ(toString(result.errors[0]), R"(Type '(string, number) -> string' could not be converted into '(string) -> string' caused by: Argument count mismatch. Function expects 2 arguments, but only 1 is specified)"); - CHECK_EQ(toString(result.errors[1]), "Cannot add property 'z' to table 'XY'"); - CHECK_EQ(toString(result.errors[2]), "Type 'number' could not be converted into 'string'"); - CHECK_EQ(toString(result.errors[3]), "Cannot add property 'w' to table 'XY'"); + CHECK_EQ(toString(result.errors[1]), XorStr("Cannot add property 'z' to table 'XY'")); + CHECK_EQ(toString(result.errors[2]), XorStr("Type 'number' could not be converted into 'string'")); + CHECK_EQ(toString(result.errors[3]), XorStr("Cannot add property 'w' to table 'XY'")); } TEST_CASE_FIXTURE(BuiltinsFixture, "table_intersection_setmetatable") @@ -376,12 +376,12 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_intersection_setmetatable") setmetatable(t, {}) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "error_detailed_intersection_part") { - ScopedFastFlag flags[] = {{"LuauLowerBoundsCalculation", false}}; + ScopedFastFlag flags[] = {{"lluzLowerBoundsCalculation", false}}; CheckResult result = check(R"( type X = { x: number } @@ -393,7 +393,7 @@ type XYZ = X & Y & Z local a: XYZ = 3 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type 'number' could not be converted into 'X & Y & Z' caused by: Not all intersection parts are compatible. Type 'number' could not be converted into 'X')"); @@ -401,7 +401,7 @@ caused by: TEST_CASE_FIXTURE(Fixture, "error_detailed_intersection_all") { - ScopedFastFlag flags[] = {{"LuauLowerBoundsCalculation", false}}; + ScopedFastFlag flags[] = {{"lluzLowerBoundsCalculation", false}}; CheckResult result = check(R"( type X = { x: number } @@ -414,8 +414,8 @@ local a: XYZ local b: number = a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), R"(Type 'X & Y & Z' could not be converted into 'number'; none of the intersection parts are compatible)"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), RXorStr("(Type 'X & Y & Z' could not be converted into 'number'; none of the intersection parts are compatible)")); } TEST_CASE_FIXTURE(Fixture, "overload_is_not_a_function") @@ -443,7 +443,7 @@ TEST_CASE_FIXTURE(Fixture, "no_stack_overflow_from_flattenintersection") until _(_)(_)._ )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_SUITE_END(); diff --git a/tests/TypeInfer.loops.test.cpp b/tests/TypeInfer.loops.test.cpp index 9b10092c..98bd2172 100644 --- a/tests/TypeInfer.loops.test.cpp +++ b/tests/TypeInfer.loops.test.cpp @@ -1,21 +1,19 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/AstQuery.h" -#include "Luau/BuiltinDefinitions.h" -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" -#include "Luau/VisitTypeVar.h" +#include "lluz/AstQuery.h" +#include "lluz/BuiltinDefinitions.h" +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" +#include "lluz/VisitTypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(LuauSpecialTypesAsterisked) - -TEST_SUITE_BEGIN("TypeInferLoops"); +TEST_SUITE_BEGIN(XorStr("TypeInferLoops")); TEST_CASE_FIXTURE(Fixture, "for_loop") { @@ -26,7 +24,7 @@ TEST_CASE_FIXTURE(Fixture, "for_loop") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.numberType, *requireType("q")); } @@ -42,7 +40,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_loop") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.numberType, *requireType("n")); CHECK_EQ(*typeChecker.stringType, *requireType("s")); @@ -59,7 +57,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_loop_with_next") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.numberType, *requireType("n")); CHECK_EQ(*typeChecker.stringType, *requireType("s")); @@ -75,7 +73,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_with_an_iterator_of_type_any") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "for_in_loop_should_fail_with_non_function_iterator") @@ -86,7 +84,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_should_fail_with_non_function_iterator") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Cannot call non-function string", toString(result.errors[0])); } @@ -106,7 +104,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_with_just_one_iterator_is_ok") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_with_a_custom_iterator_should_type_check") @@ -123,7 +121,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_with_a_custom_iterator_should_type_ch end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "for_in_loop_on_error") @@ -143,11 +141,8 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_on_error") CHECK_EQ(2, result.errors.size()); - TypeId p = requireType("p"); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(p)); - else - CHECK_EQ("", toString(p)); + TypeId p = requireType(XorStr("p")); + CHECK_EQ("*unknown*", toString(p)); } TEST_CASE_FIXTURE(Fixture, "for_in_loop_on_non_function") @@ -159,7 +154,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_on_non_function") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); REQUIRE(get(result.errors[0])); } @@ -199,7 +194,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_loop_error_on_factory_not_returning_t for p in primes3() do print(p) end -- no error )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CountMismatch* acm = get(result.errors[0]); REQUIRE(acm); @@ -223,7 +218,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "for_in_loop_error_on_iterator_requiring_args for p in prime_iter do print(p) end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CountMismatch* acm = get(result.errors[0]); REQUIRE(acm); @@ -244,7 +239,7 @@ TEST_CASE_FIXTURE(Fixture, "for_in_loop_with_custom_iterator") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -261,7 +256,7 @@ TEST_CASE_FIXTURE(Fixture, "while_loop") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.numberType, *requireType("i")); } @@ -275,7 +270,7 @@ TEST_CASE_FIXTURE(Fixture, "repeat_loop") until true )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.stringType, *requireType("i")); } @@ -288,7 +283,7 @@ TEST_CASE_FIXTURE(Fixture, "repeat_loop_condition_binds_to_its_block") until x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "symbols_in_repeat_block_should_not_be_visible_beyond_until_condition") @@ -301,7 +296,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "symbols_in_repeat_block_should_not_be_visibl print(x) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(BuiltinsFixture, "varlist_declared_by_for_in_loop_should_be_free") @@ -316,7 +311,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "varlist_declared_by_for_in_loop_should_be_fr end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "properly_infer_iteratee_is_a_free_table") @@ -329,7 +324,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "properly_infer_iteratee_is_a_free_table") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "correctly_scope_locals_while") @@ -342,11 +337,11 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "correctly_scope_locals_while") print(a) -- oops! )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); UnknownSymbol* us = get(result.errors[0]); REQUIRE(us); - CHECK_EQ(us->name, "a"); + CHECK_EQ(us->name, XorStr("a")); } TEST_CASE_FIXTURE(BuiltinsFixture, "ipairs_produces_integral_indices") @@ -356,7 +351,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "ipairs_produces_integral_indices") for i, e in ipairs({}) do key = i end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); REQUIRE_EQ("number", toString(requireType("key"))); } @@ -394,7 +389,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "unreachable_code_after_infinite_loop") unreachablecodepath(4) )"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + lluz_REQUIRE_ERROR_COUNT(0, result); } { @@ -410,7 +405,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "unreachable_code_after_infinite_loop") reachablecodepath(4) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK(get(result.errors[0])); } @@ -426,7 +421,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "unreachable_code_after_infinite_loop") unreachablecodepath(4) )"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + lluz_REQUIRE_ERROR_COUNT(0, result); } { @@ -443,7 +438,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "unreachable_code_after_infinite_loop") reachablecodepath(4) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK(get(result.errors[0])); } @@ -459,7 +454,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "unreachable_code_after_infinite_loop") unreachablecodepath(4) )"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + lluz_REQUIRE_ERROR_COUNT(0, result); } } @@ -473,7 +468,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "loop_typecheck_crash_on_empty_optional") end )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); } TEST_CASE_FIXTURE(Fixture, "fuzz_fail_missing_instantitation_follow") @@ -503,7 +498,7 @@ TEST_CASE_FIXTURE(Fixture, "loop_iter_basic") end )"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + lluz_REQUIRE_ERROR_COUNT(0, result); CHECK_EQ(*typeChecker.numberType, *requireType("key")); } @@ -517,11 +512,11 @@ TEST_CASE_FIXTURE(Fixture, "loop_iter_trailing_nil") end )"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + lluz_REQUIRE_ERROR_COUNT(0, result); CHECK_EQ(*typeChecker.nilType, *requireType("extra")); } -TEST_CASE_FIXTURE(Fixture, "loop_iter_no_indexer_strict") +TEST_CASE_FIXTURE(Fixture, "loop_iter_no_indexer") { CheckResult result = check(R"( local t = {} @@ -529,24 +524,13 @@ TEST_CASE_FIXTURE(Fixture, "loop_iter_no_indexer_strict") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); GenericError* ge = get(result.errors[0]); REQUIRE(ge); CHECK_EQ("Cannot iterate over a table without indexer", ge->message); } -TEST_CASE_FIXTURE(Fixture, "loop_iter_no_indexer_nonstrict") -{ - CheckResult result = check(Mode::Nonstrict, R"( - local t = {} - for k, v in t do - end - )"); - - LUAU_REQUIRE_ERROR_COUNT(0, result); -} - TEST_CASE_FIXTURE(BuiltinsFixture, "loop_iter_iter_metamethod") { CheckResult result = check(R"( @@ -556,7 +540,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "loop_iter_iter_metamethod") end )"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + lluz_REQUIRE_ERROR_COUNT(0, result); } TEST_SUITE_END(); diff --git a/tests/TypeInfer.modules.test.cpp b/tests/TypeInfer.modules.test.cpp index a1d41339..82683879 100644 --- a/tests/TypeInfer.modules.test.cpp +++ b/tests/TypeInfer.modules.test.cpp @@ -1,26 +1,24 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/AstQuery.h" -#include "Luau/BuiltinDefinitions.h" -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +#include "lluz/AstQuery.h" +#include "lluz/BuiltinDefinitions.h" +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(LuauSpecialTypesAsterisked) - -TEST_SUITE_BEGIN("TypeInferModules"); +TEST_SUITE_BEGIN(XorStr("TypeInferModules")); TEST_CASE_FIXTURE(BuiltinsFixture, "require") { fileResolver.source["game/A"] = R"( local function hooty(x: number): string - return "Hi there!" + return XorStr("Hi there!") end return {hooty=hooty} @@ -33,13 +31,13 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "require") local i = Hooty.hooty(h) )"; - CheckResult aResult = frontend.check("game/A"); + CheckResult aResult = frontend.check(XorStr("game/A")); dumpErrors(aResult); - LUAU_REQUIRE_NO_ERRORS(aResult); + lluz_REQUIRE_NO_ERRORS(aResult); - CheckResult bResult = frontend.check("game/B"); + CheckResult bResult = frontend.check(XorStr("game/B")); dumpErrors(bResult); - LUAU_REQUIRE_NO_ERRORS(bResult); + lluz_REQUIRE_NO_ERRORS(bResult); ModulePtr b = frontend.moduleResolver.modules["game/B"]; @@ -47,10 +45,10 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "require") dumpErrors(bResult); - std::optional iType = requireType(b, "i"); + std::optional iType = requireType(b, XorStr("i")); REQUIRE_EQ("string", toString(*iType)); - std::optional hType = requireType(b, "h"); + std::optional hType = requireType(b, XorStr("h")); REQUIRE_EQ("number", toString(*hType)); } @@ -68,13 +66,13 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "require_types") local h: Hooty.Point )"; - CheckResult bResult = frontend.check("workspace/B"); - LUAU_REQUIRE_NO_ERRORS(bResult); + CheckResult bResult = frontend.check(XorStr("workspace/B")); + lluz_REQUIRE_NO_ERRORS(bResult); ModulePtr b = frontend.moduleResolver.modules["workspace/B"]; REQUIRE(b != nullptr); - TypeId hType = requireType(b, "h"); + TypeId hType = requireType(b, XorStr("h")); REQUIRE_MESSAGE(bool(get(hType)), "Expected table but got " << toString(hType)); } @@ -91,9 +89,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "require_a_variadic_function") local f = A.f )"; - CheckResult result = frontend.check("game/B"); + CheckResult result = frontend.check(XorStr("game/B")); - ModulePtr bModule = frontend.moduleResolver.getModule("game/B"); + ModulePtr bModule = frontend.moduleResolver.getModule(XorStr("game/B")); REQUIRE(bModule != nullptr); TypeId f = follow(requireType(bModule, "f")); @@ -116,7 +114,7 @@ TEST_CASE_FIXTURE(Fixture, "type_error_of_unknown_qualified_type") local p: SomeModule.DoesNotExist )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); REQUIRE_EQ(result.errors[0], (TypeError{Location{{1, 17}, {1, 40}}, UnknownSymbol{"SomeModule.DoesNotExist"}})); } @@ -133,8 +131,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "require_module_that_does_not_export") fileResolver.source["game/Workspace/A"] = sourceA; fileResolver.source["game/Workspace/B"] = sourceB; - frontend.check("game/Workspace/A"); - frontend.check("game/Workspace/B"); + frontend.check(XorStr("game/Workspace/A")); + frontend.check(XorStr("game/Workspace/B")); ModulePtr aModule = frontend.moduleResolver.modules["game/Workspace/A"]; ModulePtr bModule = frontend.moduleResolver.modules["game/Workspace/B"]; @@ -143,12 +141,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "require_module_that_does_not_export") REQUIRE_EQ(1, bModule->errors.size()); CHECK_MESSAGE(get(bModule->errors[0]), "Should be IllegalRequire: " << toString(bModule->errors[0])); - auto hootyType = requireType(bModule, "Hooty"); + auto hootyType = requireType(bModule, XorStr("Hooty")); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(hootyType)); - else - CHECK_EQ("", toString(hootyType)); + CHECK_EQ("*unknown*", toString(hootyType)); } TEST_CASE_FIXTURE(BuiltinsFixture, "warn_if_you_try_to_require_a_non_modulescript") @@ -160,9 +155,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "warn_if_you_try_to_require_a_non_modulescrip local M = require(script.Parent.A) )"; - CheckResult result = frontend.check("Modules/B"); + CheckResult result = frontend.check(XorStr("Modules/B")); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK(get(result.errors[0])); } @@ -181,8 +176,8 @@ local a : string = "" a = tbl.abc.def )"; - CheckResult result = frontend.check("game/B"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = frontend.check(XorStr("game/B")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'number' could not be converted into 'string'", toString(result.errors[0])); } @@ -196,8 +191,8 @@ return { def = 4 } local tbl: string = require(game.A) )"; - CheckResult result = frontend.check("game/B"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = frontend.check(XorStr("game/B")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type '{| def: number |}' could not be converted into 'string'", toString(result.errors[0])); } @@ -219,7 +214,7 @@ end return m )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "custom_require_global") @@ -231,7 +226,7 @@ require = function(a) end local crash = require(game.A) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "require_failed_module") @@ -240,20 +235,16 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "require_failed_module") return unfortunately() )"; - CheckResult aResult = frontend.check("game/A"); - LUAU_REQUIRE_ERRORS(aResult); + CheckResult aResult = frontend.check(XorStr("game/A")); + lluz_REQUIRE_ERRORS(aResult); CheckResult result = check(R"( local ModuleA = require(game.A) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - std::optional oty = requireType("ModuleA"); - - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(*oty)); - else - CHECK_EQ("", toString(*oty)); + std::optional oty = requireType(XorStr("ModuleA")); + CHECK_EQ("*unknown*", toString(*oty)); } TEST_CASE_FIXTURE(BuiltinsFixture, "do_not_modify_imported_types") @@ -270,8 +261,8 @@ local x: Type = {} function x:Destroy(): () end )"; - CheckResult result = frontend.check("game/B"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + CheckResult result = frontend.check(XorStr("game/B")); + lluz_REQUIRE_ERROR_COUNT(2, result); } TEST_CASE_FIXTURE(BuiltinsFixture, "do_not_modify_imported_types_2") @@ -288,8 +279,8 @@ local x: Type = { x = { a = 2 } } type Rename = typeof(x.x) )"; - CheckResult result = frontend.check("game/B"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = frontend.check(XorStr("game/B")); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "do_not_modify_imported_types_3") @@ -307,32 +298,8 @@ local x: Type = types type Rename = typeof(x.x) )"; - CheckResult result = frontend.check("game/B"); - LUAU_REQUIRE_NO_ERRORS(result); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "do_not_modify_imported_types_4") -{ - fileResolver.source["game/A"] = R"( -export type Array = {T} -local arrayops = {} -function arrayops.foo(x: Array) end -return arrayops - )"; - - CheckResult result = check(R"( -local arrayops = require(game.A) - -local tbl = {} -tbl.a = 2 -function tbl:foo(b: number, c: number) - -- introduce BoundTypeVar to imported type - arrayops.foo(self._regions) -end -type Table = typeof(tbl) -)"); - - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = frontend.check(XorStr("game/B")); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "module_type_conflict") @@ -354,8 +321,8 @@ local a: A.T = { x = 2 } local b: B.T = a )"; - CheckResult result = frontend.check("game/C"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = frontend.check(XorStr("game/C")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type 'T' from 'game/A' could not be converted into 'T' from 'game/B' caused by: @@ -388,29 +355,12 @@ local a: A.T = { x = 2 } local b: B.T = a )"; - CheckResult result = frontend.check("game/D"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = frontend.check(XorStr("game/D")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type 'T' from 'game/B' could not be converted into 'T' from 'game/C' caused by: Property 'x' is not compatible. Type 'number' could not be converted into 'string')"); } -TEST_CASE_FIXTURE(BuiltinsFixture, "constrained_anyification_clone_immutable_types") -{ - ScopedFastFlag luauAnyificationMustClone{"LuauAnyificationMustClone", true}; - - fileResolver.source["game/A"] = R"( -return function(...) end - )"; - - fileResolver.source["game/B"] = R"( -local l0 = require(game.A) -return l0 - )"; - - CheckResult result = frontend.check("game/B"); - LUAU_REQUIRE_NO_ERRORS(result); -} - TEST_SUITE_END(); diff --git a/tests/TypeInfer.oop.test.cpp b/tests/TypeInfer.oop.test.cpp index 41690704..1ae25ac0 100644 --- a/tests/TypeInfer.oop.test.cpp +++ b/tests/TypeInfer.oop.test.cpp @@ -1,19 +1,19 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/AstQuery.h" -#include "Luau/BuiltinDefinitions.h" -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" -#include "Luau/VisitTypeVar.h" +#include "lluz/AstQuery.h" +#include "lluz/BuiltinDefinitions.h" +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" +#include "lluz/VisitTypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("TypeInferOOP"); +TEST_SUITE_BEGIN(XorStr("TypeInferOOP")); TEST_CASE_FIXTURE(Fixture, "dont_suggest_using_colon_rather_than_dot_if_not_defined_with_colon") { @@ -26,7 +26,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_suggest_using_colon_rather_than_dot_if_not_defi someTable.Function1() -- Argument count mismatch )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); REQUIRE(get(result.errors[0])); } @@ -42,7 +42,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_suggest_using_colon_rather_than_dot_if_it_wont_ someTable.Function2() -- Argument count mismatch )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); REQUIRE(get(result.errors[0])); } @@ -56,7 +56,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_suggest_using_colon_rather_than_dot_if_another_ T.method(4) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "method_depends_on_table") @@ -71,7 +71,7 @@ TEST_CASE_FIXTURE(Fixture, "method_depends_on_table") function f() x:m() end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "methods_are_topologically_sorted") @@ -90,7 +90,7 @@ TEST_CASE_FIXTURE(Fixture, "methods_are_topologically_sorted") local a, b = T:foo() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); CHECK_EQ(PrimitiveTypeVar::Number, getPrimitiveType(requireType("a"))); @@ -181,7 +181,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "object_constructor_can_refer_to_method_of_se -- foo.fooConn() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "CheckMethodsOfSealed") @@ -193,7 +193,7 @@ function x:y(z: number) end )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); } TEST_CASE_FIXTURE(Fixture, "nonstrict_self_mismatch_tail") @@ -209,7 +209,7 @@ TEST_CASE_FIXTURE(Fixture, "nonstrict_self_mismatch_tail") bar(2) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "inferred_methods_of_free_tables_have_the_same_level_as_the_enclosing_table") @@ -265,11 +265,11 @@ function test() local n = c:getx() local nn = c.x - print(string.format("%d %d", n, nn)) + print(string.format(XorStr("%d %d"), n, nn)) end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_SUITE_END(); diff --git a/tests/TypeInfer.operators.test.cpp b/tests/TypeInfer.operators.test.cpp index 3d6c0193..ca535252 100644 --- a/tests/TypeInfer.operators.test.cpp +++ b/tests/TypeInfer.operators.test.cpp @@ -1,19 +1,19 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/AstQuery.h" -#include "Luau/BuiltinDefinitions.h" -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" -#include "Luau/VisitTypeVar.h" +#include "lluz/AstQuery.h" +#include "lluz/BuiltinDefinitions.h" +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" +#include "lluz/VisitTypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("TypeInferOperators"); +TEST_SUITE_BEGIN(XorStr("TypeInferOperators")); TEST_CASE_FIXTURE(Fixture, "or_joins_types") { @@ -21,9 +21,9 @@ TEST_CASE_FIXTURE(Fixture, "or_joins_types") local s = "a" or 10 local x:string|number = s )"); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(*requireType("s")), "number | string"); - CHECK_EQ(toString(*requireType("x")), "number | string"); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ(toString(*requireType(XorStr("s")), "number | string")); + CHECK_EQ(toString(*requireType(XorStr("x")), "number | string")); } TEST_CASE_FIXTURE(Fixture, "or_joins_types_with_no_extras") @@ -34,8 +34,8 @@ TEST_CASE_FIXTURE(Fixture, "or_joins_types_with_no_extras") local y = x or "s" )"); CHECK_EQ(0, result.errors.size()); - CHECK_EQ(toString(*requireType("s")), "number | string"); - CHECK_EQ(toString(*requireType("y")), "number | string"); + CHECK_EQ(toString(*requireType(XorStr("s")), "number | string")); + CHECK_EQ(toString(*requireType(XorStr("y")), "number | string")); } TEST_CASE_FIXTURE(Fixture, "or_joins_types_with_no_superfluous_union") @@ -55,7 +55,7 @@ TEST_CASE_FIXTURE(Fixture, "and_adds_boolean") local x:boolean|number = s )"); CHECK_EQ(0, result.errors.size()); - CHECK_EQ(toString(*requireType("s")), "boolean | number"); + CHECK_EQ(toString(*requireType(XorStr("s")), "boolean | number")); } TEST_CASE_FIXTURE(Fixture, "and_adds_boolean_no_superfluous_union") @@ -74,7 +74,7 @@ TEST_CASE_FIXTURE(Fixture, "and_or_ternary") local s = (1/2) > 0.5 and "a" or 10 )"); CHECK_EQ(0, result.errors.size()); - CHECK_EQ(toString(*requireType("s")), "number | string"); + CHECK_EQ(toString(*requireType(XorStr("s")), "number | string")); } TEST_CASE_FIXTURE(BuiltinsFixture, "primitive_arith_no_metatable") @@ -86,7 +86,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "primitive_arith_no_metatable") local n, s = add(2,"3") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* functionType = get(requireType("add")); @@ -104,7 +104,7 @@ TEST_CASE_FIXTURE(Fixture, "primitive_arith_no_metatable_with_follows") local SOLAR_MASS=4*PI * PI )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(requireType("SOLAR_MASS"), typeChecker.numberType); } @@ -117,7 +117,7 @@ TEST_CASE_FIXTURE(Fixture, "primitive_arith_possible_metatable") local t = add(1,2) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("t"))); } @@ -131,7 +131,7 @@ TEST_CASE_FIXTURE(Fixture, "some_primitive_binary_ops") local c = b - a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireType("a"))); CHECK_EQ("number", toString(requireType("b"))); @@ -165,7 +165,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_overloaded_multiply_that_is_an_int local e = a * 'cabbage' )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Vec3", toString(requireType("a"))); CHECK_EQ("Vec3", toString(requireType("b"))); @@ -199,7 +199,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_overloaded_multiply_that_is_an_int local e = 'cabbage' * a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Vec3", toString(requireType("a"))); CHECK_EQ("Vec3", toString(requireType("b"))); @@ -216,7 +216,7 @@ TEST_CASE_FIXTURE(Fixture, "compare_numbers") local c = a < b )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "compare_strings") @@ -227,7 +227,7 @@ TEST_CASE_FIXTURE(Fixture, "compare_strings") local c = a < b )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "cannot_indirectly_compare_types_that_do_not_have_a_metatable") @@ -238,11 +238,11 @@ TEST_CASE_FIXTURE(Fixture, "cannot_indirectly_compare_types_that_do_not_have_a_m local c = a < b )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); GenericError* gen = get(result.errors[0]); - REQUIRE_EQ(gen->message, "Type a cannot be compared with < because it has no metatable"); + REQUIRE_EQ(gen->message, XorStr("Type a cannot be compared with < because it has no metatable")); } TEST_CASE_FIXTURE(BuiltinsFixture, "cannot_indirectly_compare_types_that_do_not_offer_overloaded_ordering_operators") @@ -259,11 +259,11 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "cannot_indirectly_compare_types_that_do_not_ local c = a < b )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); GenericError* gen = get(result.errors[0]); REQUIRE(gen != nullptr); - REQUIRE_EQ(gen->message, "Table M does not offer metamethod __lt"); + REQUIRE_EQ(gen->message, XorStr("Table M does not offer metamethod __lt")); } TEST_CASE_FIXTURE(BuiltinsFixture, "cannot_compare_tables_that_do_not_have_the_same_metatable") @@ -282,7 +282,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "cannot_compare_tables_that_do_not_have_the_s local d = b < a -- line 11 )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); REQUIRE_EQ((Location{{10, 18}, {10, 23}}), result.errors[0].location); @@ -305,7 +305,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "produce_the_correct_error_message_when_compa local c = a < b -- line 10 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto err = get(result.errors[0]); REQUIRE(err != nullptr); @@ -326,7 +326,7 @@ TEST_CASE_FIXTURE(Fixture, "in_nonstrict_mode_strip_nil_from_intersections_when_ local a = maybe_a_number() < maybe_a_number() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "compound_assign_basic") @@ -336,7 +336,7 @@ TEST_CASE_FIXTURE(Fixture, "compound_assign_basic") s += 20 )"); CHECK_EQ(0, result.errors.size()); - CHECK_EQ(toString(*requireType("s")), "number"); + CHECK_EQ(toString(*requireType(XorStr("s")), "number")); } TEST_CASE_FIXTURE(Fixture, "compound_assign_mismatch_op") @@ -345,7 +345,7 @@ TEST_CASE_FIXTURE(Fixture, "compound_assign_mismatch_op") local s = 10 s += true )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(result.errors[0], (TypeError{Location{{2, 13}, {2, 17}}, TypeMismatch{typeChecker.numberType, typeChecker.booleanType}})); } @@ -356,7 +356,7 @@ TEST_CASE_FIXTURE(Fixture, "compound_assign_mismatch_result") s += 10 )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ(result.errors[0], (TypeError{Location{{2, 8}, {2, 9}}, TypeMismatch{typeChecker.numberType, typeChecker.stringType}})); CHECK_EQ(result.errors[1], (TypeError{Location{{2, 8}, {2, 15}}, TypeMismatch{typeChecker.stringType, typeChecker.numberType}})); } @@ -398,7 +398,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "compound_assign_mismatch_metatable") local v2: V2 = setmetatable({ x = 3, y = 4 }, VMT) v1 %= v2 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); CHECK_EQ(*tm->wantedType, *requireType("v2")); @@ -413,7 +413,7 @@ function g() return 2; end (f or g)() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "CallAndOrOfFunctions") @@ -425,7 +425,7 @@ local x = false (x and f or g)() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_unary_minus") @@ -452,13 +452,13 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_unary_minus") local c = -bar -- disallowed )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("string", toString(requireType("a"))); CHECK_EQ("number", toString(requireType("b"))); GenericError* gen = get(result.errors[0]); - REQUIRE_EQ(gen->message, "Unary operator '-' not supported by type 'bar'"); + REQUIRE_EQ(gen->message, XorStr("Unary operator '-' not supported by type 'bar'")); } TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_unary_minus_error") @@ -473,13 +473,13 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_unary_minus_error") setmetatable(foo, mt) mt.__unm = function(val: boolean): string - return "test" + return XorStr("test") end local a = -foo )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("string", toString(requireType("a"))); @@ -490,6 +490,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_unary_minus_error") TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_unary_len_error") { + ScopedFastFlag sff("lluzCheckLenMT", true); + CheckResult result = check(R"( --!strict local foo = { @@ -499,13 +501,13 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "typecheck_unary_len_error") setmetatable(foo, mt) mt.__len = function(val: any): string - return "test" + return XorStr("test") end local a = #foo )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("number", toString(requireType("a"))); @@ -521,7 +523,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "unary_not_is_boolean") local c = not (math.random() > 0.5 and "string" or 7) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); REQUIRE_EQ("boolean", toString(requireType("b"))); REQUIRE_EQ("boolean", toString(requireType("c"))); } @@ -555,7 +557,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "disallow_string_and_types_without_metatables local d = bar + foo -- not allowed )"); - LUAU_REQUIRE_ERROR_COUNT(3, result); + lluz_REQUIRE_ERROR_COUNT(3, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE_EQ(*tm->wantedType, *typeChecker.numberType); @@ -566,7 +568,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "disallow_string_and_types_without_metatables CHECK_EQ(*tm2->givenType, *requireType("foo")); GenericError* gen2 = get(result.errors[1]); - REQUIRE_EQ(gen2->message, "Binary operator '+' not supported by types 'foo' and 'number'"); + REQUIRE_EQ(gen2->message, XorStr("Binary operator '+' not supported by types 'foo' and 'number'")); } // CLI-29033 @@ -579,7 +581,7 @@ TEST_CASE_FIXTURE(Fixture, "unknown_type_in_comparison") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "concat_op_on_free_lhs_and_string_rhs") @@ -590,7 +592,7 @@ TEST_CASE_FIXTURE(Fixture, "concat_op_on_free_lhs_and_string_rhs") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); REQUIRE(get(result.errors[0])); } @@ -598,11 +600,11 @@ TEST_CASE_FIXTURE(Fixture, "concat_op_on_string_lhs_and_free_rhs") { CheckResult result = check(R"( local function f(x) - return "foo" .. x + return XorStr("foo") .. x end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("(string) -> string", toString(requireType("f"))); } @@ -621,7 +623,7 @@ TEST_CASE_FIXTURE(Fixture, "strict_binary_op_where_lhs_unknown") src += "end"; CheckResult result = check(src); - LUAU_REQUIRE_ERROR_COUNT(ops.size(), result); + lluz_REQUIRE_ERROR_COUNT(ops.size(), result); CHECK_EQ("Unknown type used in + operation; consider adding a type annotation to 'a'", toString(result.errors[0])); } @@ -636,7 +638,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "and_binexps_dont_unify") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "error_on_invalid_operand_types_to_relational_operators") @@ -647,7 +649,7 @@ TEST_CASE_FIXTURE(Fixture, "error_on_invalid_operand_types_to_relational_operato local foo = a < b )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); GenericError* ge = get(result.errors[0]); REQUIRE(ge); @@ -662,7 +664,7 @@ TEST_CASE_FIXTURE(Fixture, "error_on_invalid_operand_types_to_relational_operato local foo = a < b )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); GenericError* ge = get(result.errors[0]); REQUIRE(ge); @@ -677,7 +679,7 @@ TEST_CASE_FIXTURE(Fixture, "cli_38355_recursive_union") _ += _ and _ or _ and _ or _ and _ )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type contains a self-recursive construct that cannot be resolved", toString(result.errors[0])); } @@ -691,8 +693,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "UnknownGlobalCompoundAssign") print(a) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Unknown global 'a'"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Unknown global 'a'")); } // In strict mode we no longer generate two errors from lhs @@ -703,8 +705,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "UnknownGlobalCompoundAssign") print(a) )"); - LUAU_REQUIRE_ERRORS(result); - CHECK_EQ(toString(result.errors[0]), "Unknown global 'a'"); + lluz_REQUIRE_ERRORS(result); + CHECK_EQ(toString(result.errors[0]), XorStr("Unknown global 'a'")); } // In non-strict mode, compound assignment is not a definition, it's a modification @@ -715,8 +717,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "UnknownGlobalCompoundAssign") print(a) )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); - CHECK_EQ(toString(result.errors[0]), "Unknown global 'a'"); + lluz_REQUIRE_ERROR_COUNT(2, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Unknown global 'a'")); } } @@ -728,7 +730,7 @@ local a: number? = nil local b: number = a or 1 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "strip_nil_from_lhs_or_operator2") @@ -739,7 +741,7 @@ local a: number? = nil local b: number = a or 1 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "dont_strip_nil_from_rhs_or_operator") @@ -750,7 +752,7 @@ local a: number? = nil local b: number = 1 or a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -776,7 +778,7 @@ TEST_CASE_FIXTURE(Fixture, "operator_eq_verifies_types_do_intersect") return f )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "operator_eq_operands_are_not_subtypes_of_each_other_but_has_overlap") @@ -789,7 +791,7 @@ TEST_CASE_FIXTURE(Fixture, "operator_eq_operands_are_not_subtypes_of_each_other_ // This doesn't produce any errors but for the wrong reasons. // This unit test serves as a reminder to not try and unify the operands on `==`/`~=`. - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "refine_and_or") @@ -799,7 +801,7 @@ TEST_CASE_FIXTURE(Fixture, "refine_and_or") local u = t and t.x or 5 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireType("u"))); } @@ -812,8 +814,8 @@ TEST_CASE_FIXTURE(Fixture, "infer_any_in_all_modes_when_lhs_is_unknown") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Unknown type used in + operation; consider adding a type annotation to 'x'"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Unknown type used in + operation; consider adding a type annotation to 'x'")); result = check(Mode::Nonstrict, R"( local function f(x, y) @@ -821,7 +823,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_any_in_all_modes_when_lhs_is_unknown") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // When type inference is unified, we could add an assertion that // the strict and nonstrict types are equivalent. This isn't actually @@ -842,7 +844,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "equality_operations_succeed_if_any_union_bra local v4 = y ~= x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CheckResult result2 = check(R"( local mm1 = { @@ -865,30 +867,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "equality_operations_succeed_if_any_union_bra 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_CASE_FIXTURE(BuiltinsFixture, "expected_types_through_binary_and") -{ - ScopedFastFlag sff{"LuauBinaryNeedsExpectedTypesToo", true}; - - CheckResult result = check(R"( - local x: "a" | "b" | boolean = math.random() > 0.5 and "a" - )"); - - LUAU_REQUIRE_NO_ERRORS(result); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "expected_types_through_binary_or") -{ - ScopedFastFlag sff{"LuauBinaryNeedsExpectedTypesToo", true}; - - CheckResult result = check(R"( - local x: "a" | "b" | boolean = math.random() > 0.5 or "b" - )"); - - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_ERROR_COUNT(1, result2); + CHECK(toString(result2.errors[0]) == XorStr("Types Foo and Bar cannot be compared with == because they do not have the same metatable")); } TEST_SUITE_END(); diff --git a/tests/TypeInfer.primitives.test.cpp b/tests/TypeInfer.primitives.test.cpp index a06fd749..48125e12 100644 --- a/tests/TypeInfer.primitives.test.cpp +++ b/tests/TypeInfer.primitives.test.cpp @@ -1,27 +1,24 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/AstQuery.h" -#include "Luau/BuiltinDefinitions.h" -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" -#include "Luau/VisitTypeVar.h" +#include "lluz/AstQuery.h" +#include "lluz/BuiltinDefinitions.h" +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" +#include "lluz/VisitTypeVar.h" #include "Fixture.h" #include "doctest.h" -LUAU_FASTFLAG(LuauDeduceFindMatchReturnTypes) -LUAU_FASTFLAG(LuauSpecialTypesAsterisked) +using namespace lluz; -using namespace Luau; - -TEST_SUITE_BEGIN("TypeInferPrimitives"); +TEST_SUITE_BEGIN(XorStr("TypeInferPrimitives")); TEST_CASE_FIXTURE(Fixture, "cannot_call_primitives") { - CheckResult result = check("local foo = 5 foo()"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("local foo = 5 foo()")); + lluz_REQUIRE_ERROR_COUNT(1, result); REQUIRE(get(result.errors[0]) != nullptr); } @@ -33,7 +30,7 @@ TEST_CASE_FIXTURE(Fixture, "string_length") local t = #s )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireType("t"))); } @@ -44,16 +41,13 @@ TEST_CASE_FIXTURE(Fixture, "string_index") local t = s[4] )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); NotATable* nat = get(result.errors[0]); REQUIRE(nat); CHECK_EQ("string", toString(nat->ty)); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(requireType("t"))); - else - CHECK_EQ("", toString(requireType("t"))); + CHECK_EQ("*unknown*", toString(requireType("t"))); } TEST_CASE_FIXTURE(Fixture, "string_method") @@ -86,10 +80,7 @@ TEST_CASE_FIXTURE(Fixture, "string_function_other") )"); CHECK_EQ(0, result.errors.size()); - if (FFlag::LuauDeduceFindMatchReturnTypes) - CHECK_EQ(toString(requireType("p")), "string"); - else - CHECK_EQ(toString(requireType("p")), "string?"); + CHECK_EQ(toString(requireType(XorStr("p")), "string?")); } TEST_CASE_FIXTURE(Fixture, "CheckMethodsOfNumber") @@ -101,9 +92,9 @@ function x:y(z: number) end )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); - CHECK_EQ(toString(result.errors[0]), "Cannot add method to non-table type 'number'"); - CHECK_EQ(toString(result.errors[1]), "Type 'number' could not be converted into 'string'"); + lluz_REQUIRE_ERROR_COUNT(2, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Cannot add method to non-table type 'number'")); + CHECK_EQ(toString(result.errors[1]), XorStr("Type 'number' could not be converted into 'string'")); } TEST_SUITE_END(); diff --git a/tests/TypeInfer.provisional.test.cpp b/tests/TypeInfer.provisional.test.cpp index 34afd560..948b9541 100644 --- a/tests/TypeInfer.provisional.test.cpp +++ b/tests/TypeInfer.provisional.test.cpp @@ -1,5 +1,5 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/TypeInfer.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/TypeInfer.h" #include "Fixture.h" @@ -7,11 +7,11 @@ #include -LUAU_FASTFLAG(LuauLowerBoundsCalculation) +lluz_FASTFLAG(LluLowerBoundsCalculation) -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("ProvisionalTests"); +TEST_SUITE_BEGIN(XorStr("ProvisionalTests")); // These tests check for behavior that differs from the final behavior we'd // like to have. They serve to document the current state of the typechecker. @@ -31,7 +31,7 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_inference_incomplete") { const std::string code = R"( function f(a) - if type(a) == "boolean" then + if type(a) == XorStr("boolean") then local a1 = a elseif a.fn() then local a2 = a @@ -55,7 +55,7 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_inference_incomplete") TEST_CASE_FIXTURE(BuiltinsFixture, "xpcall_returns_what_f_returns") { 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 XorStr("foo"), 1 end) )"; const std::string expected = R"( @@ -73,7 +73,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "xpcall_returns_what_f_returns") TEST_CASE_FIXTURE(Fixture, "weirditer_should_not_loop_forever") { // this flag is intentionally here doing nothing to demonstrate that we exit early via case detection - ScopedFastInt sfis{"LuauTypeInferTypePackLoopLimit", 50}; + ScopedFastInt sfis{"lluzTypeInferTypePackLoopLimit", 50}; CheckResult result = check(R"( local function toVertexList(vertices, x, y, ...) @@ -83,11 +83,11 @@ TEST_CASE_FIXTURE(Fixture, "weirditer_should_not_loop_forever") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } // This should also generate an OccursCheckFailed error too, like the above toVertexList snippet. -// at least up until we can get Luau to recognize this code as a valid function that iterates over a list of values in the pack. +// at least up until we can get lluz to recognize this code as a valid function that iterates over a list of values in the pack. TEST_CASE_FIXTURE(Fixture, "it_should_be_agnostic_of_actual_size") { CheckResult result = check(R"( @@ -99,7 +99,7 @@ TEST_CASE_FIXTURE(Fixture, "it_should_be_agnostic_of_actual_size") f(3, 2, 1, 0) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } // Ideally setmetatable's second argument would be an optional free table. @@ -113,7 +113,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "setmetatable_constrains_free_type_into_free_ b = 1 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -121,7 +121,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "setmetatable_constrains_free_type_into_free_ CHECK_EQ("number", toString(tm->givenType)); } -// Luau currently doesn't yet know how to allow assignments when the binding was refined. +// lluz currently doesn't yet know how to allow assignments when the binding was refined. TEST_CASE_FIXTURE(Fixture, "while_body_are_also_refined") { CheckResult result = check(R"( @@ -137,7 +137,7 @@ TEST_CASE_FIXTURE(Fixture, "while_body_are_also_refined") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'Node?' could not be converted into 'Node'", toString(result.errors[0])); } @@ -157,7 +157,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "error_on_eq_metamethod_returning_a_type_othe local a = tab2 == tab )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); GenericError* ge = get(result.errors[0]); REQUIRE(ge); @@ -175,7 +175,7 @@ TEST_CASE_FIXTURE(Fixture, "operator_eq_completely_incompatible") local r2 = b == a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } // Belongs in TypeInfer.refinements.test.cpp. @@ -192,13 +192,13 @@ TEST_CASE_FIXTURE(Fixture, "lvalue_equals_another_lvalue_with_no_overlap") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireTypeAtPosition({3, 33})), "string"); // a == b - CHECK_EQ(toString(requireTypeAtPosition({3, 36})), "boolean?"); // a == b + CHECK_EQ(toString(requireTypeAtPosition({3, 33})), XorStr("string")); // a == b + CHECK_EQ(toString(requireTypeAtPosition({3, 36})), XorStr("boolean?")); // a == b - CHECK_EQ(toString(requireTypeAtPosition({5, 33})), "string"); // a ~= b - CHECK_EQ(toString(requireTypeAtPosition({5, 36})), "boolean?"); // a ~= b + CHECK_EQ(toString(requireTypeAtPosition({5, 33})), XorStr("string")); // a ~= b + CHECK_EQ(toString(requireTypeAtPosition({5, 36})), XorStr("boolean?")); // a ~= b } // Also belongs in TypeInfer.refinements.test.cpp. @@ -217,7 +217,7 @@ TEST_CASE_FIXTURE(Fixture, "discriminate_from_x_not_equal_to_nil") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("{| x: string, y: number |}", toString(requireTypeAtPosition({5, 28}))); @@ -225,10 +225,10 @@ TEST_CASE_FIXTURE(Fixture, "discriminate_from_x_not_equal_to_nil") CHECK_EQ("{| x: nil, y: nil |} | {| x: string, y: number |}", toString(requireTypeAtPosition({7, 28}))); } -TEST_CASE_FIXTURE(BuiltinsFixture, "bail_early_if_unification_is_too_complicated" * doctest::timeout(0.5)) +TEST_CASE_FIXTURE(Fixture, "bail_early_if_unification_is_too_complicated" * doctest::timeout(0.5)) { - ScopedFastInt sffi{"LuauTarjanChildLimit", 1}; - ScopedFastInt sffi2{"LuauTypeInferIterationLimit", 1}; + ScopedFastInt sffi{"lluzTarjanChildLimit", 1}; + ScopedFastInt sffi2{"lluzTypeInferIterationLimit", 1}; CheckResult result = check(R"LUA( local Result @@ -259,7 +259,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "bail_early_if_unification_is_too_complicated if (it == result.errors.end()) { dumpErrors(result); - FAIL("Expected a UnificationTooComplex error"); + FAIL(XorStr("Expected a UnificationTooComplex error")); } } @@ -284,14 +284,14 @@ TEST_CASE_FIXTURE(Fixture, "invariant_table_properties_means_instantiating_table // TODO: this should error! // This should be fixed by replacing generic tables by generics with type bounds. - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } -// FIXME: Move this test to another source file when removing FFlag::LuauLowerBoundsCalculation +// FIXME: Move this test to another source file when removing FFlag::LluLowerBoundsCalculation TEST_CASE_FIXTURE(Fixture, "do_not_ice_when_trying_to_pick_first_of_generic_type_pack") { ScopedFastFlag sff[]{ - {"LuauReturnAnyInsteadOfICE", true}, + {"lluzReturnAnyInsteadOfICE", true}, }; // In-place quantification causes these types to have the wrong types but only because of nasty interaction with prototyping. @@ -315,9 +315,9 @@ TEST_CASE_FIXTURE(Fixture, "do_not_ice_when_trying_to_pick_first_of_generic_type local x = (f()) -- should error: no return values to assign from the call to f )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - if (FFlag::LuauLowerBoundsCalculation) + if (FFlag::LluLowerBoundsCalculation) { CHECK_EQ("() -> ()", toString(requireType("f"))); CHECK_EQ("() -> ()", toString(requireType("g"))); @@ -340,27 +340,13 @@ TEST_CASE_FIXTURE(Fixture, "specialization_binds_with_prototypes_too_early") local s2s: (string) -> string = id )"); - LUAU_REQUIRE_ERRORS(result); // Should not have any errors. -} - -TEST_CASE_FIXTURE(Fixture, "weird_fail_to_unify_type_pack") -{ - ScopedFastFlag sff[] = { - {"LuauLowerBoundsCalculation", false}, - }; - - CheckResult result = check(R"( - local function f() return end - local g = function() return f() end - )"); - - LUAU_REQUIRE_ERRORS(result); // Should not have any errors. + lluz_REQUIRE_ERRORS(result); // Should not have any errors. } TEST_CASE_FIXTURE(Fixture, "weird_fail_to_unify_variadic_pack") { ScopedFastFlag sff[] = { - {"LuauLowerBoundsCalculation", false}, + {"lluzLowerBoundsCalculation", false}, }; CheckResult result = check(R"( @@ -369,13 +355,13 @@ TEST_CASE_FIXTURE(Fixture, "weird_fail_to_unify_variadic_pack") local g = function(...) return f(...) end )"); - LUAU_REQUIRE_ERRORS(result); // Should not have any errors. + lluz_REQUIRE_ERRORS(result); // Should not have any errors. } TEST_CASE_FIXTURE(Fixture, "lower_bounds_calculation_is_too_permissive_with_overloaded_higher_order_functions") { ScopedFastFlag sff[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( @@ -385,7 +371,7 @@ TEST_CASE_FIXTURE(Fixture, "lower_bounds_calculation_is_too_permissive_with_over end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // We incorrectly infer that the argument to foo could be called with (number, number) or (string, string) // even though that is strictly more permissive than the actual source text shows. @@ -396,11 +382,11 @@ TEST_CASE_FIXTURE(Fixture, "lower_bounds_calculation_is_too_permissive_with_over TEST_CASE_FIXTURE(Fixture, "normalization_fails_on_certain_kinds_of_cyclic_tables") { #if defined(_DEBUG) || defined(_NOOPT) - ScopedFastInt sfi("LuauNormalizeIterationLimit", 500); + ScopedFastInt sfi("lluzNormalizeIterationLimit", 500); #endif ScopedFastFlag flags[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; // We use a function and inferred parameter types to prevent intermediate normalizations from being performed. @@ -417,7 +403,7 @@ TEST_CASE_FIXTURE(Fixture, "normalization_fails_on_certain_kinds_of_cyclic_table end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK(nullptr != get(result.errors[0])); } @@ -430,9 +416,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "pcall_returns_at_least_two_value_but_functio local ok, res = pcall(f) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Function only returns 1 value. 2 are required here", toString(result.errors[0])); - // LUAU_REQUIRE_NO_ERRORS(result); + // lluz_REQUIRE_NO_ERRORS(result); // CHECK_EQ("boolean", toString(requireType("ok"))); // CHECK_EQ("any", toString(requireType("res"))); } @@ -452,7 +438,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "choose_the_right_overload_for_pcall") local ok, res = pcall(f) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("boolean", toString(requireType("ok"))); CHECK_EQ("number", toString(requireType("res"))); // CHECK_EQ("any", toString(requireType("res"))); @@ -473,7 +459,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "function_returns_many_things_but_first_of_it local ok, res, s, b = pcall(f) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("boolean", toString(requireType("ok"))); CHECK_EQ("number", toString(requireType("res"))); // CHECK_EQ("any", toString(requireType("res"))); @@ -484,9 +470,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "function_returns_many_things_but_first_of_it TEST_CASE_FIXTURE(Fixture, "constrained_is_level_dependent") { ScopedFastFlag sff[]{ - {"LuauLowerBoundsCalculation", true}, - {"LuauNormalizeFlagIsConservative", true}, - {"LuauQuantifyConstrained", true}, + {"lluzLowerBoundsCalculation", true}, + {"lluzNormalizeFlagIsConservative", true}, + {"lluzQuantifyConstrained", true}, }; CheckResult result = check(R"( @@ -508,25 +494,14 @@ TEST_CASE_FIXTURE(Fixture, "constrained_is_level_dependent") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); // TODO: We're missing generics b... CHECK_EQ("(t1) -> {| [t1]: boolean |} where t1 = t2 ; t2 = {+ m1: (t1) -> (a...), m2: (t2) -> (b...) +}", toString(requireType("f"))); } -TEST_CASE_FIXTURE(Fixture, "free_is_not_bound_to_any") -{ - CheckResult result = check(R"( - local function foo(f: (any) -> (), x) - f(x) - end - )"); - - CHECK_EQ("((any) -> (), any) -> ()", toString(requireType("foo"))); -} - TEST_CASE_FIXTURE(BuiltinsFixture, "greedy_inference_with_shared_self_triggers_function_with_no_returns") { - ScopedFastFlag sff{"DebugLuauSharedSelf", true}; + ScopedFastFlag sff{"DebuglluzSharedSelf", true}; CheckResult result = check(R"( local T = {} @@ -542,7 +517,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "greedy_inference_with_shared_self_triggers_f end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Not all codepaths in this function return 'self, a...'.", toString(result.errors[0])); } diff --git a/tests/TypeInfer.refinements.test.cpp b/tests/TypeInfer.refinements.test.cpp index 8a1cadcf..7aa7bae0 100644 --- a/tests/TypeInfer.refinements.test.cpp +++ b/tests/TypeInfer.refinements.test.cpp @@ -1,16 +1,15 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Normalize.h" -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Normalize.h" +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" #include "Fixture.h" #include "doctest.h" -LUAU_FASTFLAG(LuauLowerBoundsCalculation) -LUAU_FASTFLAG(LuauSpecialTypesAsterisked) +lluz_FASTFLAG(LluLowerBoundsCalculation) -using namespace Luau; +using namespace lluz; namespace { @@ -20,8 +19,8 @@ std::optional> magicFunctionInstanceIsA( if (expr.args.size != 1) return std::nullopt; - auto index = expr.func->as(); - auto str = expr.args.data[0]->as(); + auto index = expr.func->as(); + auto str = expr.args.data[0]->as(); if (!index || !str) return std::nullopt; @@ -86,7 +85,7 @@ struct RefinementClassFixture : Fixture }; } // namespace -TEST_SUITE_BEGIN("RefinementTest"); +TEST_SUITE_BEGIN(XorStr("RefinementTest")); TEST_CASE_FIXTURE(Fixture, "is_truthy_constraint") { @@ -100,7 +99,7 @@ TEST_CASE_FIXTURE(Fixture, "is_truthy_constraint") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("string", toString(requireTypeAtPosition({3, 26}))); CHECK_EQ("nil", toString(requireTypeAtPosition({5, 26}))); @@ -118,7 +117,7 @@ TEST_CASE_FIXTURE(Fixture, "invert_is_truthy_constraint") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("nil", toString(requireTypeAtPosition({3, 26}))); CHECK_EQ("string", toString(requireTypeAtPosition({5, 26}))); @@ -136,7 +135,7 @@ TEST_CASE_FIXTURE(Fixture, "parenthesized_expressions_are_followed_through") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("nil", toString(requireTypeAtPosition({3, 26}))); CHECK_EQ("string", toString(requireTypeAtPosition({5, 26}))); @@ -156,7 +155,7 @@ TEST_CASE_FIXTURE(Fixture, "and_constraint") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("string", toString(requireTypeAtPosition({3, 26}))); CHECK_EQ("number", toString(requireTypeAtPosition({4, 26}))); @@ -179,7 +178,7 @@ TEST_CASE_FIXTURE(Fixture, "not_and_constraint") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("string?", toString(requireTypeAtPosition({3, 26}))); CHECK_EQ("number?", toString(requireTypeAtPosition({4, 26}))); @@ -202,7 +201,7 @@ TEST_CASE_FIXTURE(Fixture, "or_predicate_with_truthy_predicates") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("string?", toString(requireTypeAtPosition({3, 26}))); CHECK_EQ("number?", toString(requireTypeAtPosition({4, 26}))); @@ -222,7 +221,7 @@ TEST_CASE_FIXTURE(Fixture, "type_assertion_expr_carry_its_constraints") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireTypeAtPosition({3, 26}))); CHECK_EQ("string", toString(requireTypeAtPosition({4, 26}))); @@ -232,13 +231,13 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_in_if_condition_position") { CheckResult result = check(R"( function f(s: any) - if type(s) == "number" then + if type(s) == XorStr("number") then local n = s end end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireTypeAtPosition({3, 26}))); } @@ -247,11 +246,11 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "typeguard_in_assert_position") { CheckResult result = check(R"( local a - assert(type(a) == "number") + assert(type(a) == XorStr("number")) local b = a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); REQUIRE_EQ("number", toString(requireType("b"))); } @@ -264,17 +263,17 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_only_look_up_types_from_global_scope") type string = number local foo: string = 1 - if type(foo) == "string" then + if type(foo) == XorStr("string") then local bar: ActuallyString = foo local baz: boolean = foo end end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ("never", toString(requireTypeAtPosition({8, 44}))); - CHECK_EQ("never", toString(requireTypeAtPosition({9, 38}))); + CHECK_EQ("*unknown*", toString(requireTypeAtPosition({8, 44}))); + CHECK_EQ("*unknown*", toString(requireTypeAtPosition({9, 38}))); } TEST_CASE_FIXTURE(Fixture, "call_a_more_specific_function_using_typeguard") @@ -285,19 +284,19 @@ TEST_CASE_FIXTURE(Fixture, "call_a_more_specific_function_using_typeguard") end local function g(x: any) - if type(x) == "string" then + if type(x) == XorStr("string") then f(x) end end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'string' could not be converted into 'number'", toString(result.errors[0])); } 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 lluz is intelligent enough. // For instance, getting a value out of the indexer and checking whether the value exists is not an error. CheckResult result = check(R"( local t: {string} = {"a", "b", "c"} @@ -309,7 +308,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "impossible_type_narrow_is_not_an_error") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "truthy_constraint_on_properties") @@ -324,7 +323,7 @@ TEST_CASE_FIXTURE(Fixture, "truthy_constraint_on_properties") local bar = t.x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number?", toString(requireType("bar"))); } @@ -338,7 +337,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "index_on_a_refined_property") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "assert_non_binary_expressions_actually_resolve_constraints") @@ -349,7 +348,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "assert_non_binary_expressions_actually_resol local bar: string = foo )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "assign_table_with_refined_property_with_a_similar_type_is_illegal") @@ -362,7 +361,7 @@ TEST_CASE_FIXTURE(Fixture, "assign_table_with_refined_property_with_a_similar_ty end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(R"(Type '{| x: number? |}' could not be converted into '{| x: number |}' caused by: Property 'x' is not compatible. Type 'number?' could not be converted into 'number')", @@ -381,13 +380,13 @@ TEST_CASE_FIXTURE(Fixture, "lvalue_is_equal_to_another_lvalue") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireTypeAtPosition({3, 33})), "(number | string)?"); // a == b - CHECK_EQ(toString(requireTypeAtPosition({3, 36})), "boolean?"); // a == b + CHECK_EQ(toString(requireTypeAtPosition({3, 33})), XorStr("(number | string)?")); // a == b + CHECK_EQ(toString(requireTypeAtPosition({3, 36})), XorStr("boolean?")); // a == b - CHECK_EQ(toString(requireTypeAtPosition({5, 33})), "(number | string)?"); // a ~= b - CHECK_EQ(toString(requireTypeAtPosition({5, 36})), "boolean?"); // a ~= b + CHECK_EQ(toString(requireTypeAtPosition({5, 33})), XorStr("(number | string)?")); // a ~= b + CHECK_EQ(toString(requireTypeAtPosition({5, 36})), XorStr("boolean?")); // a ~= b } TEST_CASE_FIXTURE(Fixture, "lvalue_is_equal_to_a_term") @@ -402,10 +401,10 @@ TEST_CASE_FIXTURE(Fixture, "lvalue_is_equal_to_a_term") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireTypeAtPosition({3, 28})), "(number | string)?"); // a == 1 - CHECK_EQ(toString(requireTypeAtPosition({5, 28})), "(number | string)?"); // a ~= 1 + CHECK_EQ(toString(requireTypeAtPosition({3, 28})), XorStr("(number | string)?")); // a == 1 + CHECK_EQ(toString(requireTypeAtPosition({5, 28})), XorStr("(number | string)?")); // a ~= 1 } TEST_CASE_FIXTURE(Fixture, "term_is_equal_to_an_lvalue") @@ -420,10 +419,10 @@ TEST_CASE_FIXTURE(Fixture, "term_is_equal_to_an_lvalue") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireTypeAtPosition({3, 28})), R"("hello")"); // a == "hello" - CHECK_EQ(toString(requireTypeAtPosition({5, 28})), "(number | string)?"); // a ~= "hello" + CHECK_EQ(toString(requireTypeAtPosition({3, 28})), RXorStr("("hello")")); // a == XorStr("hello") + CHECK_EQ(toString(requireTypeAtPosition({5, 28})), XorStr("(number | string)?")); // a ~= "hello" } TEST_CASE_FIXTURE(Fixture, "lvalue_is_not_nil") @@ -438,10 +437,10 @@ TEST_CASE_FIXTURE(Fixture, "lvalue_is_not_nil") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireTypeAtPosition({3, 28})), "number | string"); // a ~= nil - CHECK_EQ(toString(requireTypeAtPosition({5, 28})), "(number | string)?"); // a == nil + CHECK_EQ(toString(requireTypeAtPosition({3, 28})), XorStr("number | string")); // a ~= nil + CHECK_EQ(toString(requireTypeAtPosition({5, 28})), XorStr("(number | string)?")); // a == nil } TEST_CASE_FIXTURE(Fixture, "free_type_is_equal_to_an_lvalue") @@ -454,10 +453,10 @@ TEST_CASE_FIXTURE(Fixture, "free_type_is_equal_to_an_lvalue") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireTypeAtPosition({3, 33})), "a"); // a == b - CHECK_EQ(toString(requireTypeAtPosition({3, 36})), "string?"); // a == b + CHECK_EQ(toString(requireTypeAtPosition({3, 33})), XorStr("a")); // a == b + CHECK_EQ(toString(requireTypeAtPosition({3, 36})), XorStr("string?")); // a == b } TEST_CASE_FIXTURE(Fixture, "unknown_lvalue_is_not_synonymous_with_other_on_not_equal") @@ -470,10 +469,10 @@ TEST_CASE_FIXTURE(Fixture, "unknown_lvalue_is_not_synonymous_with_other_on_not_e end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireTypeAtPosition({3, 33})), "any"); // a ~= b - CHECK_EQ(toString(requireTypeAtPosition({3, 36})), "{| x: number |}?"); // a ~= b + CHECK_EQ(toString(requireTypeAtPosition({3, 33})), XorStr("any")); // a ~= b + CHECK_EQ(toString(requireTypeAtPosition({3, 36})), XorStr("{| x: number |}?")); // a ~= b } TEST_CASE_FIXTURE(Fixture, "string_not_equal_to_string_or_nil") @@ -490,13 +489,13 @@ TEST_CASE_FIXTURE(Fixture, "string_not_equal_to_string_or_nil") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireTypeAtPosition({6, 29})), "string"); // a ~= b - CHECK_EQ(toString(requireTypeAtPosition({6, 32})), "string?"); // a ~= b + CHECK_EQ(toString(requireTypeAtPosition({6, 29})), XorStr("string")); // a ~= b + CHECK_EQ(toString(requireTypeAtPosition({6, 32})), XorStr("string?")); // a ~= b - CHECK_EQ(toString(requireTypeAtPosition({8, 29})), "string"); // a == b - CHECK_EQ(toString(requireTypeAtPosition({8, 32})), "string?"); // a == b + CHECK_EQ(toString(requireTypeAtPosition({8, 29})), XorStr("string")); // a == b + CHECK_EQ(toString(requireTypeAtPosition({8, 32})), XorStr("string?")); // a == b } TEST_CASE_FIXTURE(Fixture, "narrow_property_of_a_bounded_variable") @@ -512,25 +511,22 @@ TEST_CASE_FIXTURE(Fixture, "narrow_property_of_a_bounded_variable") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "type_narrow_to_vector") { CheckResult result = check(R"( local function f(x) - if type(x) == "vector" then + if type(x) == XorStr("vector") then local foo = x end end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(requireTypeAtPosition({3, 28}))); - else - CHECK_EQ("", toString(requireTypeAtPosition({3, 28}))); + CHECK_EQ("*unknown*", toString(requireTypeAtPosition({3, 28}))); } TEST_CASE_FIXTURE(Fixture, "nonoptional_type_can_narrow_to_nil_if_sense_is_true") @@ -538,7 +534,7 @@ TEST_CASE_FIXTURE(Fixture, "nonoptional_type_can_narrow_to_nil_if_sense_is_true" CheckResult result = check(R"( local t = {"hello"} local v = t[2] - if type(v) == "nil" then + if type(v) == XorStr("nil") then local foo = v else local foo = v @@ -551,12 +547,12 @@ TEST_CASE_FIXTURE(Fixture, "nonoptional_type_can_narrow_to_nil_if_sense_is_true" end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ("nil", toString(requireTypeAtPosition({4, 24}))); // type(v) == "nil" + CHECK_EQ("nil", toString(requireTypeAtPosition({4, 24}))); // type(v) == XorStr("nil") CHECK_EQ("string", toString(requireTypeAtPosition({6, 24}))); // type(v) ~= "nil" - CHECK_EQ("nil", toString(requireTypeAtPosition({10, 24}))); // equivalent to type(v) == "nil" + CHECK_EQ("nil", toString(requireTypeAtPosition({10, 24}))); // equivalent to type(v) == XorStr("nil") CHECK_EQ("string", toString(requireTypeAtPosition({12, 24}))); // equivalent to type(v) ~= "nil" } @@ -572,17 +568,17 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_not_to_be_string") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("boolean | number", toString(requireTypeAtPosition({3, 28}))); // type(x) ~= "string" - CHECK_EQ("string", toString(requireTypeAtPosition({5, 28}))); // type(x) == "string" + CHECK_EQ("string", toString(requireTypeAtPosition({5, 28}))); // type(x) == XorStr("string") } TEST_CASE_FIXTURE(Fixture, "typeguard_narrows_for_table") { CheckResult result = check(R"( local function f(x: string | {x: number} | {y: boolean}) - if type(x) == "table" then + if type(x) == XorStr("table") then local foo = x else local foo = x @@ -590,9 +586,9 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_narrows_for_table") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ("{| x: number |} | {| y: boolean |}", toString(requireTypeAtPosition({3, 28}))); // type(x) == "table" + CHECK_EQ("{| x: number |} | {| y: boolean |}", toString(requireTypeAtPosition({3, 28}))); // type(x) == XorStr("table") CHECK_EQ("string", toString(requireTypeAtPosition({5, 28}))); // type(x) ~= "table" } @@ -600,7 +596,7 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_narrows_for_functions") { CheckResult result = check(R"( local function weird(x: string | ((number) -> string)) - if type(x) == "function" then + if type(x) == XorStr("function") then local foo = x else local foo = x @@ -608,9 +604,9 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_narrows_for_functions") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ("(number) -> string", toString(requireTypeAtPosition({3, 28}))); // type(x) == "function" + CHECK_EQ("(number) -> string", toString(requireTypeAtPosition({3, 28}))); // type(x) == XorStr("function") CHECK_EQ("string", toString(requireTypeAtPosition({5, 28}))); // type(x) ~= "function" } @@ -619,7 +615,7 @@ TEST_CASE_FIXTURE(Fixture, "type_guard_can_filter_for_intersection_of_tables") CheckResult result = check(R"( type XYCoord = {x: number} & {y: number} local function f(t: XYCoord?) - if type(t) == "table" then + if type(t) == XorStr("table") then local foo = t else local foo = t @@ -627,9 +623,9 @@ TEST_CASE_FIXTURE(Fixture, "type_guard_can_filter_for_intersection_of_tables") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - if (FFlag::LuauLowerBoundsCalculation) + if (FFlag::LluLowerBoundsCalculation) CHECK_EQ("{| x: number, y: number |}", toString(requireTypeAtPosition({4, 28}))); else CHECK_EQ("{| x: number |} & {| y: number |}", toString(requireTypeAtPosition({4, 28}))); @@ -641,7 +637,7 @@ TEST_CASE_FIXTURE(Fixture, "type_guard_can_filter_for_overloaded_function") CheckResult result = check(R"( type SomeOverloadedFunction = ((number) -> string) & ((string) -> number) local function f(g: SomeOverloadedFunction?) - if type(g) == "function" then + if type(g) == XorStr("function") then local foo = g else local foo = g @@ -649,13 +645,13 @@ TEST_CASE_FIXTURE(Fixture, "type_guard_can_filter_for_overloaded_function") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("((number) -> string) & ((string) -> number)", toString(requireTypeAtPosition({4, 28}))); CHECK_EQ("nil", toString(requireTypeAtPosition({6, 28}))); } -TEST_CASE_FIXTURE(BuiltinsFixture, "type_guard_narrowed_into_nothingness") +TEST_CASE_FIXTURE(BuiltinsFixture, "type_guard_warns_on_no_overlapping_types_only_when_sense_is_true") { CheckResult result = check(R"( local function f(t: {x: number}) @@ -668,9 +664,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "type_guard_narrowed_into_nothingness") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ("never", toString(requireTypeAtPosition({3, 28}))); + CHECK_EQ("*unknown*", toString(requireTypeAtPosition({3, 28}))); } TEST_CASE_FIXTURE(Fixture, "not_a_or_not_b") @@ -684,7 +680,7 @@ TEST_CASE_FIXTURE(Fixture, "not_a_or_not_b") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number?", toString(requireTypeAtPosition({3, 28}))); CHECK_EQ("number?", toString(requireTypeAtPosition({4, 28}))); @@ -701,7 +697,7 @@ TEST_CASE_FIXTURE(Fixture, "not_a_or_not_b2") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number?", toString(requireTypeAtPosition({3, 28}))); CHECK_EQ("number?", toString(requireTypeAtPosition({4, 28}))); @@ -718,7 +714,7 @@ TEST_CASE_FIXTURE(Fixture, "not_a_and_not_b") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("nil", toString(requireTypeAtPosition({3, 28}))); CHECK_EQ("nil", toString(requireTypeAtPosition({4, 28}))); @@ -735,7 +731,7 @@ TEST_CASE_FIXTURE(Fixture, "not_a_and_not_b2") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("nil", toString(requireTypeAtPosition({3, 28}))); CHECK_EQ("nil", toString(requireTypeAtPosition({4, 28}))); @@ -745,13 +741,13 @@ TEST_CASE_FIXTURE(Fixture, "either_number_or_string") { CheckResult result = check(R"( local function f(x: any) - if type(x) == "number" or type(x) == "string" then + if type(x) == XorStr("number") or type(x) == XorStr("string") then local foo = x end end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number | string", toString(requireTypeAtPosition({3, 28}))); } @@ -766,7 +762,7 @@ TEST_CASE_FIXTURE(Fixture, "not_t_or_some_prop_of_t") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("{| x: boolean |}?", toString(requireTypeAtPosition({3, 28}))); } @@ -777,11 +773,11 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "assert_a_to_be_truthy_then_assert_a_to_be_nu local a: (number | string)? assert(a) local b = a - assert(type(a) == "number") + assert(type(a) == XorStr("number")) local c = a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number | string", toString(requireTypeAtPosition({3, 18}))); CHECK_EQ("number", toString(requireTypeAtPosition({5, 18}))); @@ -789,19 +785,19 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "assert_a_to_be_truthy_then_assert_a_to_be_nu 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 lluz::merge where zipping on two maps would produce the wrong merged result. CheckResult result = check(R"( local function f(b: string | { x: string }, a) - assert(type(a) == "string") - assert(type(b) == "string" or type(b) == "table") + assert(type(a) == XorStr("string")) + assert(type(b) == XorStr("string") or type(b) == XorStr("table")) - if type(b) == "string" then + if type(b) == XorStr("string") then local foo = b end end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("string", toString(requireTypeAtPosition({6, 28}))); } @@ -818,7 +814,7 @@ TEST_CASE_FIXTURE(Fixture, "refine_the_correct_types_opposite_of_when_a_is_not_n end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("boolean", toString(requireTypeAtPosition({3, 28}))); CHECK_EQ("number | string", toString(requireTypeAtPosition({5, 28}))); @@ -832,7 +828,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "is_truthy_constraint_ifelse_expression") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("string", toString(requireTypeAtPosition({2, 29}))); CHECK_EQ("nil", toString(requireTypeAtPosition({2, 45}))); @@ -846,7 +842,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "invert_is_truthy_constraint_ifelse_expressio end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("nil", toString(requireTypeAtPosition({2, 42}))); CHECK_EQ("string", toString(requireTypeAtPosition({2, 50}))); @@ -860,11 +856,11 @@ TEST_CASE_FIXTURE(Fixture, "type_comparison_ifelse_expression") end function f(v:any) - return if typeof(v) == "number" then v else returnOne(v) + return if typeof(v) == XorStr("number") then v else returnOne(v) end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireTypeAtPosition({6, 49}))); CHECK_EQ("any", toString(requireTypeAtPosition({6, 66}))); @@ -879,7 +875,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "correctly_lookup_a_shadowed_local_that_which print(foo:sub(1, 1)) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'number' does not have key 'sub'", toString(result.errors[0])); } @@ -890,13 +886,13 @@ TEST_CASE_FIXTURE(Fixture, "correctly_lookup_property_whose_base_was_previously_ type T = {x: string | number} local t: T? = {x = "hi"} if t then - if type(t.x) == "string" then + if type(t.x) == XorStr("string") then local foo = t.x end end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("string", toString(requireTypeAtPosition({5, 30}))); } @@ -913,7 +909,7 @@ TEST_CASE_FIXTURE(Fixture, "correctly_lookup_property_whose_base_was_previously_ end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number", toString(requireTypeAtPosition({5, 32}))); } @@ -929,12 +925,12 @@ TEST_CASE_FIXTURE(Fixture, "apply_refinements_on_astexprindexexpr_whose_subscrip end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "discriminate_from_truthiness_of_x") { - ScopedFastFlag sff{"LuauFalsyPredicateReturnsNilInstead", true}; + ScopedFastFlag sff{"lluzFalsyPredicateReturnsNilInstead", true}; CheckResult result = check(R"( type T = {tag: "missing", x: nil} | {tag: "exists", x: string} @@ -948,7 +944,7 @@ TEST_CASE_FIXTURE(Fixture, "discriminate_from_truthiness_of_x") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(R"({| tag: "exists", x: string |})", toString(requireTypeAtPosition({5, 28}))); CHECK_EQ(R"({| tag: "exists", x: string |} | {| tag: "missing", x: nil |})", toString(requireTypeAtPosition({7, 28}))); @@ -962,15 +958,15 @@ TEST_CASE_FIXTURE(Fixture, "discriminate_tag") type Animal = Cat | Dog local function f(animal: Animal) - if animal.tag == "Cat" then + if animal.tag == XorStr("Cat") then local cat: Cat = animal - elseif animal.tag == "Dog" then + elseif animal.tag == XorStr("Dog") then local dog: Dog = animal end end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("Cat", toString(requireTypeAtPosition({7, 33}))); CHECK_EQ("Dog", toString(requireTypeAtPosition({9, 33}))); @@ -984,7 +980,7 @@ TEST_CASE_FIXTURE(Fixture, "and_or_peephole_refinement") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "narrow_boolean_to_true_or_false") @@ -1002,7 +998,7 @@ TEST_CASE_FIXTURE(Fixture, "narrow_boolean_to_true_or_false") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "discriminate_on_properties_of_disjoint_tables_where_that_property_is_true_or_false") @@ -1021,7 +1017,7 @@ TEST_CASE_FIXTURE(Fixture, "discriminate_on_properties_of_disjoint_tables_where_ end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "refine_a_property_not_to_be_nil_through_an_intersection_table") @@ -1035,7 +1031,7 @@ TEST_CASE_FIXTURE(Fixture, "refine_a_property_not_to_be_nil_through_an_intersect end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(RefinementClassFixture, "discriminate_from_isa_of_x") @@ -1052,7 +1048,7 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "discriminate_from_isa_of_x") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(R"({| tag: "Part", x: Part |})", toString(requireTypeAtPosition({5, 28}))); CHECK_EQ(R"({| tag: "Folder", x: Folder |})", toString(requireTypeAtPosition({7, 28}))); @@ -1064,9 +1060,9 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "typeguard_cast_free_table_to_vector") local function f(vec) local X, Y, Z = vec.X, vec.Y, vec.Z - if type(vec) == "vector" then + if type(vec) == XorStr("vector") then local foo = vec - elseif typeof(vec) == "Instance" then + elseif typeof(vec) == XorStr("Instance") then local foo = vec else local foo = vec @@ -1074,11 +1070,11 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "typeguard_cast_free_table_to_vector") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ("Vector3", toString(requireTypeAtPosition({5, 28}))); // type(vec) == "vector" + CHECK_EQ("Vector3", toString(requireTypeAtPosition({5, 28}))); // type(vec) == XorStr("vector") - CHECK_EQ("never", toString(requireTypeAtPosition({7, 28}))); // typeof(vec) == "Instance" + CHECK_EQ("*unknown*", toString(requireTypeAtPosition({7, 28}))); // typeof(vec) == XorStr("Instance") CHECK_EQ("{+ X: a, Y: b, Z: c +}", toString(requireTypeAtPosition({9, 28}))); // type(vec) ~= "vector" and typeof(vec) ~= "Instance" } @@ -1087,7 +1083,7 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "typeguard_cast_instance_or_vector3_to { CheckResult result = check(R"( local function f(x: Instance | Vector3) - if typeof(x) == "Vector3" then + if typeof(x) == XorStr("Vector3") then local foo = x else local foo = x @@ -1095,7 +1091,7 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "typeguard_cast_instance_or_vector3_to end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("Vector3", toString(requireTypeAtPosition({3, 28}))); CHECK_EQ("Instance", toString(requireTypeAtPosition({5, 28}))); @@ -1105,7 +1101,7 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "type_narrow_for_all_the_userdata") { CheckResult result = check(R"( local function f(x: string | number | Instance | Vector3) - if type(x) == "userdata" then + if type(x) == XorStr("userdata") then local foo = x else local foo = x @@ -1113,7 +1109,7 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "type_narrow_for_all_the_userdata") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("Instance | Vector3", toString(requireTypeAtPosition({3, 28}))); CHECK_EQ("number | string", toString(requireTypeAtPosition({5, 28}))); @@ -1123,7 +1119,7 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "eliminate_subclasses_of_instance") { CheckResult result = check(R"( local function f(x: Part | Folder | string) - if typeof(x) == "Instance" then + if typeof(x) == XorStr("Instance") then local foo = x else local foo = x @@ -1131,7 +1127,7 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "eliminate_subclasses_of_instance") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("Folder | Part", toString(requireTypeAtPosition({3, 28}))); CHECK_EQ("string", toString(requireTypeAtPosition({5, 28}))); @@ -1141,7 +1137,7 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "narrow_this_large_union") { CheckResult result = check(R"( local function f(x: Part | Folder | Instance | string | Vector3 | any) - if typeof(x) == "Instance" then + if typeof(x) == XorStr("Instance") then local foo = x else local foo = x @@ -1149,7 +1145,7 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "narrow_this_large_union") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("Folder | Instance | Part", toString(requireTypeAtPosition({3, 28}))); CHECK_EQ("Vector3 | any | string", toString(requireTypeAtPosition({5, 28}))); @@ -1161,15 +1157,15 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "x_as_any_if_x_is_instance_elseif_x_is --!nonstrict local function f(x) - if typeof(x) == "Instance" and x:IsA("Folder") then + if typeof(x) == XorStr("Instance") and x:IsA("Folder") then local foo = x - elseif typeof(x) == "table" then + elseif typeof(x) == XorStr("table") then local foo = x end end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("Folder", toString(requireTypeAtPosition({5, 28}))); CHECK_EQ("any", toString(requireTypeAtPosition({7, 28}))); @@ -1187,7 +1183,7 @@ TEST_CASE_FIXTURE(RefinementClassFixture, "x_is_not_instance_or_else_not_part") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("Folder | string", toString(requireTypeAtPosition({3, 28}))); CHECK_EQ("Part", toString(requireTypeAtPosition({5, 28}))); @@ -1197,7 +1193,7 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_doesnt_leak_to_elseif") { CheckResult result = check(R"( function f(a) - if type(a) == "boolean" then + if type(a) == XorStr("boolean") then local a1 = a elseif a.fn() then local a2 = a @@ -1207,30 +1203,12 @@ TEST_CASE_FIXTURE(Fixture, "typeguard_doesnt_leak_to_elseif") end )"); - LUAU_REQUIRE_NO_ERRORS(result); -} - -TEST_CASE_FIXTURE(BuiltinsFixture, "refine_unknowns") -{ - CheckResult result = check(R"( - local function f(x: unknown) - if type(x) == "string" then - local foo = x - else - local bar = x - end - end - )"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK_EQ("string", toString(requireTypeAtPosition({3, 28}))); - CHECK_EQ("unknown", toString(requireTypeAtPosition({5, 28}))); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "falsiness_of_TruthyPredicate_narrows_into_nil") { - ScopedFastFlag sff{"LuauFalsyPredicateReturnsNilInstead", true}; + ScopedFastFlag sff{"lluzFalsyPredicateReturnsNilInstead", true}; CheckResult result = check(R"( local function f(t: {number}) @@ -1243,25 +1221,10 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "falsiness_of_TruthyPredicate_narrows_into_ni end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("nil", toString(requireTypeAtPosition({4, 28}))); CHECK_EQ("number", toString(requireTypeAtPosition({6, 28}))); } -TEST_CASE_FIXTURE(BuiltinsFixture, "what_nonsensical_condition") -{ - CheckResult result = check(R"( - local function f(x) - if type(x) == "string" and type(x) == "number" then - local foo = x - end - end - )"); - - LUAU_REQUIRE_NO_ERRORS(result); - - CHECK_EQ("never", toString(requireTypeAtPosition({3, 28}))); -} - TEST_SUITE_END(); diff --git a/tests/TypeInfer.singletons.test.cpp b/tests/TypeInfer.singletons.test.cpp index 5da4a340..811250a0 100644 --- a/tests/TypeInfer.singletons.test.cpp +++ b/tests/TypeInfer.singletons.test.cpp @@ -1,13 +1,13 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #include "Fixture.h" #include "doctest.h" -#include "Luau/BuiltinDefinitions.h" +#include "lluz/BuiltinDefinitions.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("TypeSingletons"); +TEST_SUITE_BEGIN(XorStr("TypeSingletons")); TEST_CASE_FIXTURE(Fixture, "bool_singletons") { @@ -16,7 +16,7 @@ TEST_CASE_FIXTURE(Fixture, "bool_singletons") local b: false = false )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "string_singletons") @@ -26,7 +26,7 @@ TEST_CASE_FIXTURE(Fixture, "string_singletons") local b: "bar" = "bar" )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "bool_singletons_mismatch") @@ -35,7 +35,7 @@ TEST_CASE_FIXTURE(Fixture, "bool_singletons_mismatch") local a: true = false )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'false' could not be converted into 'true'", toString(result.errors[0])); } @@ -45,7 +45,7 @@ TEST_CASE_FIXTURE(Fixture, "string_singletons_mismatch") local a: "foo" = "bar" )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type '\"bar\"' could not be converted into '\"foo\"'", toString(result.errors[0])); } @@ -55,7 +55,7 @@ TEST_CASE_FIXTURE(Fixture, "string_singletons_escape_chars") local a: "\n" = "\000\r" )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(R"(Type '"\000\r"' could not be converted into '"\n"')", toString(result.errors[0])); } @@ -66,7 +66,7 @@ TEST_CASE_FIXTURE(Fixture, "bool_singleton_subtype") local b: boolean = a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "string_singleton_subtype") @@ -76,7 +76,7 @@ TEST_CASE_FIXTURE(Fixture, "string_singleton_subtype") local b: string = a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "function_call_with_singletons") @@ -86,7 +86,7 @@ TEST_CASE_FIXTURE(Fixture, "function_call_with_singletons") f(true, "foo") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "function_call_with_singletons_mismatch") @@ -96,7 +96,7 @@ TEST_CASE_FIXTURE(Fixture, "function_call_with_singletons_mismatch") f(true, "bar") )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type '\"bar\"' could not be converted into '\"foo\"'", toString(result.errors[0])); } @@ -109,7 +109,7 @@ TEST_CASE_FIXTURE(Fixture, "overloaded_function_call_with_singletons") g(false, 37) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "overloaded_function_call_with_singletons_mismatch") @@ -120,7 +120,7 @@ TEST_CASE_FIXTURE(Fixture, "overloaded_function_call_with_singletons_mismatch") g(true, 37) )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ("Type 'number' could not be converted into 'string'", toString(result.errors[0])); CHECK_EQ("Other overloads are also not viable: (false, number) -> ()", toString(result.errors[1])); } @@ -134,7 +134,7 @@ TEST_CASE_FIXTURE(Fixture, "enums_using_singletons") local c : MyEnum = "baz" )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "enums_using_singletons_mismatch") @@ -144,7 +144,7 @@ TEST_CASE_FIXTURE(Fixture, "enums_using_singletons_mismatch") local a : MyEnum = "bang" )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type '\"bang\"' could not be converted into '\"bar\" | \"baz\" | \"foo\"'; none of the union options are compatible", toString(result.errors[0])); } @@ -159,7 +159,7 @@ TEST_CASE_FIXTURE(Fixture, "enums_using_singletons_subtyping") local c : string = b )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "tagged_unions_using_singletons") @@ -174,7 +174,7 @@ TEST_CASE_FIXTURE(Fixture, "tagged_unions_using_singletons") c = b )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "tagged_unions_using_singletons_mismatch") @@ -186,7 +186,7 @@ TEST_CASE_FIXTURE(Fixture, "tagged_unions_using_singletons_mismatch") local a : Animal = { tag = "Cat", howls = true } )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "tagged_unions_immutable_tag") @@ -199,7 +199,7 @@ TEST_CASE_FIXTURE(Fixture, "tagged_unions_immutable_tag") a.tag = "Dog" )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "table_properties_singleton_strings") @@ -224,7 +224,7 @@ TEST_CASE_FIXTURE(Fixture, "table_properties_singleton_strings") t.baz = false )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "table_properties_singleton_strings_mismatch") { @@ -239,7 +239,7 @@ TEST_CASE_FIXTURE(Fixture, "table_properties_singleton_strings_mismatch") t["$$bar"] = 5 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'number' could not be converted into 'string'", toString(result.errors[0])); } @@ -254,7 +254,7 @@ TEST_CASE_FIXTURE(Fixture, "table_properties_alias_or_parens_is_indexer") } )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Cannot have more than one table indexer", toString(result.errors[0])); } @@ -266,7 +266,7 @@ TEST_CASE_FIXTURE(Fixture, "table_properties_type_error_escapes") x = { ["\n"] = 5 } )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(R"(Table type '{ ["\n"]: number }' not compatible with type '{| ["<>"]: number |}' because the former is missing field '<>')", toString(result.errors[0])); } @@ -281,7 +281,7 @@ type Animal = Cat | Dog local a: Animal = { tag = 'cat', cafood = 'something' } )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(R"(Type 'a' could not be converted into 'Cat | Dog' caused by: None of the union options are compatible. For example: Table type 'a' not compatible with type 'Cat' because the former is missing field 'catfood')", @@ -298,7 +298,7 @@ type Result = Good | Bad local a: Result = { success = false, result = 'something' } )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(R"(Type 'a' could not be converted into 'Bad | Good' caused by: None of the union options are compatible. For example: Table type 'a' not compatible with type 'Bad' because the former is missing field 'error')", @@ -315,21 +315,21 @@ type Animal = Cat | Dog local a: Animal = if true then { tag = 'cat', catfood = 'something' } else { tag = 'dog', dogfood = 'other' } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "widen_the_supertype_if_it_is_free_and_subtype_has_singleton") { CheckResult result = check(R"( local function foo(f, x) - if x == "hi" then + if x == XorStr("hi") then f(x) f("foo") end end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(R"("hi")", toString(requireTypeAtPosition({3, 18}))); // should be ((string) -> a..., string) -> () but needs lower bounds calculation @@ -340,13 +340,13 @@ TEST_CASE_FIXTURE(Fixture, "return_type_of_f_is_not_widened") { CheckResult result = check(R"( local function foo(f, x): "hello"? -- anyone there? - return if x == "hi" + return if x == XorStr("hi") then f(x) else nil end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(R"("hi")", toString(requireTypeAtPosition({3, 23}))); CHECK_EQ(R"(((string) -> (a, c...), b) -> "hello"?)", toString(requireType("foo"))); @@ -360,7 +360,7 @@ TEST_CASE_FIXTURE(Fixture, "widening_happens_almost_everywhere") local copy = foo )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("string", toString(requireType("copy"))); } @@ -372,10 +372,10 @@ TEST_CASE_FIXTURE(Fixture, "widening_happens_almost_everywhere_except_for_tables type Animal = Cat | Dog local function f(tag: "Cat" | "Dog"): Animal? - if tag == "Cat" then + if tag == XorStr("Cat") then local result = {tag = tag, meows = true} return result - elseif tag == "Dog" then + elseif tag == XorStr("Dog") then local result = {tag = tag, barks = true} return result else @@ -384,16 +384,16 @@ TEST_CASE_FIXTURE(Fixture, "widening_happens_almost_everywhere_except_for_tables end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_with_a_singleton_argument") { - ScopedFastFlag sff{"LuauLowerBoundsCalculation", true}; + ScopedFastFlag sff{"lluzLowerBoundsCalculation", true}; CheckResult result = check(R"( local function foo(t, x) - if x == "hi" or x == "bye" then + if x == XorStr("hi") or x == XorStr("bye") then table.insert(t, x) end @@ -404,7 +404,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_with_a_singleton_argument") table.insert(t, "totally_unrelated_type" :: "totally_unrelated_type") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("{string}", toString(requireType("t"))); } @@ -415,7 +415,7 @@ TEST_CASE_FIXTURE(Fixture, "functions_are_not_to_be_widened") local function foo(my_enum: "A" | "B") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(R"(("A" | "B") -> ())", toString(requireType("foo"))); } @@ -424,12 +424,12 @@ TEST_CASE_FIXTURE(Fixture, "indexing_on_string_singletons") { CheckResult result = check(R"( local a: string = "hi" - if a == "hi" then + if a == XorStr("hi") then local x = a:byte() end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(R"("hi")", toString(requireTypeAtPosition({3, 22}))); } @@ -438,12 +438,12 @@ TEST_CASE_FIXTURE(Fixture, "indexing_on_union_of_string_singletons") { CheckResult result = check(R"( local a: string = "hi" - if a == "hi" or a == "bye" then + if a == XorStr("hi") or a == XorStr("bye") then local x = a:byte() end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(R"("bye" | "hi")", toString(requireTypeAtPosition({3, 22}))); } @@ -452,12 +452,12 @@ TEST_CASE_FIXTURE(Fixture, "taking_the_length_of_string_singleton") { CheckResult result = check(R"( local a: string = "hi" - if a == "hi" then + if a == XorStr("hi") then local x = #a end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(R"("hi")", toString(requireTypeAtPosition({3, 23}))); } @@ -466,31 +466,14 @@ TEST_CASE_FIXTURE(Fixture, "taking_the_length_of_union_of_string_singleton") { CheckResult result = check(R"( local a: string = "hi" - if a == "hi" or a == "bye" then + if a == XorStr("hi") or a == XorStr("bye") then local x = #a end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(R"("bye" | "hi")", toString(requireTypeAtPosition({3, 23}))); } -TEST_CASE_FIXTURE(Fixture, "no_widening_from_callsites") -{ - ScopedFastFlag sff{"LuauReturnsFromCallsitesAreNotWidened", true}; - - CheckResult result = check(R"( - type Direction = "North" | "East" | "West" | "South" - - local function direction(): Direction - return "North" - end - - local d: Direction = direction() - )"); - - LUAU_REQUIRE_NO_ERRORS(result); -} - TEST_SUITE_END(); diff --git a/tests/TypeInfer.tables.test.cpp b/tests/TypeInfer.tables.test.cpp index d9bfc89d..1a3a10dc 100644 --- a/tests/TypeInfer.tables.test.cpp +++ b/tests/TypeInfer.tables.test.cpp @@ -1,7 +1,7 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/BuiltinDefinitions.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/BuiltinDefinitions.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "Fixture.h" @@ -9,37 +9,37 @@ #include -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(LuauLowerBoundsCalculation); +lluz_FASTFLAG(LluLowerBoundsCalculation); -TEST_SUITE_BEGIN("TableTests"); +TEST_SUITE_BEGIN(XorStr("TableTests")); TEST_CASE_FIXTURE(Fixture, "basic") { - CheckResult result = check("local t = {foo = \"bar\", baz = 9, quux = nil}"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local t = {foo = \"bar\", baz = 9, quux = nil}")); + lluz_REQUIRE_NO_ERRORS(result); const TableTypeVar* tType = get(requireType("t")); REQUIRE(tType != nullptr); - std::optional fooProp = get(tType->props, "foo"); + std::optional fooProp = get(tType->props, XorStr("foo")); REQUIRE(bool(fooProp)); CHECK_EQ(PrimitiveTypeVar::String, getPrimitiveType(fooProp->type)); - std::optional bazProp = get(tType->props, "baz"); + std::optional bazProp = get(tType->props, XorStr("baz")); REQUIRE(bool(bazProp)); CHECK_EQ(PrimitiveTypeVar::Number, getPrimitiveType(bazProp->type)); - std::optional quuxProp = get(tType->props, "quux"); + std::optional quuxProp = get(tType->props, XorStr("quux")); REQUIRE(bool(quuxProp)); CHECK_EQ(PrimitiveTypeVar::NilType, getPrimitiveType(quuxProp->type)); } TEST_CASE_FIXTURE(Fixture, "augment_table") { - CheckResult result = check("local t = {} t.foo = 'bar'"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local t = {} t.foo = 'bar'")); + lluz_REQUIRE_NO_ERRORS(result); const TableTypeVar* tType = get(requireType("t")); REQUIRE(tType != nullptr); @@ -49,8 +49,8 @@ TEST_CASE_FIXTURE(Fixture, "augment_table") TEST_CASE_FIXTURE(Fixture, "augment_nested_table") { - CheckResult result = check("local t = { p = {} } t.p.foo = 'bar'"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local t = { p = {} } t.p.foo = 'bar'")); + lluz_REQUIRE_NO_ERRORS(result); TableTypeVar* tType = getMutable(requireType("t")); REQUIRE(tType != nullptr); @@ -64,8 +64,8 @@ TEST_CASE_FIXTURE(Fixture, "augment_nested_table") TEST_CASE_FIXTURE(Fixture, "cannot_augment_sealed_table") { - CheckResult result = check("function mkt() return {prop=999} end local t = mkt() t.foo = 'bar'"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("function mkt() return {prop=999} end local t = mkt() t.foo = 'bar'")); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeError& err = result.errors[0]; CannotExtendTable* error = get(err); @@ -73,8 +73,8 @@ TEST_CASE_FIXTURE(Fixture, "cannot_augment_sealed_table") // TODO: better, more robust comparison of type vars auto s = toString(error->tableType, ToStringOptions{/*exhaustive*/ true}); - CHECK_EQ(s, "{| prop: number |}"); - CHECK_EQ(error->prop, "foo"); + CHECK_EQ(s, XorStr("{| prop: number |}")); + CHECK_EQ(error->prop, XorStr("foo")); CHECK_EQ(error->context, CannotExtendTable::Property); CHECK_EQ(err.location, (Location{Position{0, 59}, Position{0, 64}})); } @@ -90,31 +90,31 @@ TEST_CASE_FIXTURE(Fixture, "dont_seal_an_unsealed_table_by_passing_it_to_a_funct function B:method() end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "updating_sealed_table_prop_is_ok") { - CheckResult result = check("local t = {prop=999} t.prop = 0"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local t = {prop=999} t.prop = 0")); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "cannot_change_type_of_unsealed_table_prop") { - CheckResult result = check("local t = {} t.prop = 999 t.prop = 'hello'"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("local t = {} t.prop = 999 t.prop = 'hello'")); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "cannot_change_type_of_table_prop") { - CheckResult result = check("local t = {prop=999} t.prop = 'hello'"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("local t = {prop=999} t.prop = 'hello'")); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "function_calls_can_produce_tables") { - CheckResult result = check("function get_table() return {prop=999} end get_table().prop = 0"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("function get_table() return {prop=999} end get_table().prop = 0")); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "function_calls_produces_sealed_table_given_unsealed_table") @@ -123,18 +123,18 @@ TEST_CASE_FIXTURE(Fixture, "function_calls_produces_sealed_table_given_unsealed_ function f() return {} end f().foo = 'fail' )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "tc_member_function") { - CheckResult result = check("local T = {} function T:foo() return 5 end"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local T = {} function T:foo() return 5 end")); + lluz_REQUIRE_NO_ERRORS(result); const TableTypeVar* tableType = get(requireType("T")); REQUIRE(tableType != nullptr); - std::optional fooProp = get(tableType->props, "foo"); + std::optional fooProp = get(tableType->props, XorStr("foo")); REQUIRE(bool(fooProp)); const FunctionTypeVar* methodType = get(follow(fooProp->type)); @@ -143,20 +143,20 @@ TEST_CASE_FIXTURE(Fixture, "tc_member_function") TEST_CASE_FIXTURE(Fixture, "tc_member_function_2") { - CheckResult result = check("local T = {U={}} function T.U:foo() return 5 end"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local T = {U={}} function T.U:foo() return 5 end")); + lluz_REQUIRE_NO_ERRORS(result); const TableTypeVar* tableType = get(requireType("T")); REQUIRE(tableType != nullptr); - std::optional uProp = get(tableType->props, "U"); + std::optional uProp = get(tableType->props, XorStr("U")); REQUIRE(bool(uProp)); TypeId uType = uProp->type; const TableTypeVar* uTable = get(uType); REQUIRE(uTable != nullptr); - std::optional fooProp = get(uTable->props, "foo"); + std::optional fooProp = get(uTable->props, XorStr("foo")); REQUIRE(bool(fooProp)); const FunctionTypeVar* methodType = get(follow(fooProp->type)); @@ -172,16 +172,16 @@ TEST_CASE_FIXTURE(Fixture, "tc_member_function_2") TEST_CASE_FIXTURE(Fixture, "call_method") { - CheckResult result = check("local T = {} T.x = 0 function T:method() return self.x end local a = T:method()"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local T = {} T.x = 0 function T:method() return self.x end local a = T:method()")); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.numberType, *requireType("a")); } TEST_CASE_FIXTURE(Fixture, "call_method_with_explicit_self_argument") { - CheckResult result = check("local T = {} T.x = 0 function T:method() return self.x end local a = T.method(T)"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local T = {} T.x = 0 function T:method() return self.x end local a = T.method(T)")); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "used_dot_instead_of_colon") @@ -212,7 +212,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "used_colon_correctly") local v = math.abs(upVector:Dot(5)) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "used_dot_instead_of_colon_but_correctly") @@ -226,7 +226,7 @@ TEST_CASE_FIXTURE(Fixture, "used_dot_instead_of_colon_but_correctly") local a = T.method(T, 6, 7) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "used_colon_instead_of_dot") @@ -270,7 +270,7 @@ TEST_CASE_FIXTURE(Fixture, "open_table_unification") foo(a) foo(b) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } #endif @@ -286,7 +286,7 @@ TEST_CASE_FIXTURE(Fixture, "open_table_unification_2") a:method() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeError& err = result.errors[0]; MissingProperties* error = get(err); REQUIRE(error != nullptr); @@ -312,7 +312,7 @@ TEST_CASE_FIXTURE(Fixture, "open_table_unification_3") end )"); - TypeId fooType = requireType("foo"); + TypeId fooType = requireType(XorStr("foo")); const FunctionTypeVar* fooFn = get(fooType); REQUIRE(fooFn != nullptr); @@ -340,7 +340,7 @@ TEST_CASE_FIXTURE(Fixture, "table_param_row_polymorphism_1") foo({x=55, y=nil, w=3.14159}) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "table_param_row_polymorphism_2") @@ -355,7 +355,7 @@ TEST_CASE_FIXTURE(Fixture, "table_param_row_polymorphism_2") foo({bar='bar'}) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); MissingProperties* error = get(result.errors[0]); REQUIRE(error != nullptr); @@ -375,7 +375,7 @@ TEST_CASE_FIXTURE(Fixture, "table_param_row_polymorphism_3") T:method() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeError& err = result.errors[0]; MissingProperties* error = get(err); REQUIRE(error != nullptr); @@ -417,11 +417,11 @@ TEST_CASE_FIXTURE(Fixture, "table_param_row_polymorphism_2") local w = foo(b) -- line 18 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); for (const auto& e : result.errors) std::cout << "Error: " << e << std::endl; - TypeId qType = requireType("q"); + TypeId qType = requireType(XorStr("q")); const TableTypeVar* qTable = get(qType); REQUIRE(qType != nullptr); @@ -430,7 +430,7 @@ TEST_CASE_FIXTURE(Fixture, "table_param_row_polymorphism_2") CHECK(qTable->props.find("z") == qTable->props.end()); CHECK(qTable->props.find("w") != qTable->props.end()); - TypeId wType = requireType("w"); + TypeId wType = requireType(XorStr("w")); const TableTypeVar* wTable = get(wType); REQUIRE(wTable != nullptr); @@ -453,7 +453,7 @@ TEST_CASE_FIXTURE(Fixture, "table_unification_4") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "ok_to_add_property_to_free_table") @@ -465,7 +465,7 @@ TEST_CASE_FIXTURE(Fixture, "ok_to_add_property_to_free_table") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); } @@ -480,7 +480,7 @@ TEST_CASE_FIXTURE(Fixture, "okay_to_add_property_to_unsealed_tables_by_assignmen local y = t.u.q )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number?", toString(requireType("x"))); CHECK_EQ("string?", toString(requireType("y"))); } @@ -498,7 +498,7 @@ TEST_CASE_FIXTURE(Fixture, "okay_to_add_property_to_unsealed_tables_by_function_ // Currently this errors but it shouldn't, since set only needs write access // TODO: file a JIRA for this - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); // CHECK_EQ("number?", toString(requireType("x"))); } @@ -514,7 +514,7 @@ TEST_CASE_FIXTURE(Fixture, "width_subtyping") local x : string = t.r )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "width_subtyping_needs_covariance") @@ -529,7 +529,7 @@ TEST_CASE_FIXTURE(Fixture, "width_subtyping_needs_covariance") local x : string = t.p.r -- x is 5 )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "infer_array") @@ -540,7 +540,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_array") t[2] = 'two' )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const TableTypeVar* ttv = get(requireType("t")); REQUIRE(ttv != nullptr); @@ -568,7 +568,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_array_2") function createButton( actionName, functionInfoTable ) local position = nil for i = 1,#buttonVector do - if buttonVector[i] == "empty" then + if buttonVector[i] == XorStr("empty") then position = i break end @@ -577,7 +577,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_array_2") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "indexers_get_quantified_too") @@ -590,7 +590,7 @@ TEST_CASE_FIXTURE(Fixture, "indexers_get_quantified_too") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* ftv = get(requireType("swap")); REQUIRE(ftv != nullptr); @@ -620,7 +620,7 @@ TEST_CASE_FIXTURE(Fixture, "indexers_quantification_2") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* ftv = get(requireType("mergesort")); REQUIRE(ftv != nullptr); @@ -648,7 +648,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_indexer_from_array_like_table") local t = {"one", "two", "three"} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const TableTypeVar* ttv = get(requireType("t")); REQUIRE(ttv != nullptr); @@ -676,7 +676,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_indexer_from_value_property_in_literal") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* fType = get(requireType("f")); REQUIRE(fType != nullptr); @@ -702,7 +702,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_indexer_from_its_variable_type_and_unifiable") t2 = t1 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm != nullptr); @@ -724,10 +724,10 @@ TEST_CASE_FIXTURE(Fixture, "indexer_mismatch") t2 = t1 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); - TypeId t1 = requireType("t1"); - TypeId t2 = requireType("t2"); + TypeId t1 = requireType(XorStr("t1")); + TypeId t2 = requireType(XorStr("t2")); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm != nullptr); @@ -745,7 +745,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_indexer_from_its_function_return_type") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "infer_indexer_for_left_unsealed_table_from_right_hand_table_with_indexer") @@ -757,7 +757,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_indexer_for_left_unsealed_table_from_right_han t = f() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "sealed_table_value_can_infer_an_indexer") @@ -766,7 +766,7 @@ TEST_CASE_FIXTURE(Fixture, "sealed_table_value_can_infer_an_indexer") local t: { a: string, [number]: string } = { a = "foo" } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "array_factory_function") @@ -776,7 +776,7 @@ TEST_CASE_FIXTURE(Fixture, "array_factory_function") local array: {string} = empty() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "sealed_table_indexers_must_unify") @@ -788,7 +788,7 @@ TEST_CASE_FIXTURE(Fixture, "sealed_table_indexers_must_unify") B = A )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_MESSAGE(nullptr != get(result.errors[0]), "Expected a TypeMismatch but got " << result.errors[0]); } @@ -803,7 +803,7 @@ TEST_CASE_FIXTURE(Fixture, "indexer_on_sealed_table_must_unify_with_free_table") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "infer_type_when_indexing_from_a_table_indexer") @@ -813,7 +813,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_type_when_indexing_from_a_table_indexer") local s = t[1] )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.stringType, *requireType("s")); } @@ -834,7 +834,7 @@ TEST_CASE_FIXTURE(Fixture, "indexing_from_a_table_should_prefer_properties_when_ local d = t[1] )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(*typeChecker.stringType, *requireType("a1")); CHECK_EQ(*typeChecker.stringType, *requireType("a2")); @@ -856,7 +856,7 @@ TEST_CASE_FIXTURE(Fixture, "assigning_to_an_unsealed_table_with_string_literal_s local a = t.a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.stringType, *requireType("a")); @@ -876,7 +876,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "oop_indexer_works") clazz.__index = clazz function clazz:speak() - return "hi" + return XorStr("hi") end function clazz.new() @@ -887,7 +887,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "oop_indexer_works") local words = me:speak() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.stringType, *requireType("words")); } @@ -900,7 +900,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "indexer_table") local b = instanace.a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.stringType, *requireType("b")); } @@ -911,7 +911,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "indexer_fn") local instanace = setmetatable({}, {__index=function() return 10 end}) local b = instanace.somemethodwedonthave )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.numberType, *requireType("b")); } @@ -928,7 +928,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "meta_add") local c = a + b )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(follow(requireType("a")), follow(requireType("c"))); } @@ -941,7 +941,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "meta_add_inferred") local c = a + a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*requireType("a"), *requireType("c")); } @@ -957,7 +957,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "meta_add_both_ways") local b = a + 2 local c = 2 + a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("Vector", toString(requireType("a"))); CHECK_EQ(*requireType("a"), *requireType("b")); @@ -984,7 +984,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "unification_of_unions_in_a_self_referential_ a = b )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const MetatableTypeVar* amtv = get(requireType("a")); REQUIRE(amtv); @@ -1006,7 +1006,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "oop_polymorphic") local pelican = {} setmetatable(pelican, animal) pelican.__index = pelican - function pelican:movement() return "fly" end + function pelican:movement() return XorStr("fly") end function pelican:speed() return 30 end function pelican.new(name) @@ -1025,7 +1025,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "oop_polymorphic") local speed = scoops:speed() )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.booleanType, *requireType("alive")); CHECK_EQ(*typeChecker.stringType, *requireType("movement")); @@ -1041,7 +1041,7 @@ TEST_CASE_FIXTURE(Fixture, "user_defined_table_types_are_named") local v: Vector3 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("Vector3", toString(requireType("v"))); } @@ -1072,7 +1072,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "result_is_always_any_if_lhs_is_any") local a = (n + Vector3.new(0, 1.5, 0)) * CFrame.Angles(0, math.pi/2, 0) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("a"))); } @@ -1086,7 +1086,7 @@ TEST_CASE_FIXTURE(Fixture, "result_is_bool_for_equality_operators_if_lhs_is_any" local c = a < b )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("boolean", toString(requireType("c"))); } @@ -1103,7 +1103,7 @@ TEST_CASE_FIXTURE(Fixture, "inequality_operators_imply_exactly_matching_types") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("(number) -> number", toString(requireType("abs"))); } @@ -1114,7 +1114,7 @@ TEST_CASE_FIXTURE(Fixture, "nice_error_when_trying_to_fetch_property_of_boolean" local b = a.some_prop )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 'boolean' does not have key 'some_prop'", toString(result.errors[0])); } @@ -1125,7 +1125,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "defining_a_method_for_a_builtin_sealed_table function string.m() end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(BuiltinsFixture, "defining_a_self_method_for_a_builtin_sealed_table_must_fail") @@ -1134,7 +1134,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "defining_a_self_method_for_a_builtin_sealed_ function string:m() end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "defining_a_method_for_a_local_sealed_table_must_fail") @@ -1145,7 +1145,7 @@ TEST_CASE_FIXTURE(Fixture, "defining_a_method_for_a_local_sealed_table_must_fail function t.m() end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "defining_a_self_method_for_a_local_sealed_table_must_fail") @@ -1156,7 +1156,7 @@ TEST_CASE_FIXTURE(Fixture, "defining_a_self_method_for_a_local_sealed_table_must function t:m() end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "defining_a_method_for_a_local_unsealed_table_is_ok") @@ -1166,7 +1166,7 @@ TEST_CASE_FIXTURE(Fixture, "defining_a_method_for_a_local_unsealed_table_is_ok") function t.m() end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "defining_a_self_method_for_a_local_unsealed_table_is_ok") @@ -1176,7 +1176,7 @@ TEST_CASE_FIXTURE(Fixture, "defining_a_self_method_for_a_local_unsealed_table_is function t:m() end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } // This unit test could be flaky if the fix has regressed. @@ -1194,8 +1194,8 @@ TEST_CASE_FIXTURE(Fixture, "pass_incompatible_union_to_a_generic_table_without_c f(a) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - if (FFlag::LuauLowerBoundsCalculation) + lluz_REQUIRE_ERROR_COUNT(1, result); + if (FFlag::LluLowerBoundsCalculation) CHECK(get(result.errors[0])); else CHECK(get(result.errors[0])); @@ -1214,7 +1214,7 @@ TEST_CASE_FIXTURE(Fixture, "passing_compatible_unions_to_a_generic_table_without f({y = 5} :: A) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "found_like_key_in_table_function_call") @@ -1226,13 +1226,13 @@ TEST_CASE_FIXTURE(Fixture, "found_like_key_in_table_function_call") t.fOo() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeError te = result.errors[0]; UnknownPropButFoundLikeProp* error = get(te); REQUIRE(error); - TypeId t = requireType("t"); + TypeId t = requireType(XorStr("t")); CHECK_EQ(*t, *error->table); CHECK_EQ("fOo", error->key); @@ -1240,7 +1240,7 @@ TEST_CASE_FIXTURE(Fixture, "found_like_key_in_table_function_call") CHECK_EQ(1, candidates.size()); CHECK(candidates.find("Foo") != candidates.end()); - CHECK_EQ(toString(te), "Key 'fOo' not found in table 't'. Did you mean 'Foo'?"); + CHECK_EQ(toString(te), XorStr("Key 'fOo' not found in table 't'. Did you mean 'Foo'?")); } TEST_CASE_FIXTURE(BuiltinsFixture, "found_like_key_in_table_property_access") @@ -1257,7 +1257,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "found_like_key_in_table_property_access") UnknownPropButFoundLikeProp* error = get(te); REQUIRE(error); - TypeId t = requireType("t"); + TypeId t = requireType(XorStr("t")); CHECK_EQ(*t, *error->table); CHECK_EQ("x", error->key); @@ -1265,7 +1265,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "found_like_key_in_table_property_access") CHECK_EQ(1, candidates.size()); CHECK(candidates.find("X") != candidates.end()); - CHECK_EQ(toString(te), "Key 'x' not found in table 't'. Did you mean 'X'?"); + CHECK_EQ(toString(te), XorStr("Key 'x' not found in table 't'. Did you mean 'X'?")); } TEST_CASE_FIXTURE(BuiltinsFixture, "found_multiple_like_keys") @@ -1282,7 +1282,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "found_multiple_like_keys") UnknownPropButFoundLikeProp* error = get(te); REQUIRE(error); - TypeId t = requireType("t"); + TypeId t = requireType(XorStr("t")); CHECK_EQ(*t, *error->table); CHECK_EQ("foo", error->key); @@ -1291,7 +1291,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "found_multiple_like_keys") CHECK(candidates.find("Foo") != candidates.end()); CHECK(candidates.find("foO") != candidates.end()); - CHECK_EQ(toString(te), "Key 'foo' not found in table 't'. Did you mean one of 'Foo', 'foO'?"); + CHECK_EQ(toString(te), XorStr("Key 'foo' not found in table 't'. Did you mean one of 'Foo', 'foO'?")); } TEST_CASE_FIXTURE(BuiltinsFixture, "dont_suggest_exact_match_keys") @@ -1309,7 +1309,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "dont_suggest_exact_match_keys") UnknownPropButFoundLikeProp* error = get(te); REQUIRE(error); - TypeId t = requireType("t"); + TypeId t = requireType(XorStr("t")); CHECK_EQ(*t, *error->table); CHECK_EQ("Foo", error->key); @@ -1318,7 +1318,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "dont_suggest_exact_match_keys") CHECK(candidates.find("foO") != candidates.end()); CHECK(candidates.find("Foo") == candidates.end()); - CHECK_EQ(toString(te), "Key 'Foo' not found in table 't'. Did you mean 'foO'?"); + CHECK_EQ(toString(te), XorStr("Key 'Foo' not found in table 't'. Did you mean 'foO'?")); } TEST_CASE_FIXTURE(BuiltinsFixture, "getmetatable_returns_pointer_to_metatable") @@ -1348,7 +1348,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "metatable_mismatch_should_fail") t1 = t2 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -1368,11 +1368,11 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "property_lookup_through_tabletypevar_metatab print(t.z) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); UnknownProperty* up = get(result.errors[0]); REQUIRE_MESSAGE(up, result.errors[0].data); - CHECK_EQ(up->key, "z"); + CHECK_EQ(up->key, XorStr("z")); } TEST_CASE_FIXTURE(BuiltinsFixture, "missing_metatable_for_sealed_tables_do_not_get_inferred") @@ -1387,10 +1387,10 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "missing_metatable_for_sealed_tables_do_not_g t = a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); - TypeId a = requireType("a"); - TypeId t = requireType("t"); + TypeId a = requireType(XorStr("a")); + TypeId t = requireType(XorStr("t")); CHECK_NE(*a, *t); TypeError te = result.errors[0]; @@ -1436,13 +1436,13 @@ TEST_CASE_FIXTURE(Fixture, "right_table_missing_key2") lt = rt )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); MissingProperties* mp = get(result.errors[0]); REQUIRE(mp); CHECK_EQ(mp->context, MissingProperties::Missing); REQUIRE_EQ(1, mp->properties.size()); - CHECK_EQ(mp->properties[0], "a"); + CHECK_EQ(mp->properties[0], XorStr("a")); CHECK_EQ("{| [string]: string, a: string |}", toString(mp->superType)); CHECK_EQ("{| |}", toString(mp->subType)); @@ -1455,7 +1455,7 @@ TEST_CASE_FIXTURE(Fixture, "casting_unsealed_tables_with_props_into_table_with_i local rt: StringToStringMap = { ["foo"] = 1 } )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); ToStringOptions o{/* exhaustive= */ true}; TypeMismatch* tm = get(result.errors[0]); @@ -1474,7 +1474,7 @@ TEST_CASE_FIXTURE(Fixture, "casting_sealed_tables_with_props_into_table_with_ind local rt: StringToStringMap = mkrt() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); ToStringOptions o{/* exhaustive= */ true}; TypeMismatch* tm = get(result.errors[0]); @@ -1490,7 +1490,7 @@ TEST_CASE_FIXTURE(Fixture, "casting_tables_with_props_into_table_with_indexer2") foo({ a = "" }) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "casting_tables_with_props_into_table_with_indexer3") @@ -1500,7 +1500,7 @@ TEST_CASE_FIXTURE(Fixture, "casting_tables_with_props_into_table_with_indexer3") foo({ a = 1 }) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); ToStringOptions o{/* exhaustive= */ true}; TypeMismatch* tm = get(result.errors[0]); @@ -1519,7 +1519,7 @@ TEST_CASE_FIXTURE(Fixture, "casting_tables_with_props_into_table_with_indexer4") )"); // This typechecks but shouldn't - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "table_subtyping_with_missing_props_dont_report_multiple_errors") @@ -1531,14 +1531,14 @@ TEST_CASE_FIXTURE(Fixture, "table_subtyping_with_missing_props_dont_report_multi vec3 = vec1 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); MissingProperties* mp = get(result.errors[0]); REQUIRE(mp); CHECK_EQ(mp->context, MissingProperties::Missing); REQUIRE_EQ(2, mp->properties.size()); - CHECK_EQ(mp->properties[0], "y"); - CHECK_EQ(mp->properties[1], "z"); + CHECK_EQ(mp->properties[0], XorStr("y")); + CHECK_EQ(mp->properties[1], XorStr("z")); CHECK_EQ("vec3", toString(mp->superType)); CHECK_EQ("vec1", toString(mp->subType)); } @@ -1550,13 +1550,13 @@ TEST_CASE_FIXTURE(Fixture, "table_subtyping_with_missing_props_dont_report_multi local t: DumbMixedTable = {"fail"} )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); MissingProperties* mp = get(result.errors[1]); REQUIRE(mp); CHECK_EQ(mp->context, MissingProperties::Missing); REQUIRE_EQ(1, mp->properties.size()); - CHECK_EQ(mp->properties[0], "x"); + CHECK_EQ(mp->properties[0], XorStr("x")); } TEST_CASE_FIXTURE(Fixture, "table_subtyping_with_extra_props_dont_report_multiple_errors") @@ -1571,7 +1571,7 @@ TEST_CASE_FIXTURE(Fixture, "table_subtyping_with_extra_props_dont_report_multipl vec1 = vec3 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -1588,12 +1588,12 @@ TEST_CASE_FIXTURE(Fixture, "table_subtyping_with_extra_props_is_ok") vec1 = vec3 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "type_mismatch_on_massive_table_is_cut_short") { - ScopedFastInt sfis{"LuauTableTypeMaximumStringifierLength", 40}; + ScopedFastInt sfis{"lluzTableTypeMaximumStringifierLength", 40}; CheckResult result = check(R"( local t @@ -1608,7 +1608,7 @@ TEST_CASE_FIXTURE(Fixture, "type_mismatch_on_massive_table_is_cut_short") t = 1 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); @@ -1629,7 +1629,7 @@ TEST_CASE_FIXTURE(Fixture, "ok_to_set_nil_even_on_non_lvalue_base_expr") f()["foo"] = nil )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "ok_to_provide_a_subtype_during_construction") @@ -1639,7 +1639,7 @@ TEST_CASE_FIXTURE(Fixture, "ok_to_provide_a_subtype_during_construction") local t = {a, 1} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("{number | string}", toString(requireType("t"), {/*exhaustive*/ true})); } @@ -1652,7 +1652,7 @@ TEST_CASE_FIXTURE(Fixture, "reasonable_error_when_adding_a_nonexistent_property_ A.B = "Hello" )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); UnknownProperty* up = get(result.errors[0]); REQUIRE(up != nullptr); @@ -1667,7 +1667,7 @@ TEST_CASE_FIXTURE(Fixture, "shorter_array_types_actually_work") local A: {string | number} )"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + lluz_REQUIRE_ERROR_COUNT(0, result); CHECK_EQ("{number | string}", toString(requireType("A"))); } @@ -1684,7 +1684,7 @@ TEST_CASE_FIXTURE(Fixture, "only_ascribe_synthetic_names_at_module_scope") end )"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + lluz_REQUIRE_ERROR_COUNT(0, result); CHECK_EQ("TopLevel", toString(requireType("TopLevel"))); CHECK_EQ("{number}", toString(requireType("foo"))); @@ -1706,7 +1706,7 @@ TEST_CASE_FIXTURE(Fixture, "hide_table_error_properties") end )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ("Cannot add property 'a' to table '{| x: number |}'", toString(result.errors[0])); CHECK_EQ("Cannot add property 'b' to table '{| x: number |}'", toString(result.errors[1])); @@ -1719,7 +1719,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "builtin_table_names") string.k = 3 )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ("Cannot add property 'h' to table 'os'", toString(result.errors[0])); CHECK_EQ("Cannot add property 'k' to table 'string'", toString(result.errors[1])); @@ -1732,7 +1732,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "persistent_sealed_table_is_immutable") function os:bad() end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Cannot add property 'bad' to table 'os'", toString(result.errors[0])); const TableTypeVar* osType = get(requireType("os")); @@ -1754,7 +1754,7 @@ local Test: {Table} = { } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "common_table_element_general") @@ -1771,7 +1771,7 @@ local Test: {Table} = { } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "common_table_element_inner_index") @@ -1791,7 +1791,7 @@ local Test: {{Table}} = {{ }} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "common_table_element_inner_prop") @@ -1811,7 +1811,7 @@ local Test: {{x: Table, y: Table}} = {{ }} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "common_table_element_union_assignment") @@ -1825,7 +1825,7 @@ local foos: {Foo} = { } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "quantifying_a_bound_var_works") @@ -1835,7 +1835,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "quantifying_a_bound_var_works") clazz.__index = clazz function clazz:speak() - return "hi" + return XorStr("hi") end function clazz.new() @@ -1843,8 +1843,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "quantifying_a_bound_var_works") end )"); - LUAU_REQUIRE_NO_ERRORS(result); - TypeId ty = requireType("clazz"); + lluz_REQUIRE_NO_ERRORS(result); + TypeId ty = requireType(XorStr("clazz")); TableTypeVar* ttv = getMutable(ty); REQUIRE(ttv); Property& prop = ttv->props["new"]; @@ -1863,7 +1863,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "quantifying_a_bound_var_works") TEST_CASE_FIXTURE(BuiltinsFixture, "less_exponential_blowup_please") { - ScopedFastFlag sff{"DebugLuauSharedSelf", true}; + ScopedFastFlag sff{"DebuglluzSharedSelf", true}; CheckResult result = check(R"( --!strict @@ -1892,7 +1892,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "less_exponential_blowup_please") newData:First() )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); } TEST_CASE_FIXTURE(Fixture, "common_table_element_union_in_call") @@ -1906,7 +1906,7 @@ foo({ }) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "common_table_element_union_in_call_tail") @@ -1918,7 +1918,7 @@ local function foo(l: {Foo}, ...: {Foo}) end foo({{x = 1234567}, {x = "hello"}}, {{x = 1234567}, {x = "hello"}}, {{x = 1234567}, {x = "hello"}}) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "common_table_element_union_in_prop") @@ -1934,7 +1934,7 @@ local t: { a: {Foo}, b: number } = { } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } // It's unsound to instantiate tables containing generic methods, @@ -1952,7 +1952,7 @@ TEST_CASE_FIXTURE(Fixture, "invariant_table_properties_means_instantiating_table local c : string = t.m("hi") )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_should_cope_with_optional_properties_in_nonstrict") @@ -1965,7 +1965,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_should_cope_with_optional_prope table.insert(buttons, { a = 3 }) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_should_cope_with_optional_properties_in_strict") @@ -1978,7 +1978,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_insert_should_cope_with_optional_prope table.insert(buttons, { a = 3 }) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "error_detailed_prop") @@ -1991,7 +1991,7 @@ local a: A local b: B = a )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ(toString(result.errors[0]), R"(Type 'A' could not be converted into 'B' caused by: Property 'y' is not compatible. Type 'number' could not be converted into 'string')"); @@ -2010,7 +2010,7 @@ local a: A local b: B = a )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ(toString(result.errors[0]), R"(Type 'A' could not be converted into 'B' caused by: Property 'b' is not compatible. Type 'AS' could not be converted into 'BS' @@ -2030,7 +2030,7 @@ local b2 = setmetatable({ x = 2, y = 4 }, { __call = function(s, t) end }); local c2: typeof(a2) = b2 )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ(toString(result.errors[0]), R"(Type 'b1' could not be converted into 'a1' caused by: Type '{ x: number, y: string }' could not be converted into '{ x: number, y: number }' @@ -2054,7 +2054,7 @@ TEST_CASE_FIXTURE(Fixture, "error_detailed_indexer_key") local b: B = a )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ(toString(result.errors[0]), R"(Type 'A' could not be converted into 'B' caused by: Property '[indexer key]' is not compatible. Type 'number' could not be converted into 'string')"); @@ -2070,7 +2070,7 @@ TEST_CASE_FIXTURE(Fixture, "error_detailed_indexer_value") local b: B = a )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ(toString(result.errors[0]), R"(Type 'A' could not be converted into 'B' caused by: Property '[indexer value]' is not compatible. Type 'number' could not be converted into 'string')"); @@ -2088,7 +2088,7 @@ local a: HasSuper = { p = { x = 5, y = 7 }} a.p = { x = 9 } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "explicitly_typed_table_error") @@ -2106,7 +2106,7 @@ a.p = { x = 9 } local y: number = tmp.p.y )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type 'tmp' could not be converted into 'HasSuper' caused by: Property 'p' is not compatible. Table type '{ x: number, y: number }' not compatible with type 'Super' because the former has extra field 'y')"); @@ -2124,7 +2124,7 @@ local a: HasSuper = { p = { x = 5, y = 7 }} a.p = { x = 9 } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "recursive_metatable_type_call") @@ -2135,8 +2135,8 @@ b = setmetatable({}, {__call = b}) b() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), R"(Cannot call non-function t1 where t1 = { @metatable { __call: t1 }, { } })"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), RXorStr("(Cannot call non-function t1 where t1 = { @metatable { __call: t1 }, { } })")); } TEST_CASE_FIXTURE(Fixture, "table_subtyping_shouldn't_add_optional_properties_to_sealed_tables") @@ -2154,7 +2154,7 @@ TEST_CASE_FIXTURE(Fixture, "table_subtyping_shouldn't_add_optional_properties_to local s: string = oh(37) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "top_table_type") @@ -2169,7 +2169,7 @@ TEST_CASE_FIXTURE(Fixture, "top_table_type") local v : HasHasTable = { p = { p = { p = 5 } } } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "length_operator_union") @@ -2179,7 +2179,7 @@ local x: {number} | {string} local y = #x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "length_operator_intersection") @@ -2189,7 +2189,7 @@ local x: {number} & {z:string} -- mixed tables are evil local y = #x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "length_operator_non_table_union") @@ -2199,7 +2199,7 @@ local x: {number} | any | string local y = #x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "length_operator_union_errors") @@ -2209,7 +2209,7 @@ local x: {number} | number | string local y = #x )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(BuiltinsFixture, "dont_hang_when_trying_to_look_up_in_cyclic_metatable_index") @@ -2225,7 +2225,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "dont_hang_when_trying_to_look_up_in_cyclic_m end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 't' does not have key 'p'", toString(result.errors[0])); } @@ -2240,7 +2240,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "give_up_after_one_metatable_index_look_up") local x2 = t2.x -- nope )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type 't2' does not have key 'x'", toString(result.errors[0])); } @@ -2255,7 +2255,7 @@ TEST_CASE_FIXTURE(Fixture, "confusing_indexing") local foo = f({p = "string"}) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number | string", toString(requireType("foo"))); } @@ -2273,7 +2273,7 @@ TEST_CASE_FIXTURE(Fixture, "pass_a_union_of_tables_to_a_function_that_requires_a local b = f(a) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); REQUIRE_EQ("{| [any]: any, x: number, y: number |} | {| y: number |}", toString(requireType("b"))); } @@ -2291,7 +2291,7 @@ TEST_CASE_FIXTURE(Fixture, "pass_a_union_of_tables_to_a_function_that_requires_a local b = f(a) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); REQUIRE_EQ("{| [any]: any, x: number, y: number |} | {| y: number |}", toString(requireType("b"))); } @@ -2323,7 +2323,7 @@ function forgetChildren(parent: AnyEntry) end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "unifying_tables_shouldnt_uaf2") @@ -2339,13 +2339,13 @@ _._ *= (_[false])[_] _ = (_.cos) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "cannot_call_tables") { - CheckResult result = check("local foo = {} foo()"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("local foo = {} foo()")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK(get(result.errors[0]) != nullptr); } @@ -2357,7 +2357,7 @@ TEST_CASE_FIXTURE(Fixture, "table_length") local s = #t )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK(nullptr != get(requireType("t"))); CHECK_EQ(*typeChecker.numberType, *requireType("s")); @@ -2365,14 +2365,14 @@ TEST_CASE_FIXTURE(Fixture, "table_length") TEST_CASE_FIXTURE(Fixture, "nil_assign_doesnt_hit_indexer") { - CheckResult result = check("local a = {} a[0] = 7 a[0] = nil"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + CheckResult result = check(XorStr("local a = {} a[0] = 7 a[0] = nil")); + lluz_REQUIRE_ERROR_COUNT(0, result); } TEST_CASE_FIXTURE(Fixture, "wrong_assign_does_hit_indexer") { - CheckResult result = check("local a = {} a[0] = 7 a[0] = 't'"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("local a = {} a[0] = 7 a[0] = 't'")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(result.errors[0], (TypeError{Location{Position{0, 30}, Position{0, 33}}, TypeMismatch{ typeChecker.numberType, typeChecker.stringType, @@ -2381,8 +2381,8 @@ TEST_CASE_FIXTURE(Fixture, "wrong_assign_does_hit_indexer") TEST_CASE_FIXTURE(Fixture, "nil_assign_doesnt_hit_no_indexer") { - CheckResult result = check("local a = {a=1, b=2} a['a'] = nil"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("local a = {a=1, b=2} a['a'] = nil")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(result.errors[0], (TypeError{Location{Position{0, 30}, Position{0, 33}}, TypeMismatch{ typeChecker.numberType, typeChecker.nilType, @@ -2437,7 +2437,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_unifies_into_map") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "tables_get_names_from_their_locals") @@ -2446,7 +2446,7 @@ TEST_CASE_FIXTURE(Fixture, "tables_get_names_from_their_locals") local T = {} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("T", toString(requireType("T"))); } @@ -2464,7 +2464,7 @@ TEST_CASE_FIXTURE(Fixture, "generalize_table_argument") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); const FunctionTypeVar* fooType = get(requireType("foo")); @@ -2511,7 +2511,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "dont_quantify_table_that_belongs_to_outer_sc print(self:incr()) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); TableTypeVar* counterType = getMutable(requireType("Counter")); REQUIRE(counterType); @@ -2540,12 +2540,12 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "instantiate_tables_at_scope_level") local Option = {} Option.__index = Option function Option.Is(obj) - return (type(obj) == "table" and getmetatable(obj) == Option) + return (type(obj) == XorStr("table") and getmetatable(obj) == Option) end return Option )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "inferring_crazy_table_should_also_be_quick") @@ -2570,7 +2570,7 @@ x[0] = true x.b = 37 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "setmetatable_cant_be_used_to_mutate_global_types") @@ -2613,8 +2613,8 @@ do end TEST_CASE_FIXTURE(BuiltinsFixture, "dont_crash_when_setmetatable_does_not_produce_a_metatabletypevar") { - CheckResult result = check("local x = setmetatable({})"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("local x = setmetatable({})")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Argument count mismatch. Function expects 2 arguments, but only 1 is specified", toString(result.errors[0])); } @@ -2631,7 +2631,7 @@ end type t0 = any )"); - std::optional ty = requireType("math"); + std::optional ty = requireType(XorStr("math")); REQUIRE(ty); const TableTypeVar* ttv = get(*ty); @@ -2646,9 +2646,9 @@ type X = T type K = X )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - std::optional ty = requireType("math"); + std::optional ty = requireType(XorStr("math")); REQUIRE(ty); const TableTypeVar* ttv = get(*ty); @@ -2668,9 +2668,9 @@ local c: X c = b )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - std::optional ty = requireType("a"); + std::optional ty = requireType(XorStr("a")); REQUIRE(ty); const TableTypeVar* ttv = get(*ty); @@ -2686,7 +2686,7 @@ local bar: number? local baz = foo[bar] )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(result.errors[0].location, Location{Position{3, 16}, Position{3, 19}}); } @@ -2703,7 +2703,7 @@ local b = a() local c = a(2) -- too many arguments )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Argument count mismatch. Function expects 1 argument, but 2 are specified", toString(result.errors[0])); } @@ -2721,7 +2721,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "access_index_metamethod_that_returns_variadi local foo = t.bar )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions o; o.exhaustive = true; @@ -2762,7 +2762,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_invalidate_the_properties_iterator_of_free_tabl return culprit )"; - CheckResult result = frontend.check("Module/Backend"); + CheckResult result = frontend.check(XorStr("Module/Backend")); } TEST_CASE_FIXTURE(Fixture, "checked_prop_too_early") @@ -2772,7 +2772,7 @@ TEST_CASE_FIXTURE(Fixture, "checked_prop_too_early") local u = t.x and t or 5 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Value of type '{| x: number? |}?' could be nil", toString(result.errors[0])); CHECK_EQ("number | {| x: number? |}", toString(requireType("u"))); } @@ -2784,14 +2784,14 @@ TEST_CASE_FIXTURE(Fixture, "accidentally_checked_prop_in_opposite_branch") local u = t and t.x == 5 or t.x == 31337 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Value of type '{| x: number? |}?' could be nil", toString(result.errors[0])); CHECK_EQ("boolean", toString(requireType("u"))); } /* * We had an issue where part of the type of pairs() was an unsealed table. - * This test depends on FFlagDebugLuauFreezeArena to trigger it. + * This test depends on FFlagDebuglluzFreezeArena to trigger it. */ TEST_CASE_FIXTURE(Fixture, "pairs_parameters_are_not_unsealed_tables") { @@ -2812,7 +2812,7 @@ function t.x(value) end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } /* @@ -2836,7 +2836,7 @@ TEST_CASE_FIXTURE(Fixture, "inferred_properties_of_a_table_should_start_with_the end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } // The real bug here was that we weren't always uncondionally typechecking a trailing return statement last. @@ -2859,7 +2859,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "dont_leak_free_table_props") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("({+ blah: a +}) -> ()", toString(requireType("a"))); CHECK_EQ("({+ gwar: a +}) -> ()", toString(requireType("b"))); @@ -2869,8 +2869,8 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "dont_leak_free_table_props") TEST_CASE_FIXTURE(Fixture, "inferred_return_type_of_free_table") { ScopedFastFlag sff[] = { - {"LuauLowerBoundsCalculation", true}, - {"DebugLuauSharedSelf", true}, + {"lluzLowerBoundsCalculation", true}, + {"DebuglluzSharedSelf", true}, }; check(R"( @@ -2900,7 +2900,7 @@ TEST_CASE_FIXTURE(Fixture, "mixed_tables_with_implicit_numbered_keys") local t: { [string]: number } = { 5, 6, 7 } )"); - LUAU_REQUIRE_ERROR_COUNT(3, result); + lluz_REQUIRE_ERROR_COUNT(3, result); 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[1])); @@ -2909,7 +2909,7 @@ TEST_CASE_FIXTURE(Fixture, "mixed_tables_with_implicit_numbered_keys") TEST_CASE_FIXTURE(Fixture, "shared_selfs") { - ScopedFastFlag sff{"DebugLuauSharedSelf", true}; + ScopedFastFlag sff{"DebuglluzSharedSelf", true}; CheckResult result = check(R"( local t = {} @@ -2921,7 +2921,7 @@ TEST_CASE_FIXTURE(Fixture, "shared_selfs") return t )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions opts; opts.exhaustive = true; @@ -2930,7 +2930,7 @@ TEST_CASE_FIXTURE(Fixture, "shared_selfs") TEST_CASE_FIXTURE(Fixture, "shared_selfs_from_free_param") { - ScopedFastFlag sff{"DebugLuauSharedSelf", true}; + ScopedFastFlag sff{"DebuglluzSharedSelf", true}; CheckResult result = check(R"( local function f(t) @@ -2939,14 +2939,14 @@ TEST_CASE_FIXTURE(Fixture, "shared_selfs_from_free_param") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("({+ m1: ({+ x: a, y: b +}) -> a, m2: ({+ x: a, y: b +}) -> b +}) -> ()", toString(requireType("f"))); } TEST_CASE_FIXTURE(BuiltinsFixture, "shared_selfs_through_metatables") { - ScopedFastFlag sff{"DebugLuauSharedSelf", true}; + ScopedFastFlag sff{"DebuglluzSharedSelf", true}; CheckResult result = check(R"( local t = {} @@ -2959,12 +2959,12 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "shared_selfs_through_metatables") return t )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions opts; opts.exhaustive = true; CHECK_EQ( - toString(requireType("t"), opts), "t1 where t1 = {| __index: t1, m1: ({+ x: a, y: b +}) -> a, m2: ({+ x: a, y: b +}) -> b |}"); + toString(requireType(XorStr("t"), opts), "t1 where t1 = {| __index: t1, m1: ({+ x: a, y: b +}) -> a, m2: ({+ x: a, y: b +}) -> b |}")); } TEST_CASE_FIXTURE(Fixture, "expected_indexer_value_type_extra") @@ -2976,7 +2976,7 @@ TEST_CASE_FIXTURE(Fixture, "expected_indexer_value_type_extra") local l2: {[any]: X} = { key = { { x = true }, { y = true } } } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "expected_indexer_value_type_extra_2") @@ -2987,48 +2987,39 @@ TEST_CASE_FIXTURE(Fixture, "expected_indexer_value_type_extra_2") local x: X = { key = "str" } )"); - LUAU_REQUIRE_NO_ERRORS(result); -} - -TEST_CASE_FIXTURE(Fixture, "expected_indexer_from_table_union") -{ - ScopedFastFlag luauExpectedTableUnionIndexerType{"LuauExpectedTableUnionIndexerType", true}; - - LUAU_REQUIRE_NO_ERRORS(check(R"(local a: {[string]: {number | string}} = {a = {2, 's'}})")); - LUAU_REQUIRE_NO_ERRORS(check(R"(local a: {[string]: {number | string}}? = {a = {2, 's'}})")); - LUAU_REQUIRE_NO_ERRORS(check(R"(local a: {[string]: {[string]: {string?}}?} = {["a"] = {["b"] = {"a", "b"}}})")); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "prop_access_on_key_whose_types_mismatches") { - ScopedFastFlag sff{"LuauReportErrorsOnIndexerKeyMismatch", true}; + ScopedFastFlag sff{"lluzReportErrorsOnIndexerKeyMismatch", true}; CheckResult result = check(R"( local t: {number} = {} local x = t.x )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Key 'x' not found in table '{number}'", toString(result.errors[0])); } TEST_CASE_FIXTURE(Fixture, "prop_access_on_unions_of_indexers_where_key_whose_types_mismatches") { - ScopedFastFlag sff{"LuauReportErrorsOnIndexerKeyMismatch", true}; + ScopedFastFlag sff{"lluzReportErrorsOnIndexerKeyMismatch", true}; CheckResult result = check(R"( local t: { [number]: number } | { [boolean]: number } = {} local u = t.x )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Type '{number} | {| [boolean]: number |}' does not have key 'x'", toString(result.errors[0])); } TEST_CASE_FIXTURE(BuiltinsFixture, "quantify_metatables_of_metatables_of_table") { ScopedFastFlag sff[]{ - {"DebugLuauSharedSelf", true}, + {"DebuglluzSharedSelf", true}, }; CheckResult result = check(R"( @@ -3048,17 +3039,17 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "quantify_metatables_of_metatables_of_table") return V )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions opts; opts.exhaustive = true; CHECK_EQ(toString(requireType("V"), opts), "{ @metatable { __index: { @metatable { __index: {| m: ({+ x: a, y: b +}) -> (a, b), n: ({+ x: a, y: b +}) -> () |} }, { } } }, { } }"); + XorStr("b>({+ x: a, y: b +}) -> () |} }, { } } }, { } }")); } TEST_CASE_FIXTURE(Fixture, "quantify_even_that_table_was_never_exported_at_all") { - ScopedFastFlag sff{"DebugLuauSharedSelf", true}; + ScopedFastFlag sff{"DebuglluzSharedSelf", true}; CheckResult result = check(R"( local T = {} @@ -3072,107 +3063,11 @@ TEST_CASE_FIXTURE(Fixture, "quantify_even_that_table_was_never_exported_at_all") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ToStringOptions opts; opts.exhaustive = true; CHECK_EQ("{| m: ({+ x: a, y: b +}) -> a, n: ({+ x: a, y: b +}) -> b |}", toString(requireType("T"), opts)); } -TEST_CASE_FIXTURE(BuiltinsFixture, "leaking_bad_metatable_errors") -{ - ScopedFastFlag luauIndexSilenceErrors{"LuauIndexSilenceErrors", true}; - - CheckResult result = check(R"( -local a = setmetatable({}, 1) -local b = a.x - )"); - - LUAU_REQUIRE_ERROR_COUNT(2, result); - CHECK_EQ("Metatable was not a table", toString(result.errors[0])); - CHECK_EQ("Type 'a' does not have key 'x'", toString(result.errors[1])); -} - -TEST_CASE_FIXTURE(Fixture, "scalar_is_a_subtype_of_a_compatible_polymorphic_shape_type") -{ - ScopedFastFlag sff{"LuauScalarShapeSubtyping", true}; - - CheckResult result = check(R"( - local function f(s) - return s:lower() - end - - f("foo" :: string) - f("bar" :: "bar") - f("baz" :: "bar" | "baz") - )"); - - LUAU_REQUIRE_NO_ERRORS(result); -} - -TEST_CASE_FIXTURE(Fixture, "scalar_is_not_a_subtype_of_a_compatible_polymorphic_shape_type") -{ - ScopedFastFlag sff{"LuauScalarShapeSubtyping", true}; - - CheckResult result = check(R"( - local function f(s) - return s:absolutely_no_scalar_has_this_method() - end - - f("foo" :: string) - f("bar" :: "bar") - f("baz" :: "bar" | "baz") - )"); - - LUAU_REQUIRE_ERROR_COUNT(3, result); - CHECK_EQ(R"(Type 'string' could not be converted into 't1 where t1 = {- absolutely_no_scalar_has_this_method: (t1) -> (a...) -}' -caused by: - The former's metatable does not satisfy the requirements. Table type 'string' not compatible with type 't1 where t1 = {- absolutely_no_scalar_has_this_method: (t1) -> (a...) -}' because the former is missing field 'absolutely_no_scalar_has_this_method')", - toString(result.errors[0])); - CHECK_EQ(R"(Type '"bar"' could not be converted into 't1 where t1 = {- absolutely_no_scalar_has_this_method: (t1) -> (a...) -}' -caused by: - The former's metatable does not satisfy the requirements. Table type 'string' not compatible with type 't1 where t1 = {- absolutely_no_scalar_has_this_method: (t1) -> (a...) -}' because the former is missing field 'absolutely_no_scalar_has_this_method')", - toString(result.errors[1])); - CHECK_EQ(R"(Type '"bar" | "baz"' could not be converted into 't1 where t1 = {- absolutely_no_scalar_has_this_method: (t1) -> (a...) -}' -caused by: - Not all union options are compatible. Type '"bar"' could not be converted into 't1 where t1 = {- absolutely_no_scalar_has_this_method: (t1) -> (a...) -}' -caused by: - The former's metatable does not satisfy the requirements. Table type 'string' not compatible with type 't1 where t1 = {- absolutely_no_scalar_has_this_method: (t1) -> (a...) -}' because the former is missing field 'absolutely_no_scalar_has_this_method')", - toString(result.errors[2])); -} - -TEST_CASE_FIXTURE(Fixture, "a_free_shape_can_turn_into_a_scalar_if_it_is_compatible") -{ - ScopedFastFlag sff{"LuauScalarShapeSubtyping", true}; - - CheckResult result = check(R"( - local function f(s): string - local foo = s:lower() - return s - end - )"); - - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ("(string) -> string", toString(requireType("f"))); -} - -TEST_CASE_FIXTURE(Fixture, "a_free_shape_cannot_turn_into_a_scalar_if_it_is_not_compatible") -{ - ScopedFastFlag sff{"LuauScalarShapeSubtyping", true}; - - CheckResult result = check(R"( - local function f(s): string - local foo = s:absolutely_no_scalar_has_this_method() - return s - end - )"); - - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(R"(Type 't1 where t1 = {+ absolutely_no_scalar_has_this_method: (t1) -> (a, b...) +}' could not be converted into 'string' -caused by: - The former's metatable does not satisfy the requirements. Table type 'string' not compatible with type 't1 where t1 = {+ absolutely_no_scalar_has_this_method: (t1) -> (a, b...) +}' because the former is missing field 'absolutely_no_scalar_has_this_method')", - toString(result.errors[0])); - CHECK_EQ("(t1) -> string where t1 = {+ absolutely_no_scalar_has_this_method: (t1) -> (a, b...) +}", toString(requireType("f"))); -} - TEST_SUITE_END(); diff --git a/tests/TypeInfer.test.cpp b/tests/TypeInfer.test.cpp index af6185ef..c3f156a1 100644 --- a/tests/TypeInfer.test.cpp +++ b/tests/TypeInfer.test.cpp @@ -1,11 +1,11 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/AstQuery.h" -#include "Luau/BuiltinDefinitions.h" -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" -#include "Luau/VisitTypeVar.h" +#include "lluz/AstQuery.h" +#include "lluz/BuiltinDefinitions.h" +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" +#include "lluz/VisitTypeVar.h" #include "Fixture.h" @@ -13,45 +13,44 @@ #include -LUAU_FASTFLAG(LuauLowerBoundsCalculation); -LUAU_FASTFLAG(LuauFixLocationSpanTableIndexExpr); -LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution); -LUAU_FASTFLAG(LuauSpecialTypesAsterisked); +lluz_FASTFLAG(LluLowerBoundsCalculation); +lluz_FASTFLAG(LluFixLocationSpanTableIndexExpr); +lluz_FASTFLAG(DebugLluDeferredConstraintResolution); -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("TypeInfer"); +TEST_SUITE_BEGIN(XorStr("TypeInfer")); TEST_CASE_FIXTURE(Fixture, "tc_hello_world") { - CheckResult result = check("local a = 7"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local a = 7")); + lluz_REQUIRE_NO_ERRORS(result); - TypeId aType = requireType("a"); + TypeId aType = requireType(XorStr("a")); CHECK_EQ(getPrimitiveType(aType), PrimitiveTypeVar::Number); } TEST_CASE_FIXTURE(Fixture, "tc_propagation") { - CheckResult result = check("local a = 7 local b = a"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local a = 7 local b = a")); + lluz_REQUIRE_NO_ERRORS(result); - TypeId bType = requireType("b"); + TypeId bType = requireType(XorStr("b")); CHECK_EQ(getPrimitiveType(bType), PrimitiveTypeVar::Number); } TEST_CASE_FIXTURE(Fixture, "tc_error") { - CheckResult result = check("local a = 7 local b = 'hi' a = b"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("local a = 7 local b = 'hi' a = b")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(result.errors[0], (TypeError{Location{Position{0, 35}, Position{0, 36}}, TypeMismatch{typeChecker.numberType, typeChecker.stringType}})); } TEST_CASE_FIXTURE(Fixture, "tc_error_2") { - CheckResult result = check("local a = 7 a = 'hi'"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("local a = 7 a = 'hi'")); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(result.errors[0], (TypeError{Location{Position{0, 18}, Position{0, 22}}, TypeMismatch{ requireType("a"), @@ -61,10 +60,10 @@ TEST_CASE_FIXTURE(Fixture, "tc_error_2") TEST_CASE_FIXTURE(Fixture, "infer_locals_with_nil_value") { - CheckResult result = check("local f = nil; f = 'hello world'"); - LUAU_REQUIRE_NO_ERRORS(result); + CheckResult result = check(XorStr("local f = nil; f = 'hello world'")); + lluz_REQUIRE_NO_ERRORS(result); - TypeId ty = requireType("f"); + TypeId ty = requireType(XorStr("f")); CHECK_EQ(getPrimitiveType(ty), PrimitiveTypeVar::String); } @@ -77,7 +76,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_locals_via_assignment_from_its_call_site") f("foo") )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("number", toString(requireType("a"))); } @@ -85,28 +84,29 @@ TEST_CASE_FIXTURE(Fixture, "infer_locals_via_assignment_from_its_call_site") TEST_CASE_FIXTURE(Fixture, "infer_in_nocheck_mode") { ScopedFastFlag sff[]{ - {"DebugLuauDeferredConstraintResolution", false}, - {"LuauLowerBoundsCalculation", true}, + {"DebuglluzDeferredConstraintResolution", false}, + {"lluzReturnTypeInferenceInNonstrict", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( --!nocheck function f(x) - return x + return 5 end -- we get type information even if there's type errors f(1, 2) )"); - CHECK_EQ("(any) -> (...any)", toString(requireType("f"))); + CHECK_EQ("(any) -> number", toString(requireType("f"))); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "expr_statement") { - CheckResult result = check("local foo = 5 foo()"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + CheckResult result = check(XorStr("local foo = 5 foo()")); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "if_statement") @@ -122,7 +122,7 @@ TEST_CASE_FIXTURE(Fixture, "if_statement") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.stringType, *requireType("a")); CHECK_EQ(*typeChecker.numberType, *requireType("b")); @@ -140,7 +140,7 @@ TEST_CASE_FIXTURE(Fixture, "statements_are_topologically_sorted") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); } @@ -156,7 +156,7 @@ TEST_CASE_FIXTURE(Fixture, "unify_nearly_identical_recursive_types") o = p )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "warn_on_lowercase_parent_property") @@ -165,7 +165,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "warn_on_lowercase_parent_property") local M = require(script.parent.DoesNotMatter) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto ed = get(result.errors[0]); REQUIRE(ed); @@ -180,7 +180,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "weird_case") local d = math.deg(f()) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "dont_ice_when_failing_the_occurs_check") @@ -190,7 +190,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_ice_when_failing_the_occurs_check") local s s(s, 'a') )"); - LUAU_REQUIRE_ERROR_COUNT(0, result); + lluz_REQUIRE_ERROR_COUNT(0, result); } TEST_CASE_FIXTURE(Fixture, "occurs_check_does_not_recurse_forever_if_asked_to_traverse_a_cyclic_type") @@ -202,7 +202,7 @@ TEST_CASE_FIXTURE(Fixture, "occurs_check_does_not_recurse_forever_if_asked_to_tr end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } #if 0 @@ -228,7 +228,7 @@ TEST_CASE_FIXTURE(Fixture, "type_errors_infer_types") local f = err )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); UnknownProperty* err = get(result.errors[0]); REQUIRE(err != nullptr); @@ -236,23 +236,12 @@ TEST_CASE_FIXTURE(Fixture, "type_errors_infer_types") CHECK_EQ("x", err->key); // TODO: Should we assert anything about these tests when DCR is being used? - if (!FFlag::DebugLuauDeferredConstraintResolution) + if (!FFlag::DebugLluDeferredConstraintResolution) { - if (FFlag::LuauSpecialTypesAsterisked) - { - CHECK_EQ("*error-type*", toString(requireType("c"))); - CHECK_EQ("*error-type*", toString(requireType("d"))); - CHECK_EQ("*error-type*", toString(requireType("e"))); - CHECK_EQ("*error-type*", toString(requireType("f"))); - } - else - { - CHECK_EQ("", toString(requireType("c"))); - CHECK_EQ("", toString(requireType("d"))); - CHECK_EQ("", toString(requireType("e"))); - CHECK_EQ("", toString(requireType("f"))); - } - + CHECK_EQ("*unknown*", toString(requireType("c"))); + CHECK_EQ("*unknown*", toString(requireType("d"))); + CHECK_EQ("*unknown*", toString(requireType("e"))); + CHECK_EQ("*unknown*", toString(requireType("f"))); } } @@ -268,7 +257,7 @@ TEST_CASE_FIXTURE(Fixture, "should_be_able_to_infer_this_without_stack_overflowi end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "exponential_blowup_from_copying_types") @@ -301,7 +290,7 @@ TEST_CASE_FIXTURE(Fixture, "exponential_blowup_from_copying_types") return x4 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); ModulePtr module = getMainModule(); // If we're not careful about copying, this ends up with O(2^N) types rather than O(N) @@ -313,7 +302,7 @@ TEST_CASE_FIXTURE(Fixture, "exponential_blowup_from_copying_types") // checker. We also want it to somewhat match up with production values, so we push up the parser recursion limit a little bit instead. TEST_CASE_FIXTURE(Fixture, "check_type_infer_recursion_count") { -#if defined(LUAU_ENABLE_ASAN) +#if defined(lluz_ENABLE_ASAN) int limit = 250; #elif defined(_DEBUG) || defined(_NOOPT) int limit = 350; @@ -321,17 +310,17 @@ TEST_CASE_FIXTURE(Fixture, "check_type_infer_recursion_count") int limit = 600; #endif - ScopedFastInt sfi{"LuauCheckRecursionLimit", limit}; + ScopedFastInt sfi{"lluzCheckRecursionLimit", limit}; - CheckResult result = check("function f() return " + rep("{a=", limit) + "'a'" + rep("}", limit) + " end"); + CheckResult result = check(XorStr("function f() return XorStr(" + rep("){a=", limit) + "'a'" + rep("}", limit) + " end")); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK(nullptr != get(result.errors[0])); } TEST_CASE_FIXTURE(Fixture, "check_block_recursion_limit") { -#if defined(LUAU_ENABLE_ASAN) +#if defined(lluz_ENABLE_ASAN) int limit = 250; #elif defined(_DEBUG) || defined(_NOOPT) int limit = 350; @@ -339,62 +328,33 @@ TEST_CASE_FIXTURE(Fixture, "check_block_recursion_limit") int limit = 600; #endif - ScopedFastInt luauRecursionLimit{"LuauRecursionLimit", limit + 100}; - ScopedFastInt luauCheckRecursionLimit{"LuauCheckRecursionLimit", limit - 100}; + ScopedFastInt lluzRecursionLimit{"lluzRecursionLimit", limit + 100}; + ScopedFastInt lluzCheckRecursionLimit{"lluzCheckRecursionLimit", limit - 100}; CheckResult result = check(rep("do ", limit) + "local a = 1" + rep(" end", limit)); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK(nullptr != get(result.errors[0])); } TEST_CASE_FIXTURE(Fixture, "check_expr_recursion_limit") { -#if defined(LUAU_ENABLE_ASAN) +#if defined(lluz_ENABLE_ASAN) int limit = 250; #elif defined(_DEBUG) || defined(_NOOPT) int limit = 300; #else int limit = 600; #endif - ScopedFastInt luauRecursionLimit{"LuauRecursionLimit", limit + 100}; - ScopedFastInt luauCheckRecursionLimit{"LuauCheckRecursionLimit", limit - 100}; + ScopedFastInt lluzRecursionLimit{"lluzRecursionLimit", limit + 100}; + ScopedFastInt lluzCheckRecursionLimit{"lluzCheckRecursionLimit", limit - 100}; CheckResult result = check(R"(("foo"))" + rep(":lower()", limit)); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK(nullptr != get(result.errors[0])); } -TEST_CASE_FIXTURE(Fixture, "globals") -{ - CheckResult result = check(R"( - --!nonstrict - foo = true - foo = "now i'm a string!" - )"); - - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ("any", toString(requireType("foo"))); -} - -TEST_CASE_FIXTURE(Fixture, "globals2") -{ - CheckResult result = check(R"( - --!nonstrict - foo = function() return 1 end - foo = "now i'm a string!" - )"); - - LUAU_REQUIRE_ERROR_COUNT(1, result); - - TypeMismatch* tm = get(result.errors[0]); - REQUIRE(tm); - CHECK_EQ("() -> (...any)", toString(tm->wantedType)); - CHECK_EQ("string", toString(tm->givenType)); - CHECK_EQ("() -> (...any)", toString(requireType("foo"))); -} - TEST_CASE_FIXTURE(Fixture, "globals_are_banned_in_strict_mode") { CheckResult result = check(R"( @@ -402,7 +362,7 @@ TEST_CASE_FIXTURE(Fixture, "globals_are_banned_in_strict_mode") foo = true )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); UnknownSymbol* us = get(result.errors[0]); REQUIRE(us); @@ -419,11 +379,11 @@ TEST_CASE_FIXTURE(Fixture, "correctly_scope_locals_do") local b = a -- oops! )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); UnknownSymbol* us = get(result.errors[0]); REQUIRE(us); - CHECK_EQ(us->name, "a"); + CHECK_EQ(us->name, XorStr("a")); } TEST_CASE_FIXTURE(Fixture, "checking_should_not_ice") @@ -496,17 +456,17 @@ TEST_CASE_FIXTURE(Fixture, "tc_after_error_recovery") local x = local a = 7 )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); - TypeId aType = requireType("a"); + TypeId aType = requireType(XorStr("a")); CHECK_EQ(getPrimitiveType(aType), PrimitiveTypeVar::Number); } // Check that type checker knows about error expressions TEST_CASE_FIXTURE(Fixture, "tc_after_error_recovery_no_assert") { - CheckResult result = check("function +() local _ = true end"); - LUAU_REQUIRE_ERRORS(result); + CheckResult result = check(XorStr("function +() local _ = true end")); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "tc_after_error_recovery_no_replacement_name_in_error") @@ -518,7 +478,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "tc_after_error_recovery_no_replacement_name_ return t. )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } { @@ -528,7 +488,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "tc_after_error_recovery_no_replacement_name_ export type = string )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); } { @@ -537,7 +497,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "tc_after_error_recovery_no_replacement_name_ function string.() end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } { @@ -547,7 +507,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "tc_after_error_recovery_no_replacement_name_ local function () end )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); } { @@ -558,7 +518,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "tc_after_error_recovery_no_replacement_name_ function dm.() end )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); } } @@ -570,7 +530,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "index_expr_should_be_checked") print(foo[(true).x]) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); UnknownProperty* up = get(result.errors[0]); // Should probably be NotATable REQUIRE(up); @@ -586,7 +546,7 @@ TEST_CASE_FIXTURE(Fixture, "stringify_nested_unions_with_optionals") local b: number = a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); CHECK_EQ(typeChecker.numberType, tm->wantedType); @@ -600,7 +560,7 @@ TEST_CASE_FIXTURE(Fixture, "cli_39932_use_unifier_in_ensure_methods") local y = x[1] - x[2] )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "dont_report_type_errors_within_an_AstStatError") @@ -609,7 +569,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_report_type_errors_within_an_AstStatError") foo )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "dont_report_type_errors_within_an_AstExprError") @@ -618,7 +578,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_report_type_errors_within_an_AstExprError") local a = foo: )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); } TEST_CASE_FIXTURE(Fixture, "dont_ice_on_astexprerror") @@ -627,10 +587,10 @@ TEST_CASE_FIXTURE(Fixture, "dont_ice_on_astexprerror") local foo = -; )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } -TEST_CASE_FIXTURE(Fixture, "luau_resolves_symbols_the_same_way_lua_does") +TEST_CASE_FIXTURE(Fixture, "lluz_resolves_symbols_the_same_way_lua_does") { CheckResult result = check(R"( --!strict @@ -641,7 +601,7 @@ TEST_CASE_FIXTURE(Fixture, "luau_resolves_symbols_the_same_way_lua_does") local foo: string = 'hello' )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto e = result.errors.front(); REQUIRE_MESSAGE(get(e) != nullptr, "Expected UnknownSymbol, but got " << e); @@ -658,15 +618,11 @@ TEST_CASE_FIXTURE(Fixture, "no_stack_overflow_from_isoptional") _(nil) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); - std::optional t0 = getMainModule()->getModuleScope()->lookupType("t0"); + std::optional t0 = getMainModule()->getModuleScope()->lookupType(XorStr("t0")); REQUIRE(t0); - - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(t0->type)); - else - CHECK_EQ("", toString(t0->type)); + CHECK_EQ("*unknown*", toString(t0->type)); auto it = std::find_if(result.errors.begin(), result.errors.end(), [](TypeError& err) { return get(err); @@ -687,7 +643,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "no_stack_overflow_from_isoptional2") local t: ({})|(t0) )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "no_infinite_loop_when_trying_to_unify_uh_this") @@ -701,7 +657,7 @@ TEST_CASE_FIXTURE(Fixture, "no_infinite_loop_when_trying_to_unify_uh_this") _() )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "no_heap_use_after_free_error") @@ -718,7 +674,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "no_heap_use_after_free_error") end )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "infer_type_assertion_value_type") @@ -729,7 +685,7 @@ local function f() end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "infer_assignment_value_types") @@ -744,7 +700,7 @@ local c: {number|string} b, c = {2, "s"}, {"b", 4} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "infer_assignment_value_types_mutable_lval") @@ -755,7 +711,7 @@ a.x = 2 a = setmetatable(a, { __call = function(x) end }) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "infer_through_group_expr") @@ -765,14 +721,14 @@ local function f(a: (number, number) -> number) return a(1, 3) end f(((function(a, b) return a + b end))) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "tc_if_else_expressions1") { - CheckResult result = check(R"(local a = if true then "true" else "false")"); - LUAU_REQUIRE_NO_ERRORS(result); - TypeId aType = requireType("a"); + CheckResult result = check(RXorStr("(local a = if true then "true" else "false")")); + lluz_REQUIRE_NO_ERRORS(result); + TypeId aType = requireType(XorStr("a")); CHECK_EQ(getPrimitiveType(aType), PrimitiveTypeVar::String); } @@ -782,17 +738,17 @@ TEST_CASE_FIXTURE(Fixture, "tc_if_else_expressions2") CheckResult result = check(R"( local a = if false then "a" elseif false then "b" else "c" )"); - LUAU_REQUIRE_NO_ERRORS(result); - TypeId aType = requireType("a"); + lluz_REQUIRE_NO_ERRORS(result); + TypeId aType = requireType(XorStr("a")); CHECK_EQ(getPrimitiveType(aType), PrimitiveTypeVar::String); } TEST_CASE_FIXTURE(Fixture, "tc_if_else_expressions_type_union") { - CheckResult result = check(R"(local a: number? = if true then 42 else nil)"); + CheckResult result = check(RXorStr("(local a: number? = if true then 42 else nil)")); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a"), {true}), "number?"); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ(toString(requireType(XorStr("a"), {true}), "number?")); } TEST_CASE_FIXTURE(Fixture, "tc_if_else_expressions_expected_type_1") @@ -802,8 +758,8 @@ type X = {number | string} local a: X = if true then {"1", 2, 3} else {4, 5, 6} )"); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a"), {true}), "{number | string}"); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ(toString(requireType(XorStr("a"), {true}), "{number | string}")); } TEST_CASE_FIXTURE(Fixture, "tc_if_else_expressions_expected_type_2") @@ -812,7 +768,7 @@ TEST_CASE_FIXTURE(Fixture, "tc_if_else_expressions_expected_type_2") local a: number? = if true then 1 else nil )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "tc_if_else_expressions_expected_type_3") @@ -826,7 +782,7 @@ local function times(n: any, f: () -> T) end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } /* @@ -899,7 +855,7 @@ local b = getIt() local c = a or b )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "bound_typepack_promote") @@ -951,7 +907,7 @@ TEST_CASE_FIXTURE(Fixture, "cli_50041_committing_txnlog_in_apollo_client_error") end function Policies:getStoreFieldName(specifier: FieldSpecifier): string - return "" + return XorStr("") end function Policies:readField(options: ReadFieldOptions) @@ -964,12 +920,12 @@ TEST_CASE_FIXTURE(Fixture, "cli_50041_committing_txnlog_in_apollo_client_error") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "type_infer_recursion_limit_no_ice") { - ScopedFastInt sfi("LuauTypeInferRecursionLimit", 2); + ScopedFastInt sfi("lluzTypeInferRecursionLimit", 2); CheckResult result = check(R"( function complex() @@ -981,7 +937,7 @@ TEST_CASE_FIXTURE(Fixture, "type_infer_recursion_limit_no_ice") end )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); CHECK_EQ("Code is too complex to typecheck! Consider simplifying the code around this area", toString(result.errors[0])); } @@ -1005,7 +961,7 @@ TEST_CASE_FIXTURE(Fixture, "follow_on_new_types_in_substitution") return obj )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } /** @@ -1015,7 +971,7 @@ 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") { ScopedFastFlag flag[] = { - {"LuauLowerBoundsCalculation", true}, + {"lluzLowerBoundsCalculation", true}, }; CheckResult result = check(R"( @@ -1036,7 +992,7 @@ TEST_CASE_FIXTURE(Fixture, "do_not_bind_a_free_table_to_a_union_containing_that_ local B = A:f() function B.g(t) - assert(type(t) == "table") + assert(type(t) == XorStr("table")) assert(t.prop ~= nil) end @@ -1056,7 +1012,7 @@ end )"); auto node = findNodeAtPosition(*getMainSourceModule(), {2, 16}); - auto ty = lookupType("alias"); + auto ty = lookupType(XorStr("alias")); REQUIRE(node); REQUIRE(node->is()); REQUIRE(ty); diff --git a/tests/TypeInfer.tryUnify.test.cpp b/tests/TypeInfer.tryUnify.test.cpp index e0a0e5b5..797f832e 100644 --- a/tests/TypeInfer.tryUnify.test.cpp +++ b/tests/TypeInfer.tryUnify.test.cpp @@ -1,15 +1,13 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; - -LUAU_FASTFLAG(LuauSpecialTypesAsterisked) +using namespace lluz; struct TryUnifyFixture : Fixture { @@ -20,7 +18,7 @@ struct TryUnifyFixture : Fixture Unifier state{&arena, Mode::Strict, Location{}, Variance::Covariant, unifierState}; }; -TEST_SUITE_BEGIN("TryUnifyTests"); +TEST_SUITE_BEGIN(XorStr("TryUnifyTests")); TEST_CASE_FIXTURE(TryUnifyFixture, "primitives_unify") { @@ -120,13 +118,10 @@ TEST_CASE_FIXTURE(TryUnifyFixture, "members_of_failed_typepack_unification_are_u f(a, b) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("a", toString(requireType("a"))); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(requireType("b"))); - else - CHECK_EQ("", toString(requireType("b"))); + CHECK_EQ("*unknown*", toString(requireType("b"))); } TEST_CASE_FIXTURE(TryUnifyFixture, "result_of_failed_typepack_unification_is_constrained") @@ -138,13 +133,10 @@ TEST_CASE_FIXTURE(TryUnifyFixture, "result_of_failed_typepack_unification_is_con local c = f(a, b) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("a", toString(requireType("a"))); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(requireType("b"))); - else - CHECK_EQ("", toString(requireType("b"))); + CHECK_EQ("*unknown*", toString(requireType("b"))); CHECK_EQ("number", toString(requireType("c"))); } @@ -163,7 +155,7 @@ TEST_CASE_FIXTURE(TryUnifyFixture, "typepack_unification_should_trim_free_tails" end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("(number) -> boolean", toString(requireType("f"))); } @@ -197,11 +189,11 @@ TEST_CASE_FIXTURE(TryUnifyFixture, "variadics_should_use_reversed_properly") local x: string = f(1) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); TypeMismatch* tm = get(result.errors[0]); REQUIRE(tm); - CHECK_EQ(toString(tm->givenType), "number"); - CHECK_EQ(toString(tm->wantedType), "string"); + CHECK_EQ(toString(tm->givenType), XorStr("number")); + CHECK_EQ(toString(tm->wantedType), XorStr("string")); } TEST_CASE_FIXTURE(BuiltinsFixture, "cli_41095_concat_log_in_sealed_table_unification") @@ -211,9 +203,9 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "cli_41095_concat_log_in_sealed_table_unifica table.insert() )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); - CHECK_EQ(toString(result.errors[0]), "No overload for function accepts 0 arguments."); - CHECK_EQ(toString(result.errors[1]), "Available overloads: ({a}, a) -> (); and ({a}, number, a) -> ()"); + lluz_REQUIRE_ERROR_COUNT(2, result); + CHECK_EQ(toString(result.errors[0]), XorStr("No overload for function accepts 0 arguments.")); + CHECK_EQ(toString(result.errors[1]), XorStr("Available overloads: ({a}, a) -> (); and ({a}, number, a) -> ()")); } TEST_CASE_FIXTURE(TryUnifyFixture, "free_tail_is_grown_properly") diff --git a/tests/TypeInfer.typePacks.cpp b/tests/TypeInfer.typePacks.cpp index bcd30498..e805d20f 100644 --- a/tests/TypeInfer.typePacks.cpp +++ b/tests/TypeInfer.typePacks.cpp @@ -1,17 +1,17 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/BuiltinDefinitions.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/BuiltinDefinitions.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTFLAG(LuauLowerBoundsCalculation); +lluz_FASTFLAG(LluLowerBoundsCalculation); -TEST_SUITE_BEGIN("TypePackTests"); +TEST_SUITE_BEGIN(XorStr("TypePackTests")); TEST_CASE_FIXTURE(Fixture, "infer_multi_return") { @@ -21,7 +21,7 @@ TEST_CASE_FIXTURE(Fixture, "infer_multi_return") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* takeTwoType = get(requireType("take_two")); REQUIRE(takeTwoType != nullptr); @@ -41,7 +41,7 @@ TEST_CASE_FIXTURE(Fixture, "empty_varargs_should_return_nil_when_not_in_tail_pos local a, b = ..., 1 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "self_and_varargs_should_work") @@ -52,7 +52,7 @@ TEST_CASE_FIXTURE(Fixture, "self_and_varargs_should_work") t:f(1) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "last_element_of_return_statement_can_itself_be_a_pack") @@ -67,7 +67,7 @@ TEST_CASE_FIXTURE(Fixture, "last_element_of_return_statement_can_itself_be_a_pac end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); dumpErrors(result); const FunctionTypeVar* takeOneMoreType = get(requireType("take_three")); @@ -91,7 +91,7 @@ TEST_CASE_FIXTURE(Fixture, "higher_order_function") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("((b...) -> (c...), (a) -> (b...), a) -> (c...)", toString(requireType("apply"))); } @@ -102,7 +102,7 @@ TEST_CASE_FIXTURE(Fixture, "return_type_should_be_empty_if_nothing_is_returned") function f() end function g() return end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* fTy = get(requireType("f")); REQUIRE(fTy != nullptr); CHECK_EQ(0, size(fTy->retTypes)); @@ -121,7 +121,7 @@ TEST_CASE_FIXTURE(Fixture, "no_return_size_should_be_zero") g(h()) f(g(),h()) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* fTy = get(requireType("f")); REQUIRE(fTy != nullptr); @@ -149,7 +149,7 @@ TEST_CASE_FIXTURE(Fixture, "varargs_inference_through_multiple_scopes") f("foo") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "multiple_varargs_inference_are_not_confused") @@ -166,7 +166,7 @@ TEST_CASE_FIXTURE(Fixture, "multiple_varargs_inference_are_not_confused") f("foo", "bar")(1, 2) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "parenthesized_varargs_returns_any") @@ -180,7 +180,7 @@ TEST_CASE_FIXTURE(Fixture, "parenthesized_varargs_returns_any") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("any", toString(requireType("value"))); } @@ -223,7 +223,7 @@ TEST_CASE_FIXTURE(Fixture, "variadic_packs") bar(1, "foo", "bar", 3) )"); - LUAU_REQUIRE_ERROR_COUNT(2, result); + lluz_REQUIRE_ERROR_COUNT(2, result); CHECK_EQ(result.errors[0], (TypeError{Location(Position{3, 21}, Position{3, 26}), TypeMismatch{typeChecker.numberType, typeChecker.stringType}})); @@ -241,8 +241,8 @@ TEST_CASE_FIXTURE(Fixture, "variadic_pack_syntax") foo(1, 2, 3, 4, 5, 6) )"); - LUAU_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("foo")), "(...number) -> ()"); + lluz_REQUIRE_NO_ERRORS(result); + CHECK_EQ(toString(requireType(XorStr("foo")), "(...number) -> ()")); } TEST_CASE_FIXTURE(Fixture, "type_pack_hidden_free_tail_infinite_growth") @@ -259,7 +259,7 @@ elseif _ then end )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "variadic_argument_tail") @@ -272,7 +272,7 @@ for y in _() do end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "type_alias_type_packs") @@ -284,14 +284,14 @@ local b: Packed local c: Packed )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - auto tf = lookupType("Packed"); + auto tf = lookupType(XorStr("Packed")); REQUIRE(tf); - CHECK_EQ(toString(*tf), "(T...) -> (T...)"); - CHECK_EQ(toString(requireType("a")), "() -> ()"); - CHECK_EQ(toString(requireType("b")), "(number) -> number"); - CHECK_EQ(toString(requireType("c")), "(string, number) -> (string, number)"); + CHECK_EQ(toString(*tf), XorStr("(T...) -> (T...)")); + CHECK_EQ(toString(requireType(XorStr("a")), "() -> ()")); + CHECK_EQ(toString(requireType(XorStr("b")), "(number) -> number")); + CHECK_EQ(toString(requireType(XorStr("c")), "(string, number) -> (string, number)")); result = check(R"( -- (U..., T) cannot be parsed right now @@ -301,42 +301,42 @@ local b: Packed local c: Packed )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - tf = lookupType("Packed"); + tf = lookupType(XorStr("Packed")); REQUIRE(tf); - CHECK_EQ(toString(*tf), "Packed"); - CHECK_EQ(toString(*tf, {true}), "{| f: (T, U...) -> (T, U...) |}"); + CHECK_EQ(toString(*tf), XorStr("Packed")); + CHECK_EQ(toString(*tf, {true}), XorStr("{| f: (T, U...) -> (T, U...) |}")); auto ttvA = get(requireType("a")); REQUIRE(ttvA); - CHECK_EQ(toString(requireType("a")), "Packed"); - if (FFlag::LuauLowerBoundsCalculation) - CHECK_EQ(toString(requireType("a"), {true}), "{| f: (number) -> number |}"); + CHECK_EQ(toString(requireType(XorStr("a")), "Packed")); + if (FFlag::LluLowerBoundsCalculation) + CHECK_EQ(toString(requireType(XorStr("a"), {true}), "{| f: (number) -> number |}")); else - CHECK_EQ(toString(requireType("a"), {true}), "{| f: (number) -> (number) |}"); + CHECK_EQ(toString(requireType(XorStr("a"), {true}), "{| f: (number) -> (number) |}")); REQUIRE(ttvA->instantiatedTypeParams.size() == 1); REQUIRE(ttvA->instantiatedTypePackParams.size() == 1); - CHECK_EQ(toString(ttvA->instantiatedTypeParams[0], {true}), "number"); - CHECK_EQ(toString(ttvA->instantiatedTypePackParams[0], {true}), ""); + CHECK_EQ(toString(ttvA->instantiatedTypeParams[0], {true}), XorStr("number")); + CHECK_EQ(toString(ttvA->instantiatedTypePackParams[0], {true}), XorStr("")); auto ttvB = get(requireType("b")); REQUIRE(ttvB); - CHECK_EQ(toString(requireType("b")), "Packed"); - CHECK_EQ(toString(requireType("b"), {true}), "{| f: (string, number) -> (string, number) |}"); + CHECK_EQ(toString(requireType(XorStr("b")), "Packed")); + CHECK_EQ(toString(requireType(XorStr("b"), {true}), "{| f: (string, number) -> (string, number) |}")); REQUIRE(ttvB->instantiatedTypeParams.size() == 1); REQUIRE(ttvB->instantiatedTypePackParams.size() == 1); - CHECK_EQ(toString(ttvB->instantiatedTypeParams[0], {true}), "string"); - CHECK_EQ(toString(ttvB->instantiatedTypePackParams[0], {true}), "number"); + CHECK_EQ(toString(ttvB->instantiatedTypeParams[0], {true}), XorStr("string")); + CHECK_EQ(toString(ttvB->instantiatedTypePackParams[0], {true}), XorStr("number")); auto ttvC = get(requireType("c")); REQUIRE(ttvC); - CHECK_EQ(toString(requireType("c")), "Packed"); - CHECK_EQ(toString(requireType("c"), {true}), "{| f: (string, number, boolean) -> (string, number, boolean) |}"); + CHECK_EQ(toString(requireType(XorStr("c")), "Packed")); + CHECK_EQ(toString(requireType(XorStr("c"), {true}), "{| f: (string, number, boolean) -> (string, number, boolean) |}")); REQUIRE(ttvC->instantiatedTypeParams.size() == 1); REQUIRE(ttvC->instantiatedTypePackParams.size() == 1); - CHECK_EQ(toString(ttvC->instantiatedTypeParams[0], {true}), "string"); - CHECK_EQ(toString(ttvC->instantiatedTypePackParams[0], {true}), "number, boolean"); + CHECK_EQ(toString(ttvC->instantiatedTypeParams[0], {true}), XorStr("string")); + CHECK_EQ(toString(ttvC->instantiatedTypePackParams[0], {true}), XorStr("number, boolean")); } TEST_CASE_FIXTURE(BuiltinsFixture, "type_alias_type_packs_import") @@ -346,8 +346,8 @@ export type Packed = { a: T, b: (U...) -> () } return {} )"; - CheckResult aResult = frontend.check("game/A"); - LUAU_REQUIRE_NO_ERRORS(aResult); + CheckResult aResult = frontend.check(XorStr("game/A")); + lluz_REQUIRE_NO_ERRORS(aResult); CheckResult bResult = check(R"( local Import = require(game.A) @@ -356,17 +356,17 @@ local b: Import.Packed local c: Import.Packed local d: { a: typeof(c) } )"); - LUAU_REQUIRE_NO_ERRORS(bResult); + lluz_REQUIRE_NO_ERRORS(bResult); - auto tf = lookupImportedType("Import", "Packed"); + auto tf = lookupImportedType(XorStr("Import", "Packed")); REQUIRE(tf); - CHECK_EQ(toString(*tf), "Packed"); - CHECK_EQ(toString(*tf, {true}), "{| a: T, b: (U...) -> () |}"); + CHECK_EQ(toString(*tf), XorStr("Packed")); + CHECK_EQ(toString(*tf, {true}), XorStr("{| a: T, b: (U...) -> () |}")); - CHECK_EQ(toString(requireType("a"), {true}), "{| a: number, b: () -> () |}"); - CHECK_EQ(toString(requireType("b"), {true}), "{| a: string, b: (number) -> () |}"); - CHECK_EQ(toString(requireType("c"), {true}), "{| a: string, b: (number, boolean) -> () |}"); - CHECK_EQ(toString(requireType("d")), "{| a: Packed |}"); + CHECK_EQ(toString(requireType(XorStr("a"), {true}), "{| a: number, b: () -> () |}")); + CHECK_EQ(toString(requireType(XorStr("b"), {true}), "{| a: string, b: (number) -> () |}")); + CHECK_EQ(toString(requireType(XorStr("c"), {true}), "{| a: string, b: (number, boolean) -> () |}")); + CHECK_EQ(toString(requireType(XorStr("d")), "{| a: Packed |}")); } TEST_CASE_FIXTURE(BuiltinsFixture, "type_pack_type_parameters") @@ -384,24 +384,24 @@ local a: Alias type B = Import.Packed type C = Import.Packed )"); - LUAU_REQUIRE_NO_ERRORS(cResult); + lluz_REQUIRE_NO_ERRORS(cResult); - auto tf = lookupType("Alias"); + auto tf = lookupType(XorStr("Alias")); REQUIRE(tf); - CHECK_EQ(toString(*tf), "Alias"); - CHECK_EQ(toString(*tf, {true}), "{| a: S, b: (T, R...) -> () |}"); + CHECK_EQ(toString(*tf), XorStr("Alias")); + CHECK_EQ(toString(*tf, {true}), XorStr("{| a: S, b: (T, R...) -> () |}")); - CHECK_EQ(toString(requireType("a"), {true}), "{| a: string, b: (number, boolean) -> () |}"); + CHECK_EQ(toString(requireType(XorStr("a"), {true}), "{| a: string, b: (number, boolean) -> () |}")); - tf = lookupType("B"); + tf = lookupType(XorStr("B")); REQUIRE(tf); - CHECK_EQ(toString(*tf), "B"); - CHECK_EQ(toString(*tf, {true}), "{| a: string, b: (X...) -> () |}"); + CHECK_EQ(toString(*tf), XorStr("B")); + CHECK_EQ(toString(*tf, {true}), XorStr("{| a: string, b: (X...) -> () |}")); - tf = lookupType("C"); + tf = lookupType(XorStr("C")); REQUIRE(tf); - CHECK_EQ(toString(*tf), "C"); - CHECK_EQ(toString(*tf, {true}), "{| a: string, b: (number, X...) -> () |}"); + CHECK_EQ(toString(*tf), XorStr("C")); + CHECK_EQ(toString(*tf, {true}), XorStr("{| a: string, b: (number, X...) -> () |}")); } TEST_CASE_FIXTURE(Fixture, "type_alias_type_packs_nested") @@ -413,13 +413,13 @@ type Packed3 = (Packed2, T...) -> (Packed2, T...) type Packed4 = (Packed3, T...) -> (Packed3, T...) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - auto tf = lookupType("Packed4"); + auto tf = lookupType(XorStr("Packed4")); REQUIRE(tf); CHECK_EQ(toString(*tf), "((((T...) -> (T...), T...) -> ((T...) -> (T...), T...), T...) -> (((T...) -> (T...), T...) -> ((T...) -> (T...), T...), T...), T...) -> " - "((((T...) -> (T...), T...) -> ((T...) -> (T...), T...), T...) -> (((T...) -> (T...), T...) -> ((T...) -> (T...), T...), T...), T...)"); + XorStr("((((T...) -> (T...), T...) -> ((T...) -> (T...), T...), T...) -> (((T...) -> (T...), T...) -> ((T...) -> (T...), T...), T...), T...)")); } TEST_CASE_FIXTURE(Fixture, "type_alias_type_pack_variadic") @@ -431,10 +431,10 @@ type D = X<...number> type E = X<(number, ...string)> )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(*lookupType("D")), "(...number) -> (string, ...number)"); - CHECK_EQ(toString(*lookupType("E")), "(number, ...string) -> (string, number, ...string)"); + CHECK_EQ(toString(*lookupType(XorStr("D")), "(...number) -> (string, ...number)")); + CHECK_EQ(toString(*lookupType(XorStr("E")), "(number, ...string) -> (string, number, ...string)")); } TEST_CASE_FIXTURE(Fixture, "type_alias_type_pack_multi") @@ -453,16 +453,16 @@ type H = W type I = W )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(*lookupType("A")), "(S...) -> (S...)"); - CHECK_EQ(toString(*lookupType("B")), "(number, ...string) -> (S...)"); + CHECK_EQ(toString(*lookupType(XorStr("A")), "(S...) -> (S...)")); + CHECK_EQ(toString(*lookupType(XorStr("B")), "(number, ...string) -> (S...)")); - CHECK_EQ(toString(*lookupType("E")), "(number) -> (S...)"); - CHECK_EQ(toString(*lookupType("F")), "(number) -> (string, S...)"); + CHECK_EQ(toString(*lookupType(XorStr("E")), "(number) -> (S...)")); + CHECK_EQ(toString(*lookupType(XorStr("F")), "(number) -> (string, S...)")); - CHECK_EQ(toString(*lookupType("H")), "(number, S...) -> (number, R...)"); - CHECK_EQ(toString(*lookupType("I")), "(number, string, S...) -> (number, R...)"); + CHECK_EQ(toString(*lookupType(XorStr("H")), "(number, S...) -> (number, R...)")); + CHECK_EQ(toString(*lookupType(XorStr("I")), "(number, string, S...) -> (number, R...)")); } TEST_CASE_FIXTURE(Fixture, "type_alias_type_pack_explicit") @@ -478,14 +478,14 @@ type E = X<(...number)> type F = X<(string, ...number)> )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(*lookupType("A")), "(S...) -> (S...)"); - CHECK_EQ(toString(*lookupType("B")), "() -> ()"); - CHECK_EQ(toString(*lookupType("C")), "(number) -> number"); - CHECK_EQ(toString(*lookupType("D")), "(number, string) -> (number, string)"); - CHECK_EQ(toString(*lookupType("E")), "(...number) -> (...number)"); - CHECK_EQ(toString(*lookupType("F")), "(string, ...number) -> (string, ...number)"); + CHECK_EQ(toString(*lookupType(XorStr("A")), "(S...) -> (S...)")); + CHECK_EQ(toString(*lookupType(XorStr("B")), "() -> ()")); + CHECK_EQ(toString(*lookupType(XorStr("C")), "(number) -> number")); + CHECK_EQ(toString(*lookupType(XorStr("D")), "(number, string) -> (number, string)")); + CHECK_EQ(toString(*lookupType(XorStr("E")), "(...number) -> (...number)")); + CHECK_EQ(toString(*lookupType(XorStr("F")), "(string, ...number) -> (string, ...number)")); } TEST_CASE_FIXTURE(Fixture, "type_alias_type_pack_explicit_multi") @@ -499,12 +499,12 @@ type C = Y<...string, (number, S...)> type D = Y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(*lookupType("A")), "(number, string) -> boolean"); - CHECK_EQ(toString(*lookupType("B")), "() -> ()"); - CHECK_EQ(toString(*lookupType("C")), "(...string) -> (number, S...)"); - CHECK_EQ(toString(*lookupType("D")), "(X...) -> (number, string, X...)"); + CHECK_EQ(toString(*lookupType(XorStr("A")), "(number, string) -> boolean")); + CHECK_EQ(toString(*lookupType(XorStr("B")), "() -> ()")); + CHECK_EQ(toString(*lookupType(XorStr("C")), "(...string) -> (number, S...)")); + CHECK_EQ(toString(*lookupType(XorStr("D")), "(X...) -> (number, string, X...)")); } TEST_CASE_FIXTURE(Fixture, "type_alias_type_pack_explicit_multi_tostring") @@ -516,10 +516,10 @@ local a: Y<(number, string), (boolean)> local b: Y<(), ()> )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Y<(number, string), (boolean)>"); - CHECK_EQ(toString(requireType("b")), "Y<(), ()>"); + CHECK_EQ(toString(requireType(XorStr("a")), "Y<(number, string), (boolean)>")); + CHECK_EQ(toString(requireType(XorStr("b")), "Y<(), ()>")); } TEST_CASE_FIXTURE(Fixture, "type_alias_backwards_compatible") @@ -533,11 +533,11 @@ type B = Y<(number), (boolean)> type C = Y<(number), boolean> )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(*lookupType("A")), "() -> number"); - CHECK_EQ(toString(*lookupType("B")), "(number) -> boolean"); - CHECK_EQ(toString(*lookupType("C")), "(number) -> boolean"); + CHECK_EQ(toString(*lookupType(XorStr("A")), "() -> number")); + CHECK_EQ(toString(*lookupType(XorStr("B")), "(number) -> boolean")); + CHECK_EQ(toString(*lookupType(XorStr("C")), "(number) -> boolean")); } TEST_CASE_FIXTURE(Fixture, "type_alias_type_packs_errors") @@ -547,56 +547,56 @@ type Packed = (T, U) -> (V...) local b: Packed )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Generic type 'Packed' expects at least 2 type arguments, but only 1 is specified"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Generic type 'Packed' expects at least 2 type arguments, but only 1 is specified")); result = check(R"( type Packed = (T, U) -> () type B = Packed )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Generic type 'Packed' expects 0 type pack arguments, but 1 is specified"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Generic type 'Packed' expects 0 type pack arguments, but 1 is specified")); result = check(R"( type Packed = (T...) -> (U...) type Other = Packed )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Type parameters must come before type pack parameters"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Type parameters must come before type pack parameters")); result = check(R"( type Packed = (T) -> U type Other = Packed )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Generic type 'Packed' expects 2 type arguments, but only 1 is specified"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Generic type 'Packed' expects 2 type arguments, but only 1 is specified")); result = check(R"( type Packed = (T...) -> T... local a: Packed )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Type parameter list is required"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Type parameter list is required")); result = check(R"( type Packed = (T...) -> (U...) type Other = Packed<> )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Generic type 'Packed' expects 2 type pack arguments, but none are specified"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Generic type 'Packed' expects 2 type pack arguments, but none are specified")); result = check(R"( type Packed = (T...) -> (U...) type Other = Packed )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Generic type 'Packed' expects 2 type pack arguments, but only 1 is specified"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Generic type 'Packed' expects 2 type pack arguments, but only 1 is specified")); } TEST_CASE_FIXTURE(Fixture, "type_alias_default_type_explicit") @@ -608,10 +608,10 @@ local a: Y = { a = 2, b = 3 } local b: Y = { a = 2, b = "s" } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Y"); - CHECK_EQ(toString(requireType("b")), "Y"); + CHECK_EQ(toString(requireType(XorStr("a")), "Y")); + CHECK_EQ(toString(requireType(XorStr("b")), "Y")); result = check(R"( type Y = { a: T } @@ -621,11 +621,11 @@ local b: Y<> = { a = "s" } local c: Y = { a = "s" } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Y"); - CHECK_EQ(toString(requireType("b")), "Y"); - CHECK_EQ(toString(requireType("c")), "Y"); + CHECK_EQ(toString(requireType(XorStr("a")), "Y")); + CHECK_EQ(toString(requireType(XorStr("b")), "Y")); + CHECK_EQ(toString(requireType(XorStr("c")), "Y")); } TEST_CASE_FIXTURE(Fixture, "type_alias_default_type_self") @@ -637,10 +637,10 @@ local a: Y = { a = 2, b = 3 } local b: Y = { a = "h", b = "s" } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Y"); - CHECK_EQ(toString(requireType("b")), "Y"); + CHECK_EQ(toString(requireType(XorStr("a")), "Y")); + CHECK_EQ(toString(requireType(XorStr("b")), "Y")); result = check(R"( type Y string> = { a: T, b: U } @@ -648,9 +648,9 @@ type Y string> = { a: T, b: U } local a: Y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Y string>"); + CHECK_EQ(toString(requireType(XorStr("a")), "Y string>")); } TEST_CASE_FIXTURE(Fixture, "type_alias_default_type_chained") @@ -662,10 +662,10 @@ local a: Y local b: Y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Y"); - CHECK_EQ(toString(requireType("b")), "Y"); + CHECK_EQ(toString(requireType(XorStr("a")), "Y")); + CHECK_EQ(toString(requireType(XorStr("b")), "Y")); } TEST_CASE_FIXTURE(Fixture, "type_alias_default_type_pack_explicit") @@ -675,9 +675,9 @@ type Y = { a: (T...) -> () } local a: Y<> )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Y"); + CHECK_EQ(toString(requireType(XorStr("a")), "Y")); } TEST_CASE_FIXTURE(Fixture, "type_alias_default_type_pack_self_ty") @@ -688,9 +688,9 @@ type Y = { a: T, b: (U...) -> T } local a: Y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Y"); + CHECK_EQ(toString(requireType(XorStr("a")), "Y")); } TEST_CASE_FIXTURE(Fixture, "type_alias_default_type_pack_self_tp") @@ -700,9 +700,9 @@ type Y = { a: (T...) -> U... } local a: Y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Y<(number, string), (number, string)>"); + CHECK_EQ(toString(requireType(XorStr("a")), "Y<(number, string), (number, string)>")); } TEST_CASE_FIXTURE(Fixture, "type_alias_default_type_pack_self_chained_tp") @@ -712,9 +712,9 @@ type Y = { a: (T...) -> U..., b: (T...) -> V... local a: Y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Y<(number, string), (number, string), (number, string)>"); + CHECK_EQ(toString(requireType(XorStr("a")), "Y<(number, string), (number, string), (number, string)>")); } TEST_CASE_FIXTURE(Fixture, "type_alias_default_mixed_self") @@ -727,12 +727,12 @@ local c: Y local d: Y ()> )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "Y"); - CHECK_EQ(toString(requireType("b")), "Y"); - CHECK_EQ(toString(requireType("c")), "Y"); - CHECK_EQ(toString(requireType("d")), "Y ()>"); + CHECK_EQ(toString(requireType(XorStr("a")), "Y")); + CHECK_EQ(toString(requireType(XorStr("b")), "Y")); + CHECK_EQ(toString(requireType(XorStr("c")), "Y")); + CHECK_EQ(toString(requireType(XorStr("d")), "Y ()>")); } TEST_CASE_FIXTURE(Fixture, "type_alias_default_type_errors") @@ -742,46 +742,46 @@ type Y = { a: T } local a: Y = { a = 2 } )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Unknown type 'T'"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Unknown type 'T'")); result = check(R"( type Y = { a: (T...) -> () } local a: Y<> )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Unknown type 'T'"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Unknown type 'T'")); result = check(R"( type Y = { a: (T) -> U... } local a: Y<...number> )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Generic type 'Y' expects at least 1 type argument, but none are specified"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Generic type 'Y' expects at least 1 type argument, but none are specified")); result = check(R"( type Packed = (T) -> T local a: Packed )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), "Type parameter list is required"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), XorStr("Type parameter list is required")); result = check(R"( type Y = { a: T } local a: Y )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); result = check(R"( type Y = { a: T } local a: Y<...number> )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "type_alias_default_export") @@ -798,8 +798,8 @@ export type H = { b: (T...) -> T... } return {} )"; - CheckResult resultTypes = frontend.check("Module/Types"); - LUAU_REQUIRE_NO_ERRORS(resultTypes); + CheckResult resultTypes = frontend.check(XorStr("Module/Types")); + lluz_REQUIRE_NO_ERRORS(resultTypes); fileResolver.source["Module/Users"] = R"( local Types = require(script.Parent.Types) @@ -815,18 +815,18 @@ local g: Types.G<...number> local h: Types.H<> )"; - CheckResult resultUsers = frontend.check("Module/Users"); - LUAU_REQUIRE_NO_ERRORS(resultUsers); + CheckResult resultUsers = frontend.check(XorStr("Module/Users")); + lluz_REQUIRE_NO_ERRORS(resultUsers); - CHECK_EQ(toString(requireType("Module/Users", "a")), "A"); - CHECK_EQ(toString(requireType("Module/Users", "b")), "B"); - CHECK_EQ(toString(requireType("Module/Users", "c")), "C string>"); - CHECK_EQ(toString(requireType("Module/Users", "d")), "D"); - CHECK_EQ(toString(requireType("Module/Users", "e")), "E"); - CHECK_EQ(toString(requireType("Module/Users", "eVoid")), "E<>"); - CHECK_EQ(toString(requireType("Module/Users", "f")), "F"); - CHECK_EQ(toString(requireType("Module/Users", "g")), "G<...number, ()>"); - CHECK_EQ(toString(requireType("Module/Users", "h")), "H<>"); + CHECK_EQ(toString(requireType(XorStr("Module/Users", "a")), "A")); + CHECK_EQ(toString(requireType(XorStr("Module/Users", "b")), "B")); + CHECK_EQ(toString(requireType(XorStr("Module/Users", "c")), "C string>")); + CHECK_EQ(toString(requireType(XorStr("Module/Users", "d")), "D")); + CHECK_EQ(toString(requireType(XorStr("Module/Users", "e")), "E")); + CHECK_EQ(toString(requireType(XorStr("Module/Users", "eVoid")), "E<>")); + CHECK_EQ(toString(requireType(XorStr("Module/Users", "f")), "F")); + CHECK_EQ(toString(requireType(XorStr("Module/Users", "g")), "G<...number, ()>")); + CHECK_EQ(toString(requireType(XorStr("Module/Users", "h")), "H<>")); } TEST_CASE_FIXTURE(Fixture, "type_alias_default_type_skip_brackets") @@ -836,9 +836,9 @@ type Y = (T...) -> number local a: Y )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(requireType("a")), "(...string) -> number"); + CHECK_EQ(toString(requireType(XorStr("a")), "(...string) -> number")); } TEST_CASE_FIXTURE(Fixture, "type_alias_defaults_confusing_types") @@ -849,10 +849,10 @@ type B = A type C = A )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(*lookupType("B"), {true}), "(string, ...any) -> (number, ...any)"); - CHECK_EQ(toString(*lookupType("C"), {true}), "(string, boolean) -> (number, boolean)"); + CHECK_EQ(toString(*lookupType(XorStr("B"), {true}), "(string, ...any) -> (number, ...any)")); + CHECK_EQ(toString(*lookupType(XorStr("C"), {true}), "(string, boolean) -> (number, boolean)")); } TEST_CASE_FIXTURE(Fixture, "type_alias_defaults_recursive_type") @@ -862,9 +862,9 @@ type F ()> = (K) -> V type R = { m: F } )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - CHECK_EQ(toString(*lookupType("R"), {true}), "t1 where t1 = {| m: (t1) -> (t1) -> () |}"); + CHECK_EQ(toString(*lookupType(XorStr("R"), {true}), "t1 where t1 = {| m: (t1) -> (t1) -> () |}")); } TEST_CASE_FIXTURE(Fixture, "pack_tail_unification_check") @@ -875,7 +875,7 @@ local b: () -> (number, ...boolean) a = b )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type '() -> (number, ...boolean)' could not be converted into '() -> (number, ...string)' caused by: Type 'boolean' could not be converted into 'string')"); @@ -890,7 +890,7 @@ TEST_CASE_FIXTURE(Fixture, "unifying_vararg_pack_with_fixed_length_pack_produces a(...) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); REQUIRE(bool(getMainModule()->getModuleScope()->varargPack)); @@ -949,7 +949,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "detect_cyclic_typepacks") ( ... ) "" )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "detect_cyclic_typepacks2") @@ -961,7 +961,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "detect_cyclic_typepacks2") end )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_SUITE_END(); diff --git a/tests/TypeInfer.unionTypes.test.cpp b/tests/TypeInfer.unionTypes.test.cpp index 8eb485e9..9773bf39 100644 --- a/tests/TypeInfer.unionTypes.test.cpp +++ b/tests/TypeInfer.unionTypes.test.cpp @@ -1,17 +1,16 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "Fixture.h" #include "doctest.h" -LUAU_FASTFLAG(LuauLowerBoundsCalculation) -LUAU_FASTFLAG(LuauSpecialTypesAsterisked) +lluz_FASTFLAG(LluLowerBoundsCalculation) -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("UnionTypes"); +TEST_SUITE_BEGIN(XorStr("UnionTypes")); TEST_CASE_FIXTURE(Fixture, "return_types_can_be_disjoint") { @@ -27,7 +26,7 @@ TEST_CASE_FIXTURE(Fixture, "return_types_can_be_disjoint") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); const FunctionTypeVar* utv = get(requireType("most_of_the_natural_numbers")); REQUIRE(utv != nullptr); @@ -39,7 +38,7 @@ TEST_CASE_FIXTURE(Fixture, "allow_specific_assign") local a:number|string = 22 )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "allow_more_specific_assign") @@ -49,7 +48,7 @@ TEST_CASE_FIXTURE(Fixture, "allow_more_specific_assign") local b:number|string|nil = a )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "disallow_less_specific_assign") @@ -60,7 +59,7 @@ TEST_CASE_FIXTURE(Fixture, "disallow_less_specific_assign") a = b )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); } TEST_CASE_FIXTURE(Fixture, "disallow_less_specific_assign2") @@ -82,7 +81,7 @@ TEST_CASE_FIXTURE(Fixture, "optional_arguments") f("s") )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "optional_arguments_table") @@ -92,7 +91,7 @@ TEST_CASE_FIXTURE(Fixture, "optional_arguments_table") a = {a="ok"} )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "optional_arguments_table2") @@ -111,7 +110,7 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "error_takes_optional_arguments") error("message", 2) )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "error_optional_argument_enforces_type") @@ -133,7 +132,7 @@ TEST_CASE_FIXTURE(Fixture, "index_on_a_union_type_with_property_guaranteed_to_ex local r = t.x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.numberType, *requireType("r")); } @@ -147,7 +146,7 @@ TEST_CASE_FIXTURE(Fixture, "index_on_a_union_type_with_mixed_types") local r = t.x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number | string", toString(requireType("r"))); } @@ -161,7 +160,7 @@ TEST_CASE_FIXTURE(Fixture, "index_on_a_union_type_works_at_arbitrary_depth") local r = t.x.y.z.thing )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number | string", toString(requireType("r"))); } @@ -175,7 +174,7 @@ TEST_CASE_FIXTURE(Fixture, "index_on_a_union_type_with_one_optional_property") local r = t.x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ("number?", toString(requireType("r"))); } @@ -189,21 +188,18 @@ TEST_CASE_FIXTURE(Fixture, "index_on_a_union_type_with_missing_property") local r = t.x )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); MissingUnionProperty* mup = get(result.errors[0]); REQUIRE(mup); CHECK_EQ(mup->type, requireType("t")); REQUIRE(mup->missing.size() == 1); - std::optional bTy = lookupType("B"); + std::optional bTy = lookupType(XorStr("B")); REQUIRE(bTy); CHECK_EQ(mup->missing[0], *bTy); - CHECK_EQ(mup->key, "x"); + CHECK_EQ(mup->key, XorStr("x")); - if (FFlag::LuauSpecialTypesAsterisked) - CHECK_EQ("*error-type*", toString(requireType("r"))); - else - CHECK_EQ("", toString(requireType("r"))); + CHECK_EQ("*unknown*", toString(requireType("r"))); } TEST_CASE_FIXTURE(Fixture, "index_on_a_union_type_with_one_property_of_type_any") @@ -216,7 +212,7 @@ TEST_CASE_FIXTURE(Fixture, "index_on_a_union_type_with_one_property_of_type_any" local r = t.x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); CHECK_EQ(*typeChecker.anyType, *requireType("r")); } @@ -237,7 +233,7 @@ TEST_CASE_FIXTURE(Fixture, "union_equality_comparisons") local z = a == c )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "optional_union_members") @@ -250,7 +246,7 @@ local bf = b local c = bf.a.y )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(*typeChecker.numberType, *requireType("c")); CHECK_EQ("Value of type 'A?' could be nil", toString(result.errors[0])); } @@ -265,7 +261,7 @@ TEST_CASE_FIXTURE(Fixture, "optional_union_functions") local c = b.foo(1, 2) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(*typeChecker.numberType, *requireType("c")); CHECK_EQ("Value of type 'A?' could be nil", toString(result.errors[0])); } @@ -280,7 +276,7 @@ local b: A? = a local c = b:foo(1, 2) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(*typeChecker.numberType, *requireType("c")); CHECK_EQ("Value of type 'A?' could be nil", toString(result.errors[0])); } @@ -294,7 +290,7 @@ local function f(a: number, b: typeof(x), c: typeof(x)) return -a end return f() )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); auto acm = get(result.errors[0]); REQUIRE(acm); @@ -312,7 +308,7 @@ local c = b.x local d = b.y )"); - LUAU_REQUIRE_ERROR_COUNT(3, result); + lluz_REQUIRE_ERROR_COUNT(3, result); CHECK_EQ("Value of type 'A?' could be nil", toString(result.errors[0])); CHECK_EQ("Value of type 'A?' could be nil", toString(result.errors[1])); CHECK_EQ("Key 'y' not found in table 'A'", toString(result.errors[2])); @@ -326,7 +322,7 @@ local a: A? = {1, 2, 3} local b = a[1] )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Value of type 'A?' could be nil", toString(result.errors[0])); } @@ -338,7 +334,7 @@ local a: A? = function(a) return -a end local b = a(4) )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Value of type '((number) -> number)?' could be nil", toString(result.errors[0])); } @@ -350,7 +346,7 @@ local a: A? = { x = 2 } a.x = 2 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Value of type 'A?' could be nil", toString(result.errors[0])); result = check(R"( @@ -359,8 +355,8 @@ local a: A? = { x = 2, y = 3 } a.x = 2 )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - if (FFlag::LuauLowerBoundsCalculation) + lluz_REQUIRE_ERROR_COUNT(1, result); + if (FFlag::LluLowerBoundsCalculation) CHECK_EQ("Value of type '{| x: number, y: number |}?' could be nil", toString(result.errors[0])); else CHECK_EQ("Value of type '({| x: number |} & {| y: number |})?' could be nil", toString(result.errors[0])); @@ -374,7 +370,7 @@ local a: A? = {1, 2, 3} local b = #a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ("Value of type 'A?' could be nil", toString(result.errors[0])); } @@ -395,7 +391,7 @@ local d = c.y local e = a.z )"); - LUAU_REQUIRE_ERROR_COUNT(4, result); + lluz_REQUIRE_ERROR_COUNT(4, result); CHECK_EQ("Key 'y' is missing from 'C', 'D' in the type 'A | B | C | D'", toString(result.errors[0])); CHECK_EQ("Value of type '(A | B | C | D)?' could be nil", toString(result.errors[1])); @@ -414,7 +410,7 @@ local y: { x: number, y: A | B } y = x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); result = check(R"( local x = { x = 3 } @@ -427,7 +423,7 @@ y.y = a y = x )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "unify_sealed_table_union_check") @@ -446,7 +442,7 @@ y.y = 5 local oh : boolean = t.y )"); - LUAU_REQUIRE_ERRORS(result); + lluz_REQUIRE_ERRORS(result); } TEST_CASE_FIXTURE(Fixture, "error_detailed_union_part") @@ -462,7 +458,7 @@ local a: XYZ local b: { w: number } = a )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type 'X | Y | Z' could not be converted into '{| w: number |}' caused by: Not all union options are compatible. Table type 'X' not compatible with type '{| w: number |}' because the former is missing field 'w')"); @@ -480,8 +476,8 @@ type XYZ = X | Y | Z local a: XYZ = { w = 4 } )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); - CHECK_EQ(toString(result.errors[0]), R"(Type 'a' could not be converted into 'X | Y | Z'; none of the union options are compatible)"); + lluz_REQUIRE_ERROR_COUNT(1, result); + CHECK_EQ(toString(result.errors[0]), RXorStr("(Type 'a' could not be converted into 'X | Y | Z'; none of the union options are compatible)")); } TEST_CASE_FIXTURE(Fixture, "error_detailed_optional") @@ -492,7 +488,7 @@ type X = { x: number } local a: X? = { w = 4 } )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); CHECK_EQ(toString(result.errors[0]), R"(Type 'a' could not be converted into 'X?' caused by: None of the union options are compatible. For example: Table type 'a' not compatible with type 'X' because the former is missing field 'x')"); @@ -511,7 +507,7 @@ TEST_CASE_FIXTURE(Fixture, "dont_allow_cyclic_unions_to_be_inferred") end )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); } TEST_CASE_FIXTURE(BuiltinsFixture, "table_union_write_indirect") @@ -530,15 +526,15 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "table_union_write_indirect") end )"); - LUAU_REQUIRE_ERROR_COUNT(1, result); + lluz_REQUIRE_ERROR_COUNT(1, result); // NOTE: union normalization will improve this message - if (FFlag::LuauLowerBoundsCalculation) + if (FFlag::LluLowerBoundsCalculation) CHECK_EQ(toString(result.errors[0]), "Type '(string) -> number' could not be converted into '(number) -> string'\n" "caused by:\n" - " Argument #1 type is not compatible. Type 'number' could not be converted into 'string'"); + XorStr(" Argument #1 type is not compatible. Type 'number' could not be converted into 'string'")); else CHECK_EQ(toString(result.errors[0]), - R"(Type '(string) -> number' could not be converted into '((number) -> string) | ((number) -> string)'; none of the union options are compatible)"); + RXorStr("(Type '(string) -> number' could not be converted into '((number) -> string) | ((number) -> string)'; none of the union options are compatible)")); } diff --git a/tests/TypePack.test.cpp b/tests/TypePack.test.cpp index 1087a24c..28a13250 100644 --- a/tests/TypePack.test.cpp +++ b/tests/TypePack.test.cpp @@ -1,12 +1,12 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" #include "Fixture.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; namespace { @@ -25,7 +25,7 @@ struct TypePackFixture TypePackId freshTypePack() { - typePacks.emplace_back(new TypePackVar{Unifiable::Free{TypeLevel{}}}); + typePacks.emplace_back(new TypePackVar{Unifiable::Free{{}}}); return typePacks.back().get(); } @@ -43,7 +43,7 @@ struct TypePackFixture } // namespace -TEST_SUITE_BEGIN("TypePackTests"); +TEST_SUITE_BEGIN(XorStr("TypePackTests")); TEST_CASE_FIXTURE(TypePackFixture, "type_pack_hello") { @@ -199,6 +199,8 @@ TEST_CASE_FIXTURE(TypePackFixture, "std_distance") TEST_CASE("content_reassignment") { + ScopedFastFlag lluzNonCopyableTypeVarFields{"lluzNonCopyableTypeVarFields", true}; + TypePackVar myError{Unifiable::Error{}, /*presistent*/ true}; TypeArena arena; diff --git a/tests/TypeVar.test.cpp b/tests/TypeVar.test.cpp index f4670048..589cb254 100644 --- a/tests/TypeVar.test.cpp +++ b/tests/TypeVar.test.cpp @@ -1,17 +1,17 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Scope.h" -#include "Luau/TypeInfer.h" -#include "Luau/TypeVar.h" -#include "Luau/VisitTypeVar.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Scope.h" +#include "lluz/TypeInfer.h" +#include "lluz/TypeVar.h" +#include "lluz/VisitTypeVar.h" #include "Fixture.h" #include "ScopedFlags.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -TEST_SUITE_BEGIN("TypeVarTests"); +TEST_SUITE_BEGIN(XorStr("TypeVarTests")); TEST_CASE_FIXTURE(Fixture, "primitives_are_equal") { @@ -79,7 +79,7 @@ TEST_CASE_FIXTURE(Fixture, "return_type_of_function_is_parenthesized_if_tail_is_ auto returnsTwo = TypeVar(FunctionTypeVar(typeChecker.globalScope->level, &emptyArgumentPack, &returnPack)); std::string res = toString(&returnsTwo); - CHECK_EQ(res, "() -> (number, a...)"); + CHECK_EQ(res, XorStr("() -> (number, a...)")); } TEST_CASE_FIXTURE(Fixture, "subset_check") @@ -266,17 +266,17 @@ TEST_CASE_FIXTURE(Fixture, "substitution_skip_failure") TEST_CASE("tagging_tables") { TypeVar ttv{TableTypeVar{}}; - CHECK(!Luau::hasTag(&ttv, "foo")); - Luau::attachTag(&ttv, "foo"); - CHECK(Luau::hasTag(&ttv, "foo")); + CHECK(!lluz::hasTag(&ttv, "foo")); + lluz::attachTag(&ttv, XorStr("foo")); + CHECK(lluz::hasTag(&ttv, "foo")); } TEST_CASE("tagging_classes") { TypeVar base{ClassTypeVar{"Base", {}, std::nullopt, std::nullopt, {}, nullptr, "Test"}}; - CHECK(!Luau::hasTag(&base, "foo")); - Luau::attachTag(&base, "foo"); - CHECK(Luau::hasTag(&base, "foo")); + CHECK(!lluz::hasTag(&base, "foo")); + lluz::attachTag(&base, XorStr("foo")); + CHECK(lluz::hasTag(&base, "foo")); } TEST_CASE("tagging_subclasses") @@ -284,33 +284,33 @@ TEST_CASE("tagging_subclasses") TypeVar base{ClassTypeVar{"Base", {}, std::nullopt, std::nullopt, {}, nullptr, "Test"}}; TypeVar derived{ClassTypeVar{"Derived", {}, &base, std::nullopt, {}, nullptr, "Test"}}; - CHECK(!Luau::hasTag(&base, "foo")); - CHECK(!Luau::hasTag(&derived, "foo")); + CHECK(!lluz::hasTag(&base, "foo")); + CHECK(!lluz::hasTag(&derived, "foo")); - Luau::attachTag(&base, "foo"); - CHECK(Luau::hasTag(&base, "foo")); - CHECK(Luau::hasTag(&derived, "foo")); + lluz::attachTag(&base, XorStr("foo")); + CHECK(lluz::hasTag(&base, "foo")); + CHECK(lluz::hasTag(&derived, "foo")); - Luau::attachTag(&derived, "bar"); - CHECK(!Luau::hasTag(&base, "bar")); - CHECK(Luau::hasTag(&derived, "bar")); + lluz::attachTag(&derived, XorStr("bar")); + CHECK(!lluz::hasTag(&base, "bar")); + CHECK(lluz::hasTag(&derived, "bar")); } TEST_CASE("tagging_functions") { TypePackVar empty{TypePack{}}; TypeVar ftv{FunctionTypeVar{&empty, &empty}}; - CHECK(!Luau::hasTag(&ftv, "foo")); - Luau::attachTag(&ftv, "foo"); - CHECK(Luau::hasTag(&ftv, "foo")); + CHECK(!lluz::hasTag(&ftv, "foo")); + lluz::attachTag(&ftv, XorStr("foo")); + CHECK(lluz::hasTag(&ftv, "foo")); } TEST_CASE("tagging_props") { Property prop{}; - CHECK(!Luau::hasTag(prop, "foo")); - Luau::attachTag(prop, "foo"); - CHECK(Luau::hasTag(prop, "foo")); + CHECK(!lluz::hasTag(prop, "foo")); + lluz::attachTag(prop, XorStr("foo")); + CHECK(lluz::hasTag(prop, "foo")); } struct VisitCountTracker final : TypeVarOnceVisitor @@ -352,9 +352,9 @@ TEST_CASE_FIXTURE(Fixture, "visit_once") type T = { a: number, b: () -> () } local b: (T, T, T) -> T )"); - LUAU_REQUIRE_NO_ERRORS(result); + lluz_REQUIRE_NO_ERRORS(result); - TypeId bType = requireType("b"); + TypeId bType = requireType(XorStr("b")); VisitCountTracker tester; tester.traverse(bType); @@ -418,6 +418,8 @@ TEST_CASE("proof_that_isBoolean_uses_all_of") TEST_CASE("content_reassignment") { + ScopedFastFlag lluzNonCopyableTypeVarFields{"lluzNonCopyableTypeVarFields", true}; + TypeVar myAny{AnyTypeVar{}, /*presistent*/ true}; myAny.normal = true; myAny.documentationSymbol = "@global/any"; @@ -430,7 +432,7 @@ TEST_CASE("content_reassignment") CHECK(get(futureAny) != nullptr); CHECK(!futureAny->persistent); CHECK(futureAny->normal); - CHECK(futureAny->documentationSymbol == "@global/any"); + CHECK(futureAny->documentationSymbol == XorStr("@global/any")); CHECK(futureAny->owningArena == &arena); } diff --git a/tests/Variant.test.cpp b/tests/Variant.test.cpp index aa0731ca..8a354ba9 100644 --- a/tests/Variant.test.cpp +++ b/tests/Variant.test.cpp @@ -1,12 +1,12 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Variant.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Variant.h" #include #include #include "doctest.h" -using namespace Luau; +using namespace lluz; struct Foo { @@ -32,7 +32,7 @@ struct Bar int Bar::count = 0; -TEST_SUITE_BEGIN("Variant"); +TEST_SUITE_BEGIN(XorStr("Variant")); TEST_CASE("DefaultCtor") { @@ -94,42 +94,42 @@ TEST_CASE("NonPOD") std::string s1 = "hello"; Variant v1 = s1; - CHECK(*get_if(&v1) == "hello"); + CHECK(*get_if(&v1) == XorStr("hello")); // initialize (move) - Variant v2 = std::string("hello"); + Variant v2 = std::string(XorStr("hello")); - CHECK(*get_if(&v2) == "hello"); + CHECK(*get_if(&v2) == XorStr("hello")); // move-assign - v2 = std::string("this is a long string that doesn't fit into the small buffer"); + v2 = std::string(XorStr("this is a long string that doesn't fit into the small buffer")); - CHECK(*get_if(&v2) == "this is a long string that doesn't fit into the small buffer"); + CHECK(*get_if(&v2) == XorStr("this is a long string that doesn't fit into the small buffer")); // copy-assign - std::string s2("this is another long string, and this time we're copying it"); + std::string s2(XorStr("this is another long string, and this time we're copying it")); v2 = s2; - CHECK(*get_if(&v2) == "this is another long string, and this time we're copying it"); + CHECK(*get_if(&v2) == XorStr("this is another long string, and this time we're copying it")); // copy ctor Variant v3 = v2; - CHECK(*get_if(&v2) == "this is another long string, and this time we're copying it"); - CHECK(*get_if(&v3) == "this is another long string, and this time we're copying it"); + CHECK(*get_if(&v2) == XorStr("this is another long string, and this time we're copying it")); + CHECK(*get_if(&v3) == XorStr("this is another long string, and this time we're copying it")); // move ctor Variant v4 = std::move(v3); - CHECK(*get_if(&v2) == "this is another long string, and this time we're copying it"); - CHECK(*get_if(&v3) == ""); // moved-from variant has an empty string now - CHECK(*get_if(&v4) == "this is another long string, and this time we're copying it"); + CHECK(*get_if(&v2) == XorStr("this is another long string, and this time we're copying it")); + CHECK(*get_if(&v3) == XorStr("")); // moved-from variant has an empty string now + CHECK(*get_if(&v4) == XorStr("this is another long string, and this time we're copying it")); } TEST_CASE("Equality") { - Variant v1 = std::string("hi"); - Variant v2 = std::string("me"); + Variant v1 = std::string(XorStr("hi")); + Variant v2 = std::string(XorStr("me")); Variant v3 = 1; Variant v4 = 0; Variant v5; @@ -169,7 +169,7 @@ struct IncrementVisitor TEST_CASE("Visit") { - Variant v1 = std::string("123"); + Variant v1 = std::string(XorStr("123")); Variant v2 = 45; const Variant& v1c = v1; const Variant& v2c = v2; @@ -186,19 +186,19 @@ TEST_CASE("Visit") r1 += ToStringVisitor()(v); }, v2c); - CHECK(r1 == "12345"); + CHECK(r1 == XorStr("12345")); // value-returning visitor, const variants std::string r2; r2 += visit(ToStringVisitor(), v1c); r2 += visit(ToStringVisitor(), v2c); - CHECK(r2 == "12345"); + CHECK(r2 == XorStr("12345")); // void-returning visitor, mutable variant visit(IncrementVisitor(), v1); visit(IncrementVisitor(), v2); - CHECK(visit(ToStringVisitor(), v1) == "1231"); - CHECK(visit(ToStringVisitor(), v2) == "46"); + CHECK(visit(ToStringVisitor(), v1) == XorStr("1231")); + CHECK(visit(ToStringVisitor(), v2) == XorStr("46")); // value-returning visitor, mutable variant std::string r3; @@ -214,7 +214,7 @@ TEST_CASE("Visit") return ToStringVisitor()(v); }, v2); - CHECK(r3 == "1231147"); + CHECK(r3 == XorStr("1231147")); } TEST_SUITE_END(); diff --git a/tests/VisitTypeVar.test.cpp b/tests/VisitTypeVar.test.cpp index 4fba694a..887f7f6b 100644 --- a/tests/VisitTypeVar.test.cpp +++ b/tests/VisitTypeVar.test.cpp @@ -1,39 +1,39 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details #include "Fixture.h" -#include "Luau/RecursionCounter.h" +#include "lluz/RecursionCounter.h" #include "doctest.h" -using namespace Luau; +using namespace lluz; -LUAU_FASTINT(LuauVisitRecursionLimit) +lluz_FASTINT(LluVisitRecursionLimit) -TEST_SUITE_BEGIN("VisitTypeVar"); +TEST_SUITE_BEGIN(XorStr("VisitTypeVar")); TEST_CASE_FIXTURE(Fixture, "throw_when_limit_is_exceeded") { - ScopedFastInt sfi{"LuauVisitRecursionLimit", 3}; + ScopedFastInt sfi{"lluzVisitRecursionLimit", 3}; CheckResult result = check(R"( local t : {a: {b: {c: {d: {e: boolean}}}}} )"); - TypeId tType = requireType("t"); + TypeId tType = requireType(XorStr("t")); CHECK_THROWS_AS(toString(tType), RecursionLimitException); } TEST_CASE_FIXTURE(Fixture, "dont_throw_when_limit_is_high_enough") { - ScopedFastInt sfi{"LuauVisitRecursionLimit", 8}; + ScopedFastInt sfi{"lluzVisitRecursionLimit", 8}; CheckResult result = check(R"( local t : {a: {b: {c: {d: {e: boolean}}}}} )"); - TypeId tType = requireType("t"); + TypeId tType = requireType(XorStr("t")); (void)toString(tType); } diff --git a/tests/conformance/nextvar.lua b/tests/conformance/nextvar.lua new file mode 100644 index 00000000..93c4ddf7 --- /dev/null +++ b/tests/conformance/nextvar.lua @@ -0,0 +1,595 @@ +-- This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +-- This file is based on Lua 5.x tests -- https://github.com/lua/lua/tree/master/testes +print('testing tables, next, and for') + +local unpack = table.unpack + +-- testing table.insert return value +assert(select('#', table.insert({}, 42)) == 0) + +local a = {} + +-- make sure table has lots of space in hash part +for i=1,100 do a[i.."+"] = true end +for i=1,100 do a[i.."+"] = nil end +-- fill hash part with numeric indices testing size operator +for i=1,100 do + a[i] = true + assert(#a == i) +end + + +if T then +-- testing table sizes + +local l2 = math.log(2) +local function log2 (x) return math.log(x)/l2 end + +local function mp2 (n) -- minimum power of 2 >= n + local mp = 2^math.ceil(log2(n)) + assert(n == 0 or (mp/2 < n and n <= mp)) + return mp +end + +local function fb (n) + local r, nn = T.int2fb(n) + assert(r < 256) + return nn +end + +-- test fb function +local a = 1 +local lim = 2^30 +while a < lim do + local n = fb(a) + assert(a <= n and n <= a*1.125) + a = math.ceil(a*1.3) +end + + +local function check (t, na, nh) + local a, h = T.querytab(t) + if a ~= na or h ~= nh then + print(na, nh, a, h) + assert(nil) + end +end + +-- testing constructor sizes +local lim = 40 +local s = 'return {' +for i=1,lim do + s = s..i..',' + local s = s + for k=0,lim do + local t = loadstring(s..'}')() + assert(#t == i) + check(t, fb(i), mp2(k)) + s = string.format('%sa%d=%d,', s, k, k) + end +end + + +-- tests with unknown number of elements +local a = {} +for i=1,lim do a[i] = i end -- build auxiliary table +for k=0,lim do + local a = {unpack(a,1,k)} + assert(#a == k) + check(a, k, 0) + a = {1,2,3,unpack(a,1,k)} + check(a, k+3, 0) + assert(#a == k + 3) +end + + +print'+' + +-- testing tables dynamically built +local lim = 130 +local a = {}; a[2] = 1; check(a, 0, 1) +a = {}; a[0] = 1; check(a, 0, 1); a[2] = 1; check(a, 0, 2) +a = {}; a[0] = 1; a[1] = 1; check(a, 1, 1) +a = {} +for i = 1,lim do + a[i] = 1 + assert(#a == i) + check(a, mp2(i), 0) +end + +a = {} +for i = 1,lim do + a['a'..i] = 1 + assert(#a == 0) + check(a, 0, mp2(i)) +end + +a = {} +for i=1,16 do a[i] = i end +check(a, 16, 0) +for i=1,11 do a[i] = nil end +for i=30,40 do a[i] = nil end -- force a rehash (?) +check(a, 0, 8) +a[10] = 1 +for i=30,40 do a[i] = nil end -- force a rehash (?) +check(a, 0, 8) +for i=1,14 do a[i] = nil end +for i=30,50 do a[i] = nil end -- force a rehash (?) +check(a, 0, 4) + +-- reverse filling +for i=1,lim do + local a = {} + for i=i,1,-1 do a[i] = i end -- fill in reverse + check(a, mp2(i), 0) +end + +-- size tests for vararg +lim = 35 +function foo (n, ...) + local arg = {...} + check(arg, n, 0) + assert(select('#', ...) == n) + arg[n+1] = true + check(arg, mp2(n+1), 0) + arg.x = true + check(arg, mp2(n+1), 1) +end +local a = {} +for i=1,lim do a[i] = true; foo(i, unpack(a)) end + +end + + +-- test size operation on empty tables +assert(#{} == 0) +assert(#{nil} == 0) +assert(#{nil, nil} == 0) +assert(#{nil, nil, nil} == 0) +assert(#{nil, nil, nil, nil} == 0) +print'+' + + +local nofind = {} + +a,b,c = 1,2,3 +a,b,c = nil + +local function find (name) + local n,v + while 1 do + n,v = next(_G, n) + if not n then return nofind end + assert(v ~= nil) + if n == name then return v end + end +end + +local function find1 (name) + for n,v in pairs(_G) do + if n==name then return v end + end + return nil -- not found +end + +do -- create 10000 new global variables + for i=1,10000 do _G[i] = i end +end + + +a = {x=90, y=8, z=23} +assert(table.foreach(a, function(i,v) if i=='x' then return v end end) == 90) +assert(table.foreach(a, function(i,v) if i=='a' then return v end end) == nil) +table.foreach({}, error) + +table.foreachi({x=10, y=20}, error) +local a = {n = 1} +table.foreachi({n=3}, function (i, v) + assert(a.n == i and not v) + a.n=a.n+1 +end) +a = {10,20,30,nil,50} +table.foreachi(a, function (i,v) assert(a[i] == v) end) +assert(table.foreachi({'a', 'b', 'c'}, function (i,v) + if i==2 then return v end + end) == 'b') + + +-- assert(print==find("print") and print == find1("print")) +-- assert(_G["print"]==find("print")) +-- assert(assert==find1("assert")) +assert(nofind==find("return")) +assert(not find1("return")) +_G["ret" .. "urn"] = nil +assert(nofind==find("return")) +_G["xxx"] = 1 +-- assert(xxx==find("xxx")) +print('+') + +a = {} +for i=0,10000 do + if i % 10 ~= 0 then + a['x'..i] = i + end +end + +n = {n=0} +for i,v in pairs(a) do + n.n = n.n+1 + assert(i and v and a[i] == v) +end +assert(n.n == 9000) +a = nil + +-- remove those 10000 new global variables +for i=1,10000 do _G[i] = nil end + +do -- clear global table + local a = {} + local preserve = {io = 1, string = 1, debug = 1, os = 1, + coroutine = 1, table = 1, math = 1} + for n,v in pairs(_G) do a[n]=v end + for n,v in pairs(a) do + if not preserve[n] and type(v) ~= "function" and + not string.find(n, "^[%u_]") then + _G[n] = nil + end + collectgarbage() + end +end + +local function foo () + local getfenv, setfenv, assert, next = + getfenv, setfenv, assert, next + local n = {gl1=3} + setfenv(foo, n) + assert(getfenv(foo) == getfenv(1)) + assert(getfenv(foo) == n) + assert(print == nil and gl1 == 3) + gl1 = nil + gl = 1 + assert(n.gl == 1 and next(n, 'gl') == nil) +end +foo() + +print'+' + +local function checknext (a) + local b = {} + table.foreach(a, function (k,v) b[k] = v end) + for k,v in pairs(b) do assert(a[k] == v) end + for k,v in pairs(a) do assert(b[k] == v) end + b = {} + do local k,v = next(a); while k do b[k] = v; k,v = next(a,k) end end + for k,v in pairs(b) do assert(a[k] == v) end + for k,v in pairs(a) do assert(b[k] == v) end +end + +checknext{1,x=1,y=2,z=3} +checknext{1,2,x=1,y=2,z=3} +checknext{1,2,3,x=1,y=2,z=3} +checknext{1,2,3,4,x=1,y=2,z=3} +checknext{1,2,3,4,5,x=1,y=2,z=3} + +assert(table.getn{} == 0) +assert(table.getn{[-1] = 2} == 0) +assert(table.getn{1,2,3,nil,nil} == 3) +for i=0,40 do + local a = {} + for j=1,i do a[j]=j end + assert(table.getn(a) == i) +end + + +assert(table.maxn{} == 0) +assert(table.maxn{["1000"] = true} == 0) +assert(table.maxn{["1000"] = true, [24.5] = 3} == 24.5) +assert(table.maxn{[1000] = true} == 1000) +assert(table.maxn{[10] = true, [100*math.pi] = print} == 100*math.pi) + + +-- int overflow +a = {} +for i=0,50 do a[math.pow(2,i)] = true end +assert(a[table.getn(a)]) + +print("+") + + +-- erasing values +local t = {[{1}] = 1, [{2}] = 2, [string.rep("x ", 4)] = 3, + [100.3] = 4, [4] = 5} + +local n = 0 +for k, v in pairs( t ) do + n = n+1 + assert(t[k] == v) + t[k] = nil + collectgarbage() + assert(t[k] == nil) +end +assert(n == 5) + + +local function test (a) + table.insert(a, 10); table.insert(a, 2, 20); + table.insert(a, 1, -1); table.insert(a, 40); + table.insert(a, table.getn(a)+1, 50) + table.insert(a, 2, -2) + assert(table.remove(a,1) == -1) + assert(table.remove(a,1) == -2) + assert(table.remove(a,1) == 10) + assert(table.remove(a,1) == 20) + assert(table.remove(a,1) == 40) + assert(table.remove(a,1) == 50) + assert(table.remove(a,1) == nil) +end + +a = {n=0, [-7] = "ban"} +test(a) +assert(a.n == 0 and a[-7] == "ban") + +a = {[-7] = "ban"}; +test(a) +assert(a.n == nil and table.getn(a) == 0 and a[-7] == "ban") + + +table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1) +assert(table.remove(a) == 10) +assert(table.remove(a) == 20) +assert(table.remove(a) == -1) + +a = {'c', 'd'} +table.insert(a, 3, 'a') +table.insert(a, 'b') +assert(table.remove(a, 1) == 'c') +assert(table.remove(a, 1) == 'd') +assert(table.remove(a, 1) == 'a') +assert(table.remove(a, 1) == 'b') +assert(table.getn(a) == 0 and a.n == nil) +print("+") + +-- out of range insertion +a = {1, 2, 3} +table.insert(a, 0, 0) +assert(a[0] == 0 and table.concat(a) == "123") +table.insert(a, 10, 10) +assert(a[0] == 0 and table.concat(a) == "123" and table.maxn(a) == 10 and a[10] == 10) +table.insert(a, -10^9, 42) +assert(a[0] == 0 and table.concat(a) == "123" and table.maxn(a) == 10 and a[10] == 10 and a[-10^9] == 42) +table.insert(a, 0 / 0, 42) -- platform-dependent behavior atm so hard to validate + +a = {} +for i=1,1000 do + a[i] = i; a[i-1] = nil +end +assert(next(a,nil) == 1000 and next(a,1000) == nil) + +assert(next({}) == nil) +assert(next({}, nil) == nil) + +-- testing table.create and table.find +do + local t = table.create(5) + assert(#t == 0) -- filled with nil! + t[5] = 5 + assert(#t == 5) -- magic + + local t2 = table.create(5, "nice") + assert(table.concat(t2,"!") == "nice!nice!nice!nice!nice") + + assert(table.find(t2, "nice") == 1) + assert(table.find(t2, "nice", 5) == 5) + assert(table.find(t2, "nice", 6) == nil) + + assert(table.find({false, true}, true) == 2) + + -- make sure table.find checks the hash portion as well by constructing a table literal that forces the value into the hash part + assert(table.find({[(1)] = true}, true) == 1) +end + +-- test indexing with strings that have zeroes embedded in them +do + local t = {} + t['start\0end'] = 1 + t['start'] = 2 + assert(t['start\0end'] == 1) + assert(t['start'] == 2) +end + +-- test table freezing +do + local t = {} + assert(not table.isfrozen(t)) + t[1] = 1 + t.a = 2 + + -- basic freeze test to validate invariants + assert(table.freeze(t) == t) + assert(table.isfrozen(t)) + assert(not pcall(rawset, t, 1, 2)) + assert(not pcall(rawset, t, "a", 2)) + assert(not pcall(function() t.a = 3 end)) + assert(not pcall(function() t[1] = 3 end)) + assert(not pcall(setmetatable, t, {})) + assert(not pcall(table.freeze, t)) -- already frozen + + -- can't freeze tables with protected metatable + local t = {} + setmetatable(t, { __metatable = "nope" }) + assert(not pcall(table.freeze, t)) + assert(not table.isfrozen(t)) + + -- note that it's valid to freeze a table with a metatable and protect it later, freeze doesn't freeze metatable automatically + local mt = {} + local t = setmetatable({}, mt) + table.freeze(t) + mt.__metatable = "nope" + assert(table.isfrozen(t)) + assert(getmetatable(t) == "nope") +end + +-- test #t +do + local t = table.create(10, 1) + assert(#t == 10) + t[5] = nil + assert(#t == 10) + t[10] = nil + assert(#t == 9) + t[9] = nil + t[8] = nil + assert(#t == 7) + + t = table.create(10) + assert(#t == 0) + t[1] = 1 + assert(#t == 1) + t[2] = 1 + assert(#t == 2) + t[3] = 1 + t[4] = 1 + assert(#t == 4) + + t = table.create(10) + assert(#t == 0) + table.insert(t, 1) + assert(#t == 1) + table.insert(t, 1) + assert(#t == 2) + table.insert(t, 1) + table.insert(t, 1) + assert(#t == 4) + + t = table.create(10, 1) + assert(#t == 10) + table.remove(t) + assert(#t == 9) + table.remove(t) + table.remove(t) + assert(#t == 7) +end + +-- test clone +do + local t = {a = 1, b = 2, 3, 4, 5} + local tt = table.clone(t) + + assert(#tt == 3) + assert(tt.a == 1 and tt.b == 2) + + t.c = 3 + assert(tt.c == nil) + + t = table.freeze({"test"}) + tt = table.clone(t) + assert(table.isfrozen(t) and not table.isfrozen(tt)) + + t = setmetatable({}, {}) + tt = table.clone(t) + assert(getmetatable(t) == getmetatable(tt)) + + t = setmetatable({}, {__metatable = "protected"}) + assert(not pcall(table.clone, t)) + + function order(t) + local r = '' + for k,v in pairs(t) do + r ..= tostring(v) + end + return v + end + + t = {a = 1, b = 2, c = 3, d = 4, e = 5, f = 6} + tt = table.clone(t) + assert(order(t) == order(tt)) + + assert(not pcall(table.clone)) + assert(not pcall(table.clone, 42)) +end + +-- test boundary invariant maintenance during rehash +do + local arr = table.create(5, 42) + + arr[1] = nil + arr.a = 'a' -- trigger rehash + + assert(#arr == 5) -- technically 0 is also valid, but it happens to be 5 because array capacity is 5 +end + +-- test boundary invariant maintenance when replacing hash keys +do + local arr = {} + arr.a = 'a' + arr.a = nil + arr[1] = 1 -- should rehash and resize array part, otherwise # won't find the boundary in array part + + assert(#arr == 1) +end + +-- test boundary invariant maintenance when table is filled from the end +do + local arr = {} + for i=5,2,-1 do + arr[i] = i + assert(#arr == 0) + end + arr[1] = 1 + assert(#arr == 5) +end + +-- test boundary invariant maintenance when table is filled using SETLIST opcode +do + local arr = {[2]=2,1} + assert(#arr == 2) +end + +-- test boundary invariant maintenance when table is filled using table.move +do + local t1 = {1, 2, 3, 4, 5} + local t2 = {[6] = 6} + + table.move(t1, 1, 5, 1, t2) + assert(#t2 == 6) +end + +-- test table.unpack fastcall for rejecting large unpacks +do + local ok, res = pcall(function() + local a = table.create(7999, 0) + local b = table.create(8000, 0) + + local at = { table.unpack(a) } + local bt = { table.unpack(b) } + end) + + assert(not ok) +end + +-- test iteration with lightuserdata keys +do + function countud() + local t = {} + t[makelud(1)] = 1 + t[makelud(2)] = 2 + + local count = 0 + for k,v in pairs(t) do + count += v + end + + return count + end + + assert(countud() == 3) +end + +-- test iteration with lightuserdata keys with a substituted environment +do + local env = { makelud = makelud, pairs = pairs } + setfenv(countud, env) + assert(countud() == 3) +end + +return"OK" diff --git a/tests/conformance/vector.lua b/tests/conformance/vector.lua index 6164e929..22d6adfc 100644 --- a/tests/conformance/vector.lua +++ b/tests/conformance/vector.lua @@ -101,20 +101,4 @@ if vector_size == 4 then assert(vector(1, 2, 3, 4).W == 4) end --- negative zero should hash the same as zero --- note: our earlier test only really checks the low hash bit, so in absence of perfect avalanche it's insufficient -do - local larget = {} - for i = 1, 2^14 do - larget[vector(0, 0, i)] = true - end - - larget[vector(0, 0, 0)] = 42 - - assert(larget[vector(0, 0, 0)] == 42) - assert(larget[vector(0, 0, -0)] == 42) - assert(larget[vector(0, -0, 0)] == 42) - assert(larget[vector(-0, 0, 0)] == 42) -end - return 'OK' diff --git a/tests/main.cpp b/tests/main.cpp index 40ccd0b3..6876af28 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -1,5 +1,5 @@ -// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details -#include "Luau/Common.h" +// This file is part of the lluz programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lluz/Common.h" #define DOCTEST_CONFIG_IMPLEMENT // Our calls to parseOption/parseFlag don't provide a prefix so set the prefix to the empty string. @@ -23,13 +23,10 @@ #include -// Indicates if verbose output is enabled; can be overridden via --verbose -// Currently, this enables output from 'print', but other verbose output could be enabled eventually. +// Indicates if verbose output is enabled. +// Currently, this enables output from lua's 'print', but other verbose output could be enabled eventually. bool verbose = false; -// Default optimization level for conformance test; can be overridden via -On -int optimizationLevel = 1; - static bool skipFastFlag(const char* flagName) { if (strncmp(flagName, "Test", 4) == 0) @@ -61,9 +58,9 @@ static bool debuggerPresent() static int testAssertionHandler(const char* expr, const char* file, int line, const char* function) { if (debuggerPresent()) - LUAU_DEBUGBREAK(); + lluz_DEBUGBREAK(); - ADD_FAIL_AT(file, line, "Assertion failed: ", std::string(expr)); + ADD_FAIL_AT(file, line, "Assertion failed: ", expr); return 1; } @@ -103,7 +100,7 @@ struct BoostLikeReporter : doctest::IReporter // called when a test case has ended void test_case_end(const doctest::CurrentTestCaseStats& tc) override { - LUAU_ASSERT(currentTest); + lluz_ASSERT(currentTest); printf("Leaving test case \"%s\"\n", currentTest->m_name); printf("Leaving test suite \"%s\"\n", currentTest->m_test_suite); @@ -114,7 +111,7 @@ struct BoostLikeReporter : doctest::IReporter // called when an exception is thrown from the test case (or it crashes) void test_case_exception(const doctest::TestCaseException& e) override { - LUAU_ASSERT(currentTest); + lluz_ASSERT(currentTest); printf("%s(%d): FATAL: Unhandled exception %s\n", currentTest->m_file.c_str(), currentTest->m_line, e.error_string.c_str()); } @@ -174,7 +171,7 @@ static FValueResult parseFFlag(std::string_view view) { // If we have a flag name but there's no provided value, we default to true. auto [name, value] = parseFValueHelper(view); - bool state = value ? *value == "true" : true; + bool state = value ? *value == XorStr("true") : true; if (value && value != "true" && value != "false") std::cerr << "Ignored '" << name << "' because '" << *value << "' is not a valid FFlag state." << std::endl; @@ -184,7 +181,7 @@ static FValueResult parseFFlag(std::string_view view) template static void setFastValue(const std::string& name, T value) { - for (Luau::FValue* fvalue = Luau::FValue::list; fvalue; fvalue = fvalue->next) + for (lluz::FValue* fvalue = lluz::FValue::list; fvalue; fvalue = fvalue->next) if (fvalue->name == name) fvalue->value = value; } @@ -194,12 +191,12 @@ static void setFastFlags(const std::vector& flags) for (const doctest::String& flag : flags) { std::string_view view = flag.c_str(); - if (view == "true" || view == "false") + if (view == XorStr("true") || view == XorStr("false")) { - for (Luau::FValue* flag = Luau::FValue::list; flag; flag = flag->next) + for (lluz::FValue* flag = lluz::FValue::list; flag; flag = flag->next) { if (!skipFastFlag(flag->name)) - flag->value = view == "true"; + flag->value = view == XorStr("true"); } continue; @@ -208,15 +205,15 @@ static void setFastFlags(const std::vector& flags) if (view.size() >= 2 && view[0] == 'D' && view[1] == 'F') view.remove_prefix(1); - if (view.substr(0, 4) == "FInt") + if (view.substr(0, 4) == XorStr("FInt")) { auto [name, value] = parseFInt(view.substr(4)); setFastValue(name, value); } else { - // We want to prevent the footgun where '--fflags=LuauSomeFlag' is ignored. We'll assume that this was declared as FFlag. - auto [name, value] = parseFFlag(view.substr(0, 5) == "FFlag" ? view.substr(5) : view); + // We want to prevent the footgun where '--fflags=lluzSomeFlag' is ignored. We'll assume that this was declared as FFlag. + auto [name, value] = parseFFlag(view.substr(0, 5) == XorStr("FFlag") ? view.substr(5) : view); setFastValue(name, value); } } @@ -224,7 +221,7 @@ static void setFastFlags(const std::vector& flags) int main(int argc, char** argv) { - Luau::assertHandler() = testAssertionHandler; + lluz::assertHandler() = testAssertionHandler; doctest::registerReporter("boost", 0, true); @@ -234,7 +231,7 @@ int main(int argc, char** argv) if (doctest::parseFlag(argc, argv, "--list-fflags")) { - for (Luau::FValue* flag = Luau::FValue::list; flag; flag = flag->next) + for (lluz::FValue* flag = lluz::FValue::list; flag; flag = flag->next) { if (skipFastFlag(flag->name)) continue; @@ -252,15 +249,6 @@ int main(int argc, char** argv) verbose = true; } - int level = -1; - if (doctest::parseIntOption(argc, argv, "-O", doctest::option_int, level)) - { - if (level < 0 || level > 2) - std::cerr << "Optimization level must be between 0 and 2 inclusive." << std::endl; - else - optimizationLevel = level; - } - if (std::vector flags; doctest::parseCommaSepArgs(argc, argv, "--fflags=", flags)) setFastFlags(flags); @@ -290,11 +278,12 @@ int main(int argc, char** argv) int result = context.run(); if (doctest::parseFlag(argc, argv, "--help") || doctest::parseFlag(argc, argv, "-h")) { - printf("Additional command line options:\n"); - printf(" -O[n] Changes default optimization level (1) for conformance runs\n"); - printf(" --verbose Enables verbose output (e.g. lua 'print' statements)\n"); - printf(" --fflags= Sets specified fast flags\n"); - printf(" --list-fflags List all fast flags\n"); + printf(XorStr("Additional command line options:\n")); + printf(XorStr(" --verbose Enables verbose output (e.g. lua 'print' statements)\n")); + printf(XorStr(" --fflags= Sets specified fast flags\n")); + printf(XorStr(" --list-fflags List all fast flags\n")); } return result; } + +