Skip to content

Conversation

@HaroldCindy
Copy link
Contributor

No description provided.

vrn-sn and others added 10 commits September 19, 2025 13:58
Another week, another release!

## Analysis/Autocomplete

- Improve recursive type lookups by using scoped tracking of processed
types.
- Enforce recursion limits in subtyping on type packs, not just on
types.
- Simplify type checking for intersections between tables and
discriminants containing read-only table properties.
- Allow fields provided by `__index` to satisfy subtyping relationships.
- Improve the ability for the type checker to do proper generic
substitution in `for ... in` loops.
- Fix a fragment autocomplete bug that caused fragments to be selected
incorrectly in `for ... in` loops.
- Fix a crash caused by `typeof` containing an unterminated function
definition: `typeof(function())`.
- Fix a flagging issue that may have been causing stack overflows in the
previous release.

## Runtime

- Support constant folding for interpolated strings.
- Fix a bug caused by the empty string being the result of constant
folding.
- Add helper macros in Bytecode.h to help access data in Luau auxiliary
instruction bits.
- Add support for branchless `==`/`~=` comparisons in CodeGen (in
certain cases).

---

Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: Annie Tang <annietang@roblox.com>
Co-authored-by: Ariel Weiss <aaronweiss@roblox.com>
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: Vighnesh Vijay <vvijay@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
The original wasn't actually allowing universal references and if you
have a datatype with a deleted copy constructor, the template
substitution would fail here. This lets me use `TypedAllocator` for some
type that isn't copyable. I doubt there would be any performance
difference due to copy elision anyway.
# New Solver
* Avoid bidirectional inference always forcing constraints for simple
code such as the example below. Fixes #2017.
```luau
type Suit = "Hearts" | "Spades" | "Clubs" | "Diamonds"

local getSuits(): { Suit }
    return { "Hearts", "Spades", "Clubs", "Diamonds" }
end
```
* Iterating over an empty pack, such as in the below example, should
error but still allow type inference to complete.
```luau
local function foo() end -- has type `() -> ()`
for _ in foo() do end -- Errors, as you can't iterate over `()`, but type inference still completes.
```
* Implement arity based overload selection: this allows for overloaded
functions with generics to more consistently infer reasonable results.
For example:
```luau
-- This code no longer errors  as we determine that the first overload to 
-- table.insert is what the author intended.
table.insert({} :: { any }, 42)
```
* Allow the`table` type to be a subtype of generic tables. This means
code like the following no longer raises a type error:
```luau
local function doSomething(t: unknown)
    if type(t) == "table" then
        -- Prior we would error as `table` is not a subtype of a generic table
        -- Also works with `pairs` and similar builtin functions.
        local foo, bar = next(t)
    end
end
```
* Descend into intersection types when performing bidirectional
inference, this allows us to correctly bidirectionally infer code like:
```luau
type A = { foo: "a" }
type B = { bar: "b" }
type AB = A & B
-- No longer errors as the literals "a" and "b" will be inferred to be their singleton types.
local t: AB = { foo = "a", bar = "b" }
```
* #2008
* Fix intersections between table types and extern types to preserve
intersections when either type contains an indexer, fixing a regression
introduced when trying to refine table and extern types more precisely:
```luau
function f(obj: { [any]: any }, functionName: string)
    if typeof(obj) == "userdata" then
        -- No longer errors as we still have a `class & { [any]: any }` rather than a `class`
        local _ = obj[functionName]
    end
end
```
* Separated recursion limits for different parts of the new solver. No
immediate changes, but this creates more tools to tamp down on stack
overflows without affecting other subsystems.

# Runtime
* Implement "stackless" `pcall` / `xpcall` in yieldable contexts: this
lets recursive calls to `pcall` nest further, erroring at the Luau call
stack limit (20000 calls as of this writing) rather than the C call
stack limit (200 calls as of this writing)

---

