The interactive file manager requires Javascript. Please enable it or use sftp or scp.
You may still browse the files here.

Download Latest Version 0.699 source code.tar.gz (2.1 MB)
Email in envelope

Get an email when there's a new version of Luau

Home / 0.699
Name Modified Size InfoDownloads / Week
Parent folder
luau-windows.zip 2025-11-07 2.6 MB
Luau.Web.js 2025-11-07 3.9 MB
luau-ubuntu.zip 2025-11-07 6.4 MB
luau-macos.zip 2025-11-07 4.7 MB
0.699 source code.tar.gz 2025-11-07 2.1 MB
0.699 source code.zip 2025-11-07 2.5 MB
README.md 2025-11-07 2.9 kB
Totals: 7 Items   22.2 MB 13

Hello all! Another week, another release!

Analysis

  • Fixed table.clone in the old solver to ensure intersections of tables were being entirely cloned: prior only the first table in the intersection would be copied:

    :::luau type FIRST = { some: string } type SECOND = FIRST & { thing: string } local b: SECOND -- c's type used to be FIRST, but should be the full type of SECOND local c = table.clone(b) * Fixed table.clone in the old solver to be more permissive and treat a variadic return as having at least one element. This works around some unfortunate behavior in the old solver version of nonstrict mode, see:

    :::luau -- A.luau --!nonstrict return function() return {} end -- B.luau local A = require("A") -- This line would previously error as A has type () -> (...any), so -- we might not be providing enough parameters to table.clone. local _ = table.clone(A()) * Fixed a bug in the new solver where error suppression was not kicking in for indexing, as in:

    :::luau local function f(value: any) if value ~= nil then for k = 1, #value do -- Previously this would error, claiming you cannot index into a *error-type* | ~nil local _ = value[k] end end end * Fix the getmetatable type function in the new solver to accept *error-type* and table as valid type inputs. * Changed how error reporting for invalid for ... in loops works: for now this may result in slightly worse error messages (see the example below), but should mean error suppression is more consistent going forward:

    :::luau function my_iter(state: string, index: number) return state, index end local my_state = {} local first_index = "first" -- Prior we would claim my_state and first_index are of the incorrect types, -- now we claim that my_iter is of the incorrect type, which can be considered -- true, but is less helpful. for a, b in my_iter, my_state, first_index do end

Runtime

  • Introduced lua_rawgetptagged and lua_rawsetptagged, as well as Lua 5.2+ compatibility macros lua_rawgetp and lua_rawsetp, to be able to perform lookups into tables using tagged or untagged lightuserdata without additional calls and stack manipulation. This enables a more efficient lookup way for lightuserdata keys similar to how lua_rawgetfield and lua_rawgeti avoid extra operations for their corresponding types.

Co-authored-by: Andy Friesen afriesen@roblox.com Co-authored-by: Annie Tang annietang@roblox.com Co-authored-by: Ariel Weiss arielweiss@roblox.com Co-authored-by: Hunter Goldstein hgoldstein@roblox.com Co-authored-by: Varun Saini vsaini@roblox.com Co-authored-by: Vyacheslav Egorov vegorov@roblox.com

Source: README.md, updated 2025-11-07