Skip to content

test: run lua 5.5 tests on the lua 5.5 wasm binding#1723

Open
RealColdFry wants to merge 5 commits into
TypeScriptToLua:masterfrom
RealColdFry:lua55-test-bindings
Open

test: run lua 5.5 tests on the lua 5.5 wasm binding#1723
RealColdFry wants to merge 5 commits into
TypeScriptToLua:masterfrom
RealColdFry:lua55-test-bindings

Conversation

@RealColdFry
Copy link
Copy Markdown
Contributor

@RealColdFry RealColdFry commented May 2, 2026

Lua 5.5 changes:

Related to #1676 but doesn't address any of the listed changes there. Note that this incompat is not listed in the issue or in the linked change list: https://www.lua.org/manual/5.5/readme.html#changes (although the change list does link to the incompat list)

@RealColdFry RealColdFry marked this pull request as ready for review May 2, 2026 13:39
// is replaced by a string when it propagates out of a protected call. To
// preserve `throw undefined` semantics, route through xpcall with a message
// handler that wraps nil into a sentinel, and unwrap before the user catch.
// See: https://www.lua.org/manual/5.5/manual.html#8.1
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be the result if we did not do this workaround? Do we get failing tests? Are we getting unexpected type failures at runtime?

Copy link
Copy Markdown
Contributor Author

@RealColdFry RealColdFry May 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running the below snippet

ok, err = pcall(function() error(nil) end)
print(ok, err, type(err))

In Lua 5.0-5.4, LuaJIT, Luau (Lune) gives

false   nil     nil

while in 5.5:

false	<no error object>	string

Without the wrapper, error(nil) in Lua 5.5 surfaces as the string "<no error object>" rather than nil. This breaks the error.spec.ts "throw and catch undefined" test (https://github.com/TypeScriptToLua/TypeScriptToLua/actions/runs/25261709047/job/74069980641?pr=1723#step:6:250).

  ● throw and catch undefined                                                                                                                
                                                                                                                                             
    expect(received).toEqual(expected) // deep equality                                                                                      
                                                                                                                                             
    Expected: undefined                                                                                                                      
    Received: "<no error object>"                                                                                                            
                                                                                                                                             
      405 |         const luaResult = this.getLuaExecutionResult();                                                                          
      406 |         const jsResult = this.getJsExecutionResult();                                                                            
    > 407 |         expect(luaResult).toEqual(jsResult);                                                                                     
          |                           ^                                                                                                      
      408 |                                                                                                                                  
      409 |         return this;                                                                                                             
      410 |     }                                                                                                                            
                                                                                                                                             
      at FunctionTestBuilder.expectToMatchJsResult (test/util.ts:407:27)                                                                     
      at test/unit/error.spec.ts:320:7 

Otherwise, in

function doThing() {
  throw undefined;
}

function main() {
  try {
    doThing();
    return "didThing";
  } catch (
    e // e: unknown
  ) {
    if (e === undefined) {
      // handle the "thrown undefined" case
      return "undefined";
    }
    if (e instanceof Error) {
      return "Error[" + e.message + "]";
    }
    if (typeof e === "string") {
      // Lua 5.5 gives a string
      return "string[" + e + "]";
    }
    return "something else";
  }
}

console.log(main());

if doThing() threw undefined, on 5.5 e is actually the string <no error object> at runtime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants