[ANN] Lua 5.5.0 (rc1) now available

461 views
Skip to first unread message

Luiz Henrique de Figueiredo

unread,
Nov 14, 2025, 8:08:44 PM (13 days ago) Nov 14
to lua-l
Lua 5.5 is the next version of Lua.

Lua 5.5.0 (rc1) is now available for testing at
https://www.lua.org/work/lua-5.5.0-rc1.tar.gz

The SHA256 checksum is
34a4dcca0c04877fbce4baff54054b9793b70bca5d8c676ca4d3504dd47c3772  -

The Git commit ID is
4cf498210e6a60637a7abb06d32460ec21efdbdc

The main changes in Lua 5.5.0 are listed at
https://www.lua.org/work/doc/#changes

An updated reference manual is included and also available at
https://www.lua.org/work/doc

The complete diffs from beta to rc1 are available at
https://www.lua.org/work/diffs-lua-5.5.0-beta-rc1.html.html
https://www.lua.org/work/diffu-lua-5.5.0-beta-rc1.html.html

A test suite is available at
https://www.lua.org/work/lua-5.5.0-tests.tar.gz

All feedback welcome. Thanks.
--lhf

Luiz Henrique de Figueiredo

unread,
Nov 14, 2025, 8:37:45 PM (13 days ago) Nov 14
to lu...@googlegroups.com
The complete diffs from beta to rc1 are available at
https://www.lua.org/work/diffs-lua-5.5.0-beta-rc1.html
https://www.lua.org/work/diffu-lua-5.5.0-beta-rc1.html

Sorry about the typo in the announcement.
--lhf

Bas Groothedde

unread,
Nov 15, 2025, 6:12:14 AM (12 days ago) Nov 15
to lu...@googlegroups.com

Thank you, I have processed those changes on luac.nl

~b

Xmilia Hermit

unread,
Nov 15, 2025, 6:46:13 AM (12 days ago) Nov 15
to lu...@googlegroups.com
I already reported all the problems I found in the new features and they
are already fixed.
Personally, I like the new `...name` syntax to name varargs.
However, I would have liked to see a `varargtable...` operator as the
reverse of the named vararg `...varargtable`.
This should behave like `table.unpack(varargtable, 1, varargtable.n)`
and should not have parsing problems since constructs such as
`...(funcarg)` or `...[1]=1` are not valid.
In my opinion this would make the use of `...` cleaner in case the
function uses a named vararg parameter as in:

local function test(...args)
return ...
end

vs

local function test(...args)
return args...
end

and could allow for constructs such as

local function test(...args)
return functon() return args... end
end

I tried to implement this myself by using OP_VARARG and the unused K and
RB parameters to encode if this is the `a...` version and what the slot
of `a` is.
The following is the patch in case someone is interested:

index 95ef900c..fe9e4454 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1951,6 +1951,11 @@ void luaK_finish (FuncState *fs) {
SET_OPCODE(*pc, OP_GETTABLE); /* must get vararg there */
break;
}
+ case OP_VARARG: {
+ if ((p->flag & (PF_VATAB | PF_ISVARARG)) == PF_ISVARARG &&
GETARG_B(*pc) == fs->f->numparams)
+ SETARG_k(*pc, 0); /* Don't use the spread function in case
the vararg table is not created */
+ break;
+ }
case OP_JMP: { /* to optimize jumps to jumps */
int target = finaltarget(p->code, i);
fixjump(fs, i, target); /* jump directly to final target */
diff --git a/lparser.c b/lparser.c
index 77141e79..4ecaa670 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1247,6 +1247,21 @@ static void suffixedexp (LexState *ls, expdesc *v) {
funcargs(ls, v);
break;
}
+ case TK_DOTS: {
+ if (v->k == VVARGVAR && v->t == v->f) {
+ init_exp(v, VVARARG, luaK_codeABCk(fs, OP_VARARG, 0,
v->u.var.ridx, 1, 1));
+ } else {
+ luaK_exp2anyreg(fs, v);
+ if (v->k == VNONRELOC && v->u.info >= luaY_nvarstack(fs)) {
+ fs->freereg--;
+ lua_assert(v->u.info == fs->freereg);
+ }
+ init_exp(v, VVARARG, luaK_codeABCk(fs, OP_VARARG, 0,
v->u.info, 1, 1));
+ }
+ luaK_checkstack(fs, 2);
+ luaX_next(ls);
+ return;
+ }
default: return;
}
}
diff --git a/ltablib.c b/ltablib.c
index 46ecb5e0..0c0aefac 100644
--- a/ltablib.c
+++ b/ltablib.c
@@ -424,3 +424,13 @@ LUAMOD_API int luaopen_table (lua_State *L) {
return 1;
}

