Releases: luau-lang/luau
0.715
The Luau team has been cooking for this week's release! 🍳
We have implemented an initial version of the 64-bit Integer Type! Please keep in mind that although the RFC has been accepted, we are currently in the process of identifying and fixing bugs, which may require amending the original RFC.
Additionally, we've been working on the following:
Analysis
- Fix crash reported in #2305.
- Reword type-function error messages.
- Fix various crashes found by fuzzer and in unit tests.
- Rework how we track generalizable free types.
Runtime
- NCG: Propagate register tags across block chains.
- NCG: Fix a bug in how register information was set up when entering a new block.
- NCG: Fix a bug where register tag information for non-live registers was incorrectly propagated.
- NCG: Remove duplicate stores of doubles and integers.
- NCG: Unconditionally provide tags to read/write functions for buffers.
Miscellaneous
- Various Makefile, lldb_formatter, and lldb-dap improvements.
Thanks as always to our open-source contributors:
- Read-only/Write-only extern properties, Read-only vector properties by @PhoenixWhitefire in #2071
Full Changelog: 0.714...0.715
Co-authored-by: Ariel Weiss arielweiss@roblox.com
Co-authored-by: David Cope dcope@roblox.com
Co-authored-by: Hunter Goldstein hgoldstein@roblox.com
Co-authored-by: James McNellis jmcnellis@roblox.com
Co-authored-by: Sora Kanosue skanosue@roblox.com
Co-authored-by: Thomas Schollenberger tschollenberger@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
0.714
Another week, another release! Happy spring! 🌷
Open-source contributions
- Fix
type(x) == "vector"always refiningxtoneverby @PhoenixWhitefire in #2291
Analysis
- Remove an incorrect assertion triggered when we fail to bind a generic pack.
- Various miscellaneous fixes for bugs found by the fuzzer.
Runtime
- Fix
DUPTABLEconstant packing not respecting side-effects. - NCG: fix removal of stores that are still needed in VM exits.
- NCG: fix a bug that caused buffer access ranges to be computed incorrectly.
- Fix #2293.
Miscellaneous
- Various
Makefileimprovements. - Add lldb providers for
Proto. - Add new
--dump-constantsflag toluau-compile.
Full Changelog: 0.713...0.714
Co-authored-by: Andy Friesen afriesen@roblox.com
Co-authored-by: Ariel Weiss arielweiss@roblox.com
Co-authored-by: David Cope dcope@roblox.com
Co-authored-by: Hunter Goldstein hgoldstein@roblox.com
Co-authored-by: Sora Kanosue skanosue@roblox.com
Co-authored-by: Thomas Schollenberger tschollenberger@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
0.713
Hey folks! Another week another Luau release 🙂
Analysis
InsertionOrderedMaphas been moved from theAnalysislibrary toCommon.- Subtyping has been rewritten to avoid extra allocations: there should be no behavioral change from this effort, only somewhat lower memory pressure.
- Fixed a bug where analyzing comparing a value that is too complex to type check against
nilmay cause the type checker to crash. pcallnow handles functions that return no values, for example:
local mod = require('mymodule')
-- Previously, we would error claiming that we only expect one value on the left-hand-side.
-- Now, there is no error and `result` is typed as `unknown`.
local success, result = pcall(function()
mod.dothething()
end)Compiler
- Fixed a bug in
constwhere function statements were excluded from const checks. Fixes #2282
const a = 42
-- The following will now fail to compile.
function a()
end- Table literal "shapes" can now encorporate constant values at bytecode compile time. We store the shape of constant tables if all their keys are constants, which allows slightly faster insertion when building said literals (we can preallocate a table in a particular shape). Now, we can also store constant values, making construction a single bytecode. For example:
-- This snippet ...
return { x = 1, y = 2 }-- ... used to compile to bytecode like ...
DUPTABLE R0 2
LOADN R1 1
SETTABLEKS R1 R0 K0 ['x']
LOADN R1 2
SETTABLEKS R1 R0 K1 ['y']
RETURN R0 1-- ... and now compiles to something like ...
DUPTABLE R0 4
RETURN R0 1Runtime
- Introduced a
@debugnoinlineattribute behind a debug flag. We do not actively plan to ship this but have added it to help test compiler and runtime optimizations. - Fixed a bug where setting a breakpoint in a natively compiled function could crash on ARM64.
- NCG: The data section of generated code is no longer allocated as executable, preventing a class of potential exploits.
Co-authored-by: Andy Friesen afriesen@roblox.com
Co-authored-by: Ariel Weiss arielweiss@roblox.com
Co-authored-by: David Cope dcope@roblox.com
Co-authored-by: Hunter Goldstein hgoldstein@roblox.com
Co-authored-by: Ilya Rezvov irezvov@roblox.com
Co-authored-by: Tom Schollenberger tschollenberger@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Karim Mouline kmouline@roblox.com
0.712
Analysis
- Fix being able to write to a read-only field in a compound assignment by @PhoenixWhitefire in #2290
- Fix #1986
- Fix #1890
- Minor bugfixes and improvements
Compiler
- Do not constant-fold strings that are longer than 4096 characters. This helps to avoid pathalogical misoptimizations that could result in the compiling bytecode growing very large.
- fix constant placement into the CHECK_BUFFER_LEN 'double source' argument
Contributors
Co-authored-by: Ariel Weiss arielweiss@roblox.com
Co-authored-by: Hunter Goldstein hgoldstein@roblox.com
Co-authored-by: Thomas Schollenberger tschollenberger@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
Full Changelog: 0.711...0.712
0.711
Hi there, folks! We're back with another weekly Luau release!
Language
- Adds the
constkeyword for defining constant bindings that are statically forbidden to be reassigned to. This implements luau-lang/rfcs#166. - Adds a collection of new math constants to Luau's
mathlibrary per luau-lang/rfcs#169.
Analysis
- Fixes a class of bugs where Luau would not retain reasonable upper or lower bounds on free types, resulting in types snapping to
neverorunknowndespite having bounds.
--!strict
-- `lines` will be inferred to be of `{ string }` now, and prior
-- was
local lines = {}
table.insert(lines, table.concat({}, ""))
print(table.concat(lines, "\n"))--!strict
-- `buttons` will be inferred to be of type `{ { a: number } }`
local buttons = {}
table.insert(buttons, { a = 1 })
table.insert(buttons, { a = 2, b = true })
table.insert(buttons, { a = 3 })- Disables the type error from
string.formatwhen called with a dynamically-determined format string (i.e. a non-literal string argument with the typestring) in response to user feedback about it being too noisy. - Resolves an ICE that could occur when type checking curried generic functions. Fixes #2061!
- Fixes false positive type errors from doing equality or inequality against
nilwhen indexing from a table - In #2256, adds a state parameter to the
useratomcallback for consistency with other callbacks.
Compiler
- Improves the compiler's type inference for vector component access, numerical for loops, function return types and singleton type annotations, fixing #2244 #2235 and #2255.
Native Code Generation
- Fixes a bug where some operations on x86_64 would produce integers that would take up more than 32-bits when a 32-bit integer is expected. We resolve these issues by properly truncating to 32-bits in these situations.
- Improves dead store elimination for conditional jumps and fastcalls arguments, improving overall native codegen performance by about 2% on average in benchmarks, with some benchmarks as high as 25%.
Contributors
Co-authored-by: Andy Friesen afriesen@roblox.com
Co-authored-by: Ariel Weiss arielweiss@roblox.com
Co-authored-by: David Cope dcope@roblox.com
Co-authored-by: Hunter Goldstein hgoldstein@roblox.com
Co-authored-by: Ilya Rezvov irezvov@roblox.com
Co-authored-by: Thomas Schollenberger tschollenberger@roblox.com
Co-authored-by: Varun Saini vsaini@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
Full Changelog: 0.710...0.711
0.710
Hello! Another week with updates to type analysis and fixes in compiler and native code generation.
Breaking C API change: the useratom callback function now has an extra argument for lua_State pointer. If you are using string atom identifiers, add an argument in your handler.
Analysis
- Table types are treated as shape types when normalizing against an extern type. This allows intersections against extern types to provide information on additional properties not declared in an extern type, but present for that particular value:
function take(thing: Instance & { Brushes: Instance })
print(thing)
print(thing.Brushes.Name)
end- Fixed another crash which could happen when auto-complete visits a table with write-only properties
Require library
- During path resolution, we now reset to the requirer's context before
to_alias_overrideis called, enabling embedders to implement context-sensitive alias overrides
Compiler
- In a fast-call fallback sequence,
GETGLOBAL/GETUPVALwill never use extra registers (Fixes #2248)
Native Code Generation
- A counter system has been added which is used by native execution to report regular/fallback block execution and VM side exit statistics. When using
--codegentogether with--countersin Luau REPL,callgrind.outfile is written containing the counter data to view in callgrind/cachegrind tools - Fixed an issue where
setfenvchange could have been ignored, executing fast-paths for longer than is allowed - Stability improvements
Community Contributions
- Pass a state parameter to
useratomby @jackdotink in #2256
Co-authored-by: Andy Friesen afriesen@roblox.com
Co-authored-by: Ariel Weiss arielweiss@roblox.com
Co-authored-by: Sora Kanosue skanosue@roblox.com
Co-authored-by: Varun Saini vsaini@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
Full Changelog: 0.709...0.710
0.709
We skipped the release last week, but we're back today with some new additions to the VM and Native Code Generation (and as always, improvements to typechecking).
Analysis
- Fixed some instances of "unreduced table types" like { x: number } | { x: number }, especially for data-like arrays (extremely large tables that have the same element of a given type).
-- Prior, hovering would claim `t: {{number} | {number}}`, and now
-- we will claim it is a `{{number}}`
local t = {
{1, 2, 3},
{4, 5, 6}
}- Fixed a bug where user defined type function could crash if passed too many arguments.
- Enables autocomplete to use type information for function arguments to suggest results when those types are variadic. For example:
local function foo(...: "Val1") end
foo(@1)will now suggest "Val1"
- Partially annotated local statements with type packs on the right-hand-side (see example) are now correctly inferred. Prior, we mishandled this case in a way that caused subsequent assignments to assume the first element of the type pack corresponded to the first unannotated element:
local function foo(): (number, boolean, string)
return 1, true "three"
end
-- Prior to this fix, we inferred that `y: number` for this statement ...
local x: number, y, z: string = foo()
-- ... similarly, this would have inferred `z: number` ...
local x: number, y: boolean, z = foo()
-- ... and this would have inferred `y: number` and `z: boolean`
local x: number, y, z = foo()VM
- Fix a use-after-free in
table.find.
Native Code Generation
- Fix a bug in NCG caused by using an incorrect operand in a buffer length check.
- NCG now unmaps executable pages when functions are garbage-collected.
- Provide a native implementation for
math.isnan
Co-authored-by: Hunter Goldstein hgoldstein@roblox.com
Co-authored-by: Ilya Rezvov irezvov@roblox.com
Co-authored-by: Sora Kanosue skanosue@roblox.com
Co-authored-by: Varun Saini vsaini@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
0.708
Another week, another release!
Analysis
- Defining aliases that share a name with the built in types is now disallowed; this was the case in the old solver but never made its way to the new solver.
- Incremental work toward removing
FFlagLuauSolverV2from the Analysis codebase. - Fix a bug that caused nested tables to be parsed as
AstTypeReference. - Fix a bug related to visiting
AstExprInstantiatenodes. - Recursive functions defined on tables and as globals will now more consistently infer, such as in:
local coolmath = {}
function coolmath.factorial(n: number)
if n <= 1 then
return 1
end
-- Prior, this being recursive might have caused strange errors or for constraint
-- solving to be incomplete.
return coolmath.factorial(n - 1) * n
endNative CodeGen
- Support lowering for
bit32.band/bor/bxor/btestcalled with a single argument. - Add missing table data invalidations to load-store optimization.
- Fix missing condition for new dead store optimization.
- Implement load-store propagation for table nodes and array elements.
Miscellaneous
- Various improvements to our lldb formatter under
tools: better compatibility with older Python versions and support forTStringandTValue.
Co-authored-by: David Cope dcope@roblox.com
Co-authored-by: Hunter Goldstein hgoldstein@roblox.com
Co-authored-by: Sora Kanosue skanosue@roblox.com
Co-authored-by: Varun Saini vsaini@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
0.707
Hello Luaunators! This release comes with an API change for users of Luau.Require and some nice improvements for the bytecode compiler and native codegen!
Require Library
For users of Luau.Require's RequireNavigator: getRequirerIdentifier and reset have been merged into a single resetToRequirer API. This reflects existing usage, where the identifier returned by getRequirerIdentifier was always immediately passed to reset. The API surface is simpler, and this eliminates the artificial bottleneck of communicating requirer state via a std::string identifier.
Runtime
- Inlining at bytecode compile time now retains information about builtin symbols, so
FASTCALLs can be emitted when appropriate, such as in:
local function tryWithZero(f, x)
return f(x, 0)
end
return function (n)
-- If we inline `tryWithZero`, we'll be able to emit a
-- FASTCALL opcode when compiling the now inlined
-- `math.max(n, 0)`
return tryWithZero(math.max, n)
end- NCG: Fixed a crash resulting from partially eliminated dead store instructions: we would incidentally mark a floating point value as a potential pointer into the heap, which could crash during garbage collection.
- NCG: Add vectorized instruction support for
min,max,floor,ceil, andabs - NCG: Fixed a crash when constant folding a buffer access using an offset outside the representable range of integers.
- Add support for constant folding vector component access at bytecode compile time.
Co-authored-by: Andy Friesen afriesen@roblox.com
Co-authored-by: Sora Kanosue skanosue@roblox.com
Co-authored-by: Varun Saini vsaini@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
0.706
Hey everyone! We've been hard at work fixing bugs and improving native codegen. Enjoy!
Analysis
-
Rename the class tag to extern in type functions
-
Fix #2204
-
Rework type unification in terms of subtyping.
This uses the new solver's understanding of subtyping to drive unification for
some internal callsites. This is a broad change that should result in more
consistent inference. For example:local function sum<T>(x: T, y: T, z: (T, T) -> T) return z(x, y) end local function sumrec(f: typeof(sum)) return sum(2, 3, function<X>(g: X, h: X): add<X, X> return g + h end) end -- Prior we would claim that `b` is of type `add<X, X> | number`: not good! -- We now correctly claim that it is of type `number` thanks to bug fixes -- made to subtyping that did not make their way to the unifier. local b = sumrec(sum)
Native Codegen
- Improve vector handling in binary operations
- Fix missed optimization causing an assertion failure
- Propagate loads of STORE_VECTOR components produced by UINT_TO_FLOAT
- Constant-fold new operand of CHECK_BUFFER_LEN
- For register load-store propagation, use the second operand only for LOAD_FLOAT
- TValue store cannot be removed when it's partially over-written
- Rework equality and ordering comparisons to fix issues and be more type aware
- Migrate Luau NCG IrInst operands representation to SmallVector
Runtime
- Fix 64-bit countrz to build on 32 bit Windows.
- Remap Luau local debug and type information after performing jump expansion
- Add support for building Luau as a shared library
- Luau should be able to make fastcalls even if library name is obscured by a local polyfill
OSS Contributions
- Track type spans in
ToStringResultto support decomposition #2163 - Expose
luaL_tracebackfrom Lua C API #2167
Internal Contributors
Co-authored-by: Ariel Weiss arielweiss@roblox.com
Co-authored-by: Hunter Goldstein hgoldstein@roblox.com
Co-authored-by: Ilya Rezvov irezvov@roblox.com
Co-authored-by: Varun Saini vsaini@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
Full Changelog: 0.705...0.706