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.708 source code.tar.gz (2.2 MB)
Email in envelope

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

Home / 0.705
Name Modified Size InfoDownloads / Week
Parent folder
luau-windows.zip 2026-01-16 2.6 MB
Luau.Web.js 2026-01-16 3.7 MB
luau-ubuntu.zip 2026-01-16 6.3 MB
luau-macos.zip 2026-01-16 4.7 MB
0.705 source code.tar.gz 2026-01-16 2.1 MB
0.705 source code.zip 2026-01-16 2.5 MB
README.md 2026-01-16 7.2 kB
Totals: 7 Items   22.0 MB 1

Hello Luaunauts, we're continuing into the second release of the year at a brisk pace! We've got a number of improvements for both native code generation and the new type solver, as well as some other assorted changes, that keep us moving towards the goal of making the best possible scripting language!

Analysis

  • Refinements against a union of tables would sometimes erroneously refine to a narrower type than intended. The root cause here was a bug in the logic that determines how to "simplify" types (for example knowing that true | false is the same as boolean). ```luau export type States = "Closed" | "Closing" | "Opening" | "Open" export type MyType = { State: States, IsOpen: boolean, Open: (self: MyType) -> (), }

local value = {} :: MyType

function value:Open() if self.IsOpen == true then elseif self.State == "Closing" or self.State == "Opening" then -- Prior, this line errored as we were erroneously refining -- self with { State: "Closing" | "Opening" } rather -- than `{ read State: "Closing" | "Opening" } self:Open() end end ```

  • Adds an option in ToString.cpp to disable the use of synthetic names, which can be used to improve the quality of hover type.
  • Fixes a bug where table.freeze would incorrectly error on arguments of any type (fixes [#2181])
  • Subtyping mistakenly did not allow for us to covariantly check tables with missing properties against table types that gave those properties optional types. This release should fix these issues, including fixes [#2164].
  • Type functions have a global environment that defines all of the type aliases present in the environment around the type function definition, and the API of type functions also allows you to mutate types, specifically table types and function types. Though we never supported the type functions actually mutating the aliases present in the environment around them, the mutable API allowed for users to author type functions that appeared to do so, which could be confusing when they later discover that their mutation did not take place. This release introduces new errors for type functions that attempt to call mutable APIs on types from their environment, e.g. luau type myType = {} type function create_table_with_key() myType:setproperty(types.singleton "key", types.optional(types.number)) -- this errors now! return myType end local my_tbl: create_table_with_key<> = {key = "123"}
  • Bidirectional inference for lambdas on extern types with generic parameters should work more consistently.
  • [#2166] fixes a bug with findBindingAtPosition that should enable LSP tools to better support finding references for local functions and their parameters.
  • This release also includes a broad-strokes improvement to error suppression handling. The New Type Solver should now be more consistent about not reporting (or re-reporting) errors involving any or *error-type* or directly downstream of an existing type error.
  • This release removes the experimental DebugLuauStringSingletonBasedOnQuotes flag that trialed basing singleton type inference solely on the usage of different quote styles. We do not think we will be proceeding with this approach at this time.

Native Code Generation

  • Fixes a crash in getOffsetBase when the passed in IrOp is not an IrInst.
  • Improves inlining support by passing the argument value as the initializer for the temporary being allocated in cases like anonymous function arguments or referring to upvalues in a function body.
  • Fixes the function end byte offset value, along side a number of other internal values that could lead to incorrect code size values.
  • Adds a more direct implementation of code generation for vector equality and inequality that leads to fewer instructions in the IR and a smaller number of produced basic blocks.
  • Adds a more optimized code generation flow for situations where we're indexing a table with keys that have unexpected type tags.
  • Fixes a bug where NCG would sometimes mistakenly optimize away necessary entry tag checks.
  • Introduces a customizable per-VM storage for use from "execution callbacks" system, with NCG as its first consumer for extra spill spaces. This adds 32x 8-byte spill slots on arm64 (on top of existing 22) and 64x 8-byte spill slots on x64 (on top of existing 12*).
  • Changes codegen for bit32 operations to use guards, rather than normal control flow, leading to significant (~30%) performance improvements in some benchmarks that heavily leverage these operations.
  • Adds a combined instruction UINT_TO_FLOAT to replace instances where we needed to emit UINT_TO_NUM and NUM_TO_FLOAT paired up. This leads to some very modest performance improvements.

Runtime

Internal Contributors

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: James McNellis jmcnellis@roblox.com Co-authored-by: Sora Kanosue skanosue@roblox.com Co-authored-by: Vighnesh Vijay vvijay@roblox.com Co-authored-by: Vyacheslav Egorov vegorov@roblox.com

OSS Contributions

New Contributors

Full Changelog: https://github.com/luau-lang/luau/compare/0.704...0.705

Source: README.md, updated 2026-01-16