+LUAI_FUNC int luaT_spread(lua_State *L);
+int luaT_spread(lua_State *L) {
+ int isnum;
+ lua_settop(L, 1);
+ lua_pushinteger(L, 1);
+ lua_getfield(L, 1, "n");
+ lua_tointegerx(L, -1, &isnum);
+ if (l_unlikely(!isnum)) return luaL_error(L, "'n' not an integer");
+ return tunpack(L);
+}
\ No newline at end of file
diff --git a/lvm.c b/lvm.c
index 2c868c21..77ad8e2e 100644
--- a/lvm.c
+++ b/lvm.c
@@ -31,6 +31,7 @@
#include "ltm.h"
#include "lvm.h"

+LUAI_FUNC int luaT_spread(lua_State *L);

/*
** By default, use jump tables in the main interpreter loop on gcc
@@ -1936,6 +1937,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
vmcase(OP_VARARG) {
StkId ra = RA(i);
int n = GETARG_C(i) - 1; /* required results */
+ if (TESTARG_k(i)) {
+ StkId rb = RB(i);
+ setobjs2s(L, ra+1, rb);
+ setfvalue(s2v(ra), luaT_spread);
+ L->top.p = ra + 2;
+ ProtectNT(luaD_call(L, ra, n));
+ } else
Protect(luaT_getvarargs(L, ci, ra, n));
vmbreak;
}

Regards,
Xmilia

Luiz Henrique de Figueiredo

unread,
Nov 15, 2025, 7:13:29 AM (12 days ago) Nov 15
to lu...@googlegroups.com
> Thank you, I have processed those changes on luac.nl.

In that example, try also the new vararg feature:
https://luac.nl/s/19dfbcdf6bb8f25a7cb86416bdf

local function print_all(...a)
for i=1,a.n do
print(i, a[i]);
end
end

print_all(1, 2, 3, 4, 5, false, true, {}, "hello");

Bas Groothedde

unread,
Nov 15, 2025, 8:44:01 AM (12 days ago) Nov 15
to lu...@googlegroups.com


> On 15 Nov 2025, at 13:13, Luiz Henrique de Figueiredo <l...@tecgraf.puc-rio.br> wrote:
>
> 
Thank you, I will work that into the signatures.

~b

Scott Morgan

unread,
Nov 15, 2025, 8:48:31 AM (12 days ago) Nov 15
to lu...@googlegroups.com
On 15/11/2025 11:46, Xmilia Hermit wrote:
> I already reported all the problems I found in the new features and they
> are already fixed.
> Personally, I like the new `...name` syntax to name varargs.
> However, I would have liked to see a `varargtable...` operator as the
> reverse of the named vararg `...varargtable`.
> This should behave like `table.unpack(varargtable, 1, varargtable.n)`
> and should not have parsing problems since constructs such as `...
> (funcarg)` or `...[1]=1` are not valid.
> In my opinion this would make the use of `...` cleaner in case the
> function uses a named vararg parameter as in:
...
> and could allow for constructs such as
>
> local function test(...args)
>    return functon() return args... end
> end
>

Would it make sense to also work for any table?

e.g.

function test()
local t = { 1,2,3 } -- Does it need n setting?
return t...
end

Scott

Xmilia Hermit

unread,
Nov 15, 2025, 9:03:01 AM (12 days ago) Nov 15
to lu...@googlegroups.com