Co-authored-by: Ariel Weiss <aaronweiss@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>

---------

Co-authored-by: Varun Saini <61795485+vrn-sn@users.noreply.github.com>
Co-authored-by: Alexander Youngblood <ayoungblood@roblox.com>
Co-authored-by: Menarul Alam <malam@roblox.com>
Co-authored-by: Aviral Goel <agoel@roblox.com>
Co-authored-by: Vighnesh <vvijay@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
Co-authored-by: Ariel Weiss <aaronweiss@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
## What's Changed?

This week we have improvements in new type solver inference, performance
optimizations for the new type solver as well as fixes for optimization
passes in native code generation.

- Fixed the order of errors returned by `Frontend::getCheckResult` with
`accumulateNested` flag
- Typechecker now uses `userdata` instead of `class` as the extern type
name

## New Type Solver
- When a string is passed to a function expecting an argument that might
be a string singleton, bidirectional type inference will choose the
lower bound (string literal) for that argument (Fixes #2010)
- Fixed incorrect definition of `vector.lerp` (Fixes #2024)
- Added error suppression in type path traversal. Without it, errors
with `*error-type*` were sometimes visible (Fixes #1840)
- Fixed another case of combinatorial explosion in union type
normalization which could have caused a hang
- Fixed a crash on out-of-bounds access during `for..in` statement
typechecking

## Runtime
- Fixed an assertion in native code generation in a sequence of `nil`
and `boolean` stores to a local
- Fixed incorrect lowering in rare cases when LuauCodegenDirectCompare
was enabled

## Internal Contributors

Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: Annie Tang <annietang@roblox.com>
Co-authored-by: Ariel Weiss <aaronweiss@roblox.com>
Co-authored-by: Hunter Goldstein <hgoldstein@roblox.com>
Co-authored-by: Ilya Rezvov <irezvov@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
Hey there friends, apologies for the late release this week! Most of the
changes amount to essentially spring (really, autumn) cleaning as we
prepare for the next stage of release for the New Type Solver! We've
cleaned up lots of flags, enabled regression tests that had been
disabled because the New Type Solver did not support them, done some
refactoring and otherwise cleaned up bits of code. None of these are
really worth capturing beyond the high-level of saying we cleaned things
up, but there's also a few small runtime fixes that we'll describe
below.

### Runtime

- Fix a bug with the argument ordering for the `vblendvps` and
`vblendvpd` instructions in our Native Code Generation IR that led to
`vector.lerp` having the wrong argument order in some situations when
using NCG. `vector.lerp` should now behave correctly under NCG.
- Remove an incorrect debug assertion in Native Code Generation's
register allocation implementation for A64 assembly (i.e. for ARM's
64-bit architecture).

--- 

Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: Annie Tang <annietang@roblox.com>
Co-authored-by: Ariel Weiss <aaronweiss@roblox.com>
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: Vyacheslav Egorov <vegorov@roblox.com>

---------

Co-authored-by: Hunter Goldstein <hgoldstein@roblox.com>
Co-authored-by: Varun Saini <61795485+vrn-sn@users.noreply.github.com>
Co-authored-by: Alexander Youngblood <ayoungblood@roblox.com>
Co-authored-by: Menarul Alam <malam@roblox.com>
Co-authored-by: Aviral Goel <agoel@roblox.com>
Co-authored-by: Vighnesh <vvijay@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Hey everyone. In preparation for the next phase of the New Type Solver
rollout, we have another round of important bugfixes.

We've also got a few improvements to the new require alias machinery and
a little optimization to native codegen.

## New Type Solver

* Fix a case where Luau would erroneously simplify `{} & { p: number |
string }` to `number`.
* Fix a crash that could occur within generic substitution. TODO: Sora
to help word this.
* Fix a case where Luau would infer a spurious union type as the result
of a `setmetatable` call.
* Fix luau-lang/luau#1803
* Improve bidirectional inference of table literals in the case that the
expected type has an indexer.

## Luau.Require

* Zero-initialize `luarequire_Configuration` function pointers before
user initialization
* Error if ambiguity is detected during alias discovery

## Native Codegen

* Do not replace known constant value with a load propagation in
STORE_TVALUE

---------

Co-authored-by: Annie Tang <annietang@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: Vyacheslav Egorov <vegorov@roblox.com>
Another somewhat small release as we work our way up to the next stage
of the new type solver!

# General

* Implement configuration extraction as per the [Luau-syntax
configuration files
RFC](https://github.com/luau-lang/rfcs/blob/master/docs/config-luauconfig.md):
we now expose a low-level `extractConfig` API and a higher level
`extractLuauConfig` API for extracting configurations from these files.
The runtime and analysis integrations with `require`, for this feature,
are coming in a later release.

# Analysis

* Implemented native stack guards: on Windows and MacOS spots where we
attempt to guard against stack overflows by using a counter now _also_
check whether we are close to hitting the runtime stack limit via OS
specific APIs.
* Fix a performance issue that could occur when trying to reduce type
functions for math operations in the new solver, causing the new solver
to fail to solve all constraints and take a disproportionate amount of
time to finish solving.
* Improve the new solver's non-strict checking performance when checking
exceptionally large function calls and function definitions.

---------

Co-authored-by: Varun Saini <61795485+vrn-sn@users.noreply.github.com>
Co-authored-by: Alexander Youngblood <ayoungblood@roblox.com>
Co-authored-by: Menarul Alam <malam@roblox.com>
Co-authored-by: Aviral Goel <agoel@roblox.com>
Co-authored-by: Vighnesh <vvijay@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
Co-authored-by: Ariel Weiss <aaronweiss@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Well this is a pretty small thing. There is one NBSP in the document in
the file that I removed😅
# General

Another week, another release. Happy Halloween! 🎃

## Require
- Integrate support for `.config.luau` files into `Luau.Require` as part
of the [Luau-syntax configuration files
RFC](https://rfcs.luau.org/config-luauconfig.html).
  - `is_config_present` has been replaced with `get_config_status`.
- `get_luau_config_timeout` has been added to configure extraction
timeouts at runtime.
- Enable support for `.config.luau` files in `luau` and `luau-analyze`.
- Merge the `Luau.RequireNavigator` static library into `Luau.Require`.

## Analysis
- Add fuel-based limits for normalization: normalization will now take a
set number of steps (the "fuel") and stop when we hit a certain number
of steps ("run out of fuel"). This is in lieu of trying to check static
limits on the size of its inputs. This may result in seeing more "code
too complex" errors but should dramatically reduce the number of cases
where Luau becomes unresponsive and uses several gigabytes of memory. We
plan to tune this limit over time to find the right balance between
responsiveness and completeness.
- Fix a case where refining a variable with the type `any` would cause
it to become `unknown` instead due to normalization not preserving `any`
in the top type position.
- Improve the wording of type errors in the new non-strict mode.
- Fix #1910.
- Fix #2065.
- Fix #1483.
- Fix #2018.

## Miscellaneous
- Introduce `Luau::overloaded` to facilitate interacting with
`Luau::Variant`.
- Add type checking support to the [Luau demo](https://luau.org/demo)!

---

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: Ilya Rezvov <irezvov@roblox.com>
Co-authored-by: Sora Kanosue <skanosue@roblox.com>
Co-authored-by: Varun Saini <vsaini@roblox.com>
@HaroldCindy HaroldCindy closed this Nov 2, 2025
@HaroldCindy HaroldCindy reopened this Nov 2, 2025
@HaroldCindy HaroldCindy merged commit 39d5414 into main Nov 2, 2025
6 checks passed
@HaroldCindy HaroldCindy deleted the wip_merge branch November 4, 2025 00:47
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.

10 participants