### What's new?
* Removed new `table.move` optimization because of correctness problems.
### New Type Solver
* Improved error messages for type families to describe what's wrong in
more detail, and ideally without using the term `type family` at all.
* Change `boolean` and `string` singletons in type checking to report
errors to the user when they've gotten an impossible type (indicating a
type error from their context).
* Split debugging flags for type family reduction
(`DebugLuauLogTypeFamilies`) from general solver logging
(`DebugLuauLogSolver`).
* Improve type simplification to support patterns like `(number |
string) | (string | number)` becoming `number | string`.
### Native Code Generation
* Use templated `luaV_doarith` to speedup vector operation fallbacks.
* Various small changes to better support arm64 on Windows.
### Internal Contributors
Co-authored-by: Aaron Weiss <aaronweiss@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: James McNellis <jmcnellis@roblox.com>
Co-authored-by: Vighnesh Vijay <vvijay@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
---------
Co-authored-by: Alexander McCord <amccord@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: Vighnesh <vvijay@roblox.com>
Co-authored-by: Aviral Goel <agoel@roblox.com>
Co-authored-by: David Cope <dcope@roblox.com>
Co-authored-by: Lily Brown <lbrown@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
In the readme file under the building section, it specifies that you
should run the command `mkdir cmake && cd cmake`; however, the folder is
not currently being ignored.
### New Type Solver
* Fixed crash in numeric binary operation type families
* Results of an indexing operation are now comparable to `nil` without a
false positive error
* Fixed a crash when a type that failed normalization was accessed
* Iterating on a free value now implies that it is iterable
---
### Internal Contributors
Co-authored-by: Aaron Weiss <aaronweiss@roblox.com>
Co-authored-by: Alexander McCord <amccord@roblox.com>
Co-authored-by: James McNellis <jmcnellis@roblox.com>
Co-authored-by: Vighnesh Vijay <vvijay@roblox.com>
# What's changed?
* Optimize table.maxn. This function is now 5-14x faster
* Reserve Luau stack space for error message.
## New Solver
* Globals can be type-stated, but only if they are already in scope
* Fix a stack overflow that could occur when normalizing certain kinds
of recursive unions of intersections (of unions of intersections...)
* Fix an assertion failure that would trigger when the __iter metamethod
has a bad signature
## Native Codegen
* Type propagation and temporary register type hints
* Direct vector property access should only happen for names of right
length
* BytecodeAnalysis will only predict that some of the vector value
fields are numbers
---
## Internal Contributors
Co-authored-by: Alexander McCord <amccord@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: Aviral Goel <agoel@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
table.concat is idiomatic and should be the fastest way to concatenate
all table array elements together, but apparently you can beat it by
using `string.format`, `string.rep` and `table.unpack`:
```lua
string.format(string.rep("%*", #t), table.unpack(t))
```
... this just won't do, so we should fix table.concat performance.
The deficit comes from two places:
- rawgeti overhead followed by other stack accesses, all to extract a
string from what is almost always an in-bounds array lookup
- addlstring overhead in case separator is empty (extra function calls)
This change fixes this by using a fast path for in-bounds array lookup
for a string. Note that `table.concat` also supports numbers (these need
to be converted to strings which is a little cumbersome and has innate
overhead), and out-of-bounds accesses*. In these cases we fall back to
the old implementation.
To trigger out-of-bounds accesses, you need to skip the past-array-end
element (which is nil per array invariant), but this is achievable
because table.concat supports offset+length arguments. This should
almost never come up in practice but the per-element branches et al are
fairly cheap compared to the eventual string copy/alloc anyway.
This change makes table.concat ~2x faster when the separator is empty;
the table.concat benchmark shows +40% gains but it uses a variety of
string separators of different lengths so it doesn't get the full
benefit from this change.
---------
Co-authored-by: vegorov-rbx <75688451+vegorov-rbx@users.noreply.github.com>
# What's changed?
### New Type Solver
- Unification of two fresh types no longer binds them together.
- Replaced uses of raw `emplace` with `emplaceType` to catch cyclic
bound types when they are created.
- `SetIndexerConstraint` is blocked until the indexer result type is not
blocked.
- Fix a case where a blocked type got past the constraint solver.
- Searching for free types should no longer traverse into `ClassType`s.
- Fix a corner case that could result in the non-testable type `~{}`.
- Fix incorrect flagging when `any` was a parameter of some checked
function in nonstrict type checker.
- `IterableConstraint` now consider tables without `__iter` to be
iterables.
### Native Code Generation
- Improve register type info lookup by program counter.
- Generate type information for locals and upvalues
---
### Internal Contributors
Co-authored-by: Aaron Weiss <aaronweiss@roblox.com>
Co-authored-by: Alexander McCord <amccord@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: James McNellis <jmcnellis@roblox.com>
Co-authored-by: Vighnesh Vijay <vvijay@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
---------
Co-authored-by: Aaron Weiss <aaronweiss@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: Vighnesh <vvijay@roblox.com>
Co-authored-by: Aviral Goel <agoel@roblox.com>
Co-authored-by: David Cope <dcope@roblox.com>
Co-authored-by: Lily Brown <lbrown@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
# What's changed?
* Improved the actual message for the type errors for `cannot call
non-function` when attempting to call a union of functions/callable
tables. The error now correctly explains the issue is an inability to
determine the return type of the call in this situation.
* Resolve an issue where tables and metatables were not correctly being
cloned during instantiation (fixes#1176).
* Refactor `luaM_getnextgcopage` to `luaM_getnextpage` (generally
removing `gco` prefix where appropriate).
* Optimize `table.move` between tables for large ranges of elements.
* Reformat a bunch of code automatically using `clang-format`.
### New Type Solver
* Clean up minimally-used or unused constraints in the constraint solver
(`InstantiationConstraint`, `SetOpConstraint`,
`SingletonOrTopTypeConstraint`).
* Add a builtin `singleton` type family to replace
`SingletonOrTopTypeConstraint` when inferring refinements.
* Fixed a crash involving type path reasoning by recording when type
family reduction has taken place in the path.
* Improved constraint ordering by blocking on unreduced types families
that are not yet proven uninhabitable.
* Improved the handling of `SetIndexerConstraints` for both better
inference quality and to resolve crashes.
* Fix a crash when normalizing cyclic unions of intersections.
* Fix a crash when normalizing an intersection with the negation of
`unknown`.
* Fix a number of crashes caused by missing `follow` calls on `TypeId`s.
* Changed type family reduction to correctly use a semantic notion of
uninhabited types, rather than checking for `never` types specifically.
* Refactor the `union` and `intersect` type families to be variadic.
### Native Code Generation
* Improve translation for userdata key get/set and userdata/vector
namecall.
* Provide `[top level]` and `[anonymous]` as function names to
`FunctionStats` as appropriate when no function name is available.
* Disable unwind support on Android platforms since it is unsupported.
*
---
### Internal Contributors
Co-authored-by: Aaron Weiss <aaronweiss@roblox.com>
Co-authored-by: Alexander McCord <amccord@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: Aviral Goel <agoel@roblox.com>
Co-authored-by: Vighnesh Vijay <vvijay@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
---------
Co-authored-by: Alexander McCord <amccord@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: Vighnesh <vvijay@roblox.com>
Co-authored-by: Aviral Goel <agoel@roblox.com>
Co-authored-by: David Cope <dcope@roblox.com>
Co-authored-by: Lily Brown <lbrown@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
# What's changed?
* Support for new 'require by string' RFC with relative paths and
aliases in now enabled in Luau REPL application
### New Type Solver
* Fixed assertion failure on generic table keys (`[expr] = value`)
* Fixed an issue with type substitution traversing into the substituted
parts during type instantiation
* Fixed crash in union simplification when that union contained
uninhabited unions and other types inside
* Union types in binary type families like `add<a | b, c>` are expanded
into `add<a, c> | add<b, c>` to handle
* Added handling for type family solving creating new type families
* Fixed a bug with normalization operation caching types with unsolved
parts
* Tables with uninhabited properties are now simplified to `never`
* Fixed failures found by fuzzer
### Native Code Generation
* Added support for shared code generation between multiple Luau VM
instances
* Fixed issue in load-store propagation and new tagged LOAD_TVALUE
instructions
* Fixed issues with partial register dead store elimination causing
failures in GC assists
---
### Internal Contributors
Co-authored-by: Aaron Weiss <aaronweiss@roblox.com>
Co-authored-by: Alexander McCord <amccord@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: James McNellis <jmcnellis@roblox.com>
Co-authored-by: Vighnesh Vijay <vvijay@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
# What's Changed
## New Type Solver
- Many more fixes to crashes, assertions, and hangs
- Annotated locals now countermand the inferred types of locals, meaning
that for a type `type MyType = number | string`, `local foo : MyType =
5` behaves the same as `local foo = 5 :: MyType`, where before, foo
would be assigned the type of the value on the rhs.
- Type Normalization now respects resource limits.
- Subtyping between classes and cyclic tables now supported
## Native Code Generation
- Work on the Native Code Generation(NCG) allocator continues
---
# Internal Contributors
Co-authored-by: Aaron Weiss <aaronweiss@roblox.com>
Co-authored-by: Alexander McCord <amccord@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: James McNellis <jmcnellis@roblox.com>
Co-authored-by: Vighnesh Vijay <vvijay@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
---------
Co-authored-by: Aaron Weiss <aaronweiss@roblox.com>
Co-authored-by: Alexander McCord <amccord@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: Aviral Goel <agoel@roblox.com>
Co-authored-by: David Cope <dcope@roblox.com>
Co-authored-by: Lily Brown <lbrown@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
# What's Changed
## New Type Solver
- Many fixes to crashes, assertions, and hangs
- Binary type family aliases now have a default parameter
- Added a debug check for unsolved types escaping the constraint solver
- Overloaded functions are no longer inferred
- Unification creates additional subtyping constraints for blocked types
- Attempt to guess the result type for type families that are too large
to resolve timely
## Native Code Generation
- Fixed `IrCmd::CHECK_TRUTHY` lowering in a specific case
- Detailed compilation errors are now supported
- More work on the new allocator
---
# Internal Contributors
Co-authored-by: Aaron Weiss <aaronweiss@roblox.com>
Co-authored-by: Alexander McCord <amccord@roblox.com>
Co-authored-by: Andy Friesen <afriesen@roblox.com>
Co-authored-by: James McNellis <jmcnellis@roblox.com>
Co-authored-by: Lily Brown <lbrown@roblox.com>
Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
Co-authored-by: Vighnesh Vijay <vvijay@roblox.com>