> Would it make sense to also work for any table?
>
> e.g.
>
> function test()
>   local t = { 1,2,3 } -- Does it need n setting?
>   return t...
> end

In case the table does not have a `n` key the length with `#` could
certainly be used before failing. I just wanted to give a small
motivating example.

Regards,
Xmilia

Martin Eden

unread,
Nov 15, 2025, 9:14:50 AM (12 days ago) Nov 15
to lu...@googlegroups.com
On 2025-11-15 14:13, Luiz Henrique de Figueiredo wrote:
> In that example, try also the new vararg feature:
> https://luac.nl/s/19dfbcdf6bb8f25a7cb86416bdf
>
> local function print_all(...a)
> for i=1,a.n do
> print(i, a[i]);
> end
> end

It's nice to see a new release. But I'm here for grumping..

Just tested vararg aliasing on Lua 5.5.0.

Alias feature is nice but we still can't have named sequence in Lua in
general case.

My use case is wrapping Lua functions. I want to print args before call
and results after call.

So I'm writing wrapper that returns function with embedded calls
of printers around call of main function:

  local Wrap =
    function(Main, Before, After)
      return
        function(...)
          Before(...)
          local Result = table.pack(Main(...))
          After(table.unpack(Result, 1, Result.n))
          return table.unpack(Result, 1, Result.n)
        end
    end

Naming "...Args" here won't help, we're not using select()'s.
Note a hoops jumping at using table.pack() and table.unpack().

Please make sequences first-class citizens.

Then I can write something like

  local Wrap =
    function(Main, Before, After)
      return
        function(...)
          Before(...)
          local Result... = Main(...)
          After(Result...)
          return Result...
        end
    end

  -- (And still be able to do "Result[i]" and "Result.n" if needed.)

-- Martin

Andrey Dobrovolsky

unread,
Nov 15, 2025, 10:38:31 AM (12 days ago) Nov 15
to lu...@googlegroups.com
Huge thanks for the new Lua version!

There is the typo "varag" instead of "vararg" in manual.hml line 2925:

> The presence of a varag table in a variadic function is indicated

And I have a small question: if I use the named vararg list under
ipairs(), will the interpreter transform this list into the
full-featured table?

Regards,
-- Andrew

сб, 15 лист. 2025 р. о 16:14 'Martin Eden' via lua-l
<lu...@googlegroups.com> пише:
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/06095d9a-c0e7-4d96-b4f6-a4656d90a44c%40disroot.org.

Roberto Ierusalimschy

unread,
Nov 15, 2025, 2:46:31 PM (12 days ago) Nov 15
to lu...@googlegroups.com
> There is the typo "varag" instead of "vararg" in manual.hml line 2925:
> > The presence of a varag table in a variadic function is indicated

Thanks.


> And I have a small question: if I use the named vararg list under
> ipairs(), will the interpreter transform this list into the
> full-featured table?

Yes. Any use not syntactically in the form 't[exp]' or 't.name' forces a
real table. (Among other issues, the name 'ipairs' can refer to a
different function.)

-- Roberto

Andrey Dobrovolsky

unread,
Nov 16, 2025, 6:14:43 AM (11 days ago) Nov 16
to lu...@googlegroups.com
сб, 15 лист. 2025 р. о 21:46 Roberto Ierusalimschy
<rob...@inf.puc-rio.br> пише:
>
> Yes. Any use not syntactically in the form 't[exp]' or 't.name' forces a
> real table. (Among other issues, the name 'ipairs' can refer to a
> different function.)

Thanks! Got it.

May I ask one more silly question?
Are actually passed varargs allowed to assign new values or they are a
kind of <const>? Seems that

function(i, new_value, ... t)
if i < 0 and i <= t.n then
t[i] = new_value
end
end

is not violating the above mentioned rule? Or varargs appear to be
<const> locals, unlike the named parameters?

-- Andrew

Bas Groothedde

unread,
Nov 16, 2025, 6:42:24 AM (11 days ago) Nov 16
to lu...@googlegroups.com

