diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 12f6717c4..d9f1624c1 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -6,7 +6,7 @@ import { isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { unsupportedVarDeclaration } from "../utils/diagnostics"; import { addExportToIdentifier } from "../utils/export"; -import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall } from "../utils/lua-ast"; +import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformIdentifier } from "./identifier"; import { isMultiReturnCall } from "./language-extensions/multi"; @@ -158,9 +158,11 @@ export function transformBindingVariableDeclaration( // Contain the expression in a temporary variable table = lua.createAnonymousIdentifier(); if (initializer) { - statements.push( - lua.createVariableDeclarationStatement(table, context.transformExpression(initializer)) - ); + let expression = context.transformExpression(initializer); + if (isTupleReturnCall(context, initializer) || isMultiReturnCall(context, initializer)) { + expression = wrapInTable(expression); + } + statements.push(lua.createVariableDeclarationStatement(table, expression)); } } statements.push(...transformBindingPattern(context, bindingPattern, table)); diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index a280fe331..b2b679d30 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -69,7 +69,9 @@ exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"mai exports[`invalid $multi call (const {} = $multi();): code 1`] = ` "local ____ = { - ____(_G) + { + ____(_G) + } }" `; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index 0b99cf4dc..5d59aa4d0 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -24,6 +24,33 @@ test("multi example use case", () => { .expectToEqual({ a: "foo", b: 5 }); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/995 +test("Destructuring assignment of LuaMultiReturn", () => { + util.testModule` + function multiReturn(): LuaMultiReturn<[number, number, number]> { + return $multi(1, 2, 3); + } + + const [a, ...b] = multiReturn(); + export {a, b}; + ` + .setOptions(multiProjectOptions) + .expectToEqual({ a: 1, b: [2, 3] }); +}); + +test("Destructuring assignment of LuaMultiReturn returning nil", () => { + util.testModule` + function multiReturn(): LuaMultiReturn<[number, number, number]> { + return; + } + + const [a, ...b] = multiReturn(); + export {a, b}; + ` + .setOptions(multiProjectOptions) + .expectToEqual({ a: undefined, b: [] }); +}); + test.each<[string, any]>([ ["$multi()", undefined], ["$multi(true)", true],