See https://luac.nl/s/19e61f2fc9bbf557b1093781d35 - test1 mutates the vararg, thus Lua emits code for a vararg table. (forces a real table)

test2 does not mutate it, thus it generates code for accessing the vararg pack through GETVARG

~b

Andrey Dobrovolsky

unread,
Nov 16, 2025, 7:09:50 AM (11 days ago) Nov 16
to lu...@googlegroups.com
Hi Bas,

Thanks for Your answer. Sorry for the noise, it appeared not to be hard to test.
So varargs are <const>, good to have a confirmed answer.

-- Andrew

нд, 16 лист. 2025 р. о 13:42 'Bas Groothedde' via lua-l
<lu...@googlegroups.com> пише:
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/a7f57c549115eeae9517e42b393072ea%40xoru.net.

Bas Groothedde

unread,
Nov 16, 2025, 10:12:00 AM (11 days ago) Nov 16
to lu...@googlegroups.com
--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
In luac.c, line 651:
 
   case OP_ERRNNIL:
    printf("%d %d",a,bx);
    printf(COMMENT); PrintConstant(f,bx);
    break;
 
Should this not include a test for bx?
 
l_noret luaG_errnnil (lua_State *L, LClosure *cl, int k) {
  const char *globalname = "?";  /* default name if k == 0 */
  if (k > 0)
    kname(cl->p, k - 1, &globalname);
  luaG_runerror(L, "global '%s' already defined", globalname);
}
 
luaG_errnil subtracts 1 from k when k is greater than 0, but PrintConstant in luac.c does not - resulting in an out of bounds access,
as PrintConstant simply reads from f->k[i] even if i is not a valid index. 
 
   case OP_ERRNNIL:
    printf("%d %d",a,bx);
    if (bx == 0) {
        printf(COMMENT); printf("?");
    } else {
        printf(COMMENT); PrintConstant(f,bx - 1);
    }
    break;
 
 
~b

Luiz Henrique de Figueiredo

unread,
Nov 16, 2025, 2:28:41 PM (11 days ago) Nov 16
to lu...@googlegroups.com
> In luac.c, line 651:
> Should this not include a test for bx?

It seems you're right. Thanks for the report.

André Naef

unread,
Nov 16, 2025, 2:47:37 PM (11 days ago) Nov 16
to lua-l
Minor: the lua_pushexternalstring documentation does not describe the return value of the function.

sur-behoffski

unread,
Nov 17, 2025, 5:11:21 AM (11 days ago) Nov 17
to lu...@googlegroups.com
On 2025-11-15 11:38, Luiz Henrique de Figueiredo wrote:
> Lua 5.5 is the next version of Lua.
>
> Lua 5.5.0 (rc1) is now available for testing at
> https://www.lua.org/work/lua-5.5.0-rc1.tar.gz [...]

Have tried building from source on LinuxMint 22.2, using my
GNU/Linux "lglicua" framework. Results are as expected.

Distro: LinuxMint 22.2
Kernel: 6.14.0-35-generic
GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0

Lua: lua-5.5.0-rc1
LuaRocks: 3.12.2

Lua compiles and installs without problem (for all four combinations
of {static, dynamic}x{gcc, g++}).

LuaRocks fails (as expected). From previous chat when looking at
the -beta, there is a newer version waiting in the wings (not sure,
but is it written in Rust?). (Hisham noted that things can change
quite a bit between -beta and -rc1, and so any LuaRocks release
would not occur while Lua 5.5.0 was in beta.)

install$ ./i luarocks-install
'LuaRocks entire install' failed (2):
'Configure+make LuaRocks for 'Lua5.5'' failed (1):
'Configure LuaRocks for 5.5' failed (1): Invalid Lua version in flag --lua-version.

----

So far so good, but, personally, I'd like to see LuaRocks working
(and a set of Rocks ported to 5.5) before signing off on a Lua -rc.



cheers, s-b etc.

Roberto Ierusalimschy

unread,
Nov 17, 2025, 8:15:06 AM (10 days ago) Nov 17
to lu...@googlegroups.com
> Thanks for Your answer. Sorry for the noise, it appeared not to be hard to test.
> So varargs are <const>, good to have a confirmed answer.

The manual says that:

When present, a vararg table behaves like a read-only local variable
with the given name that is initialized with a table.

and later:

the code behaves as if the function started with the following
statement, assuming the standard behavior of table.pack:

local <const> name = table.pack(...)

-- Roberto

Roberto Ierusalimschy

unread,
Nov 17, 2025, 8:18:03 AM (10 days ago) Nov 17
to lu...@googlegroups.com
> Minor: the lua_pushexternalstring documentation does not describe the
> return value of the function.

Thanks for the feedback.

-- Roberto

Andrey Dobrovolsky

unread,
Nov 18, 2025, 9:02:49 AM (9 days ago) Nov 18
to lu...@googlegroups.com
Named vararg lists are a very attractive feature in the new Lua
version. Let me speculate a little about it.

"... name" in function declaration supposes the true list of the known
(at the runtime, not during code loading) and fixed size being already
present on the Lua stack, which may wake the full-featured table in
certain circumstances. Those circumstances are described in the
manual.

In the current Lua release candidate such named lists may be used in
the functions' declarations.

But there is one more case, when some true list of the known at the
runtime and fixed size is placed into the Lua stack. It is the case of
another great Lua feature - the function can return the list.

Xmilia Hermit proposed the syntax:

name ...

It supposes that there may be more than one object, behaving like
named varargs "...".

For example

local f = function()
return 1, 2, 3
end

.... t = f() -- declaration of local t <const> = table.pack(f())

where t may behave in the same way as named varargs. In case t will
become the full-featured table, the original function returned values
may be accessed unchanged as "t ...".

Is it possible for these sweet dreams to come true?

Thanks for the exciting Lua improvements, and best regards,
-- Andrew

Matěj Cepl

unread,
Nov 18, 2025, 4:28:09 PM (9 days ago) Nov 18
to lu...@googlegroups.com
On Sat Nov 15, 2025 at 2:08 AM CET, Luiz Henrique de Figueiredo wrote:
> Lua 5.5 is the next version of Lua.
>
> Lua 5.5.0 (rc1) is now available for testing at
> https://www.lua.org/work/lua-5.5.0-rc1.tar.gz

Unfortunately failure to build on i586 reported for beta [1] is still
present. Complete log is available on [2].

Best,

Matěj


[1] https://groups.google.com/u/1/g/lua-l/c/So-oIbHbIIE/m/6_GMzGv7AAAJ
[2] https://mcepl.fedorapeople.org/tmp/lua55-rc1-i586-FTBFS-log.txt
--
http://matej.ceplovi.cz/blog/, @mc...@en.osm.town
GPG Finger: 3C76 A027 CA45 AD70 98B5 BC1D 7920 5802 880B C9D8

If in desperation, read the documentation!
-- Brian D. Ripley, on R-help list

E09FEF25D96484AC.asc
E09FEF25D96484AC.asc
application_pgp-keys_11340884770069117365
signature.asc

Roberto Ierusalimschy

unread,
Nov 19, 2025, 8:48:34 AM (8 days ago) Nov 19
to lu...@googlegroups.com
> On Sat Nov 15, 2025 at 2:08 AM CET, Luiz Henrique de Figueiredo wrote:
> > Lua 5.5 is the next version of Lua.
> >
> > Lua 5.5.0 (rc1) is now available for testing at
> > https://www.lua.org/work/lua-5.5.0-rc1.tar.gz
>
> Unfortunately failure to build on i586 reported for beta [1] is still
> present. Complete log is available on [2].

Maybe I am misreading something, but apparently [1] mentions a
Segmentation fault while running strings.lua, while [2] ends with a
regular Lua error while running tpack.lua. Are they really about the
same issue?

-- Roberto

Mitchell

unread,
Nov 24, 2025, 1:19:47 PM (3 days ago) Nov 24
to lu...@googlegroups.com
Hi,
I noticed that in the reference manual for `math.random()`, the “range [0,1)” was changed to “range [0, 1)” (insertion of a space), but a couple of sentences later, “math.random(1,n)” still doesn’t have a space before ’n’. Perhaps you’d like to make that change too for consistency.

Thanks for this new release!

Cheers,
Mitchell

Roberto Ierusalimschy

unread,
Nov 24, 2025, 2:51:01 PM (3 days ago) Nov 24
to lu...@googlegroups.com
> I noticed that in the reference manual for `math.random()`, the “range [0,1)” was changed to “range [0, 1)” (insertion of a space), but a couple of sentences later, “math.random(1,n)” still doesn’t have a space before ’n’. Perhaps you’d like to make that change too for consistency.

Note that "range [0, 1)" is regular text, while "math.random(1,n)" is code
(written with a different font), so they don't need to be consistent.

However, our code style uses a space after commas in argument lists,
so in the end "math.random(1,n)" should have a space too.

-- Roberto

最萌 小汐

unread,
5:37 AM (12 hours ago) 5:37 AM
to lu...@googlegroups.com
Is this as expected?

```lua
print(_VERSION)

do
    global X = 1
end
global X = 2 -- global 'X' already defined
```


-- sumneko

发件人: lu...@googlegroups.com <lu...@googlegroups.com> 代表 Roberto Ierusalimschy <rob...@inf.puc-rio.br>
发送时间: 2025年11月25日 3:50
收件人: lu...@googlegroups.com <lu...@googlegroups.com>
主题: Re: [ANN] Lua 5.5.0 (rc1) now available
 
--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.

Luiz Henrique de Figueiredo

unread,
8:06 AM (9 hours ago) 8:06 AM
to lu...@googlegroups.com
> Is this as expected?
> do
> global X = 1
> end
> global X = 2 -- global 'X' already defined

What do you expect from the code below?
do
global X = 1
end
print(X)

最萌 小汐

unread,
9:23 AM (8 hours ago) 9:23 AM
to lu...@googlegroups.com
It should be 1, because there is a global * outside.

Let us see this code:


do
    global <const> X = 1
end

X = 2 — ok. There is no const X
global X = 3 — error: global 'X' already defined . Where is the defined X?


I am really confused by the scope of the global keyword

-- sumneko

发件人: lu...@googlegroups.com <lu...@googlegroups.com> 代表 Luiz Henrique de Figueiredo <l...@tecgraf.puc-rio.br>
发送时间: 2025年11月27日 21:06

收件人: lu...@googlegroups.com <lu...@googlegroups.com>
主题: Re: [ANN] Lua 5.5.0 (rc1) now available
--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.

Roberto Ierusalimschy

unread,
9:43 AM (8 hours ago) 9:43 AM
to lu...@googlegroups.com
> Let us see this code:
>
> do
> global <const> X = 1
> end
>
> X = 2 — ok. There is no const X
> global X = 3 — error: global 'X' already defined . Where is the defined X?
>
> I am really confused by the scope of the global keyword

Despite the scope of the global keyword, both 'X' refer to the same variable.

The whole point of this error is when you try to define a global already
defined somewhere else. So, as explained in the manual, it does not rely
on visible global definitions, but on the runtime value of the global:

Moreover, for global variables, the initialization will raise a
runtime error if the variable is already defined, that is, it has a
non-nil value.

-- Roberto

最萌 小汐

unread,
10:19 AM (7 hours ago) 10:19 AM
to lu...@googlegroups.com
Thank you for your explanation! I never noticed that this was a runtime error, so it's much clearer now.

-- sumneko

发件人: lu...@googlegroups.com <lu...@googlegroups.com> 代表 Roberto Ierusalimschy <rob...@inf.puc-rio.br>
发送时间: 2025年11月27日 22:43
收件人: lu...@googlegroups.com <lu...@googlegroups.com>
主题: Re: 回复: [ANN] Lua 5.5.0 (rc1) now available
 
--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages