Releases: luau-lang/luau
0.688
Hi there guys & gals & non-binary pals, hope everyone has been enjoying their summer as it winds down! We're coming at y'all this week with another collection of Luau updates largely focused on polishing up the New Type Solver and tackling some of the biggest issues folks are experiencing today.
What's Changed?
- Implement
vector.lerp
method as a fastcall, support for native code generation coming soon (re: #1936 and luau-lang/rfcs#132) - Introduce
CMP_INT
to the Native Code Generation IR to improve the overall code generation forbit32.btest
, eliminating an unnecessary branch and fixed a failing assertion in lowering. - Fix a crash in the old type solver where committing a transaction log (a finalizing operation for unification during the type inference implementation) would sometimes create a tightly-recursive type.
- Change Luau's autocompletion service to be aware of contextual keywords for loops, so
break
andcontinue
will no longer be suggested while editing code outside of loop constructs.
New Type Solver
- We're interested in figuring out the best way to deal with singleton type inference, as it's a common pain-point expressed to us by developers in both the new and old type inference engines. Towards that end, in the new type solver, we've implemented an experimental approach (gated by
FFlagDebugLuauStringSingletonBasedOnQuotes
) that simplifies the singleton inference model a lot. With this flag enabled, the type of a string literal will bestring
whenever it uses double-quotes or backticks for interpolation, and the corresponding singleton type (e.g.'foo'
for'foo'
) when it uses a single-quote. We would love for folks to try out Luau with this flag intentionally enabled in code where they were previously having issues, and let us know about their experience with it! - Adjust the behavior of typechecking tables again to correct a mistake from last release where we unintentionally made it illegal to use a table that has both a number indexer (i.e. an array portion) and a number of string properties.
- Improve overall type inference performance by changing the vast majority of our visitors to using a skip bound types option. This should not represent any behavioral difference, but should pull out a lot of wasted cycles on following indirections.
- Fix a bug where we would mistakenly not report errors when the inferred instantiation of some polymorphic type was impossible, e.g. something like
table.insert
's signature of<T>({T}, T) -> ()
where the array type at a particular call site is{number}
and the inserted argument isstring
. - Resolve some reports of false positive type errors caused by variadic
...any
types on function types causing type mismatches. - Fix a crash caused by iterator invalidation when processing nested user-defined type functions.
Internal Contributors
Co-authored-by: Andy Friesen afriesen@roblox.com
Co-authored-by: Annie Tang annietang@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
0.687
What's Changed?
This week we have an update with an implementation for one of the RFCs we had approved before, an improvement of the new type solver and a small Lua 5.1 C API compatibility improvement.
@deprecated
attribute can now have a custom suggestion for a replacement and a reason message as described in 'deprecated' attribute parameters RFC
For example:
@[deprecated {reason = "foo suffers from performance issues", use = "bar"}]
local function foo()
...
end
-- Function 'foo' is deprecated, use 'bar' instead. foo suffers from performance issues
foo()
lua_cpcall
C API function has been restored both for compatibility with Lua 5.1 and as a safe way to enter protected call environment to work with Luau C API functions that may error
Instead of
if (!lua_checkstack(L, 2)) // have to ensure stack space is available
return -1;
lua_pushcfunction(L, test, nullptr); // can error on out-of-memory
lua_pushlightuserdata(L, context);
int status = lua_pcall(L, 1, 0, 0);
you can simply do
int status = lua_cpcall(L, test, context);
- In Luau CLI, required module return values can now have any type
New Type Solver
- Additional improvements on type refinements used with external types should fix some reported false positive errors where types refined to
never
- Fixed an issue in recursive refinement types in a form of
t1 where t1 = refine<t1, _>
getting 'stuck' - Fixed an issue in subtyping of generic functions, it is now possible to assign
<T>(T, (T) -> T) -> T
to(number, <X>(X) -> X) -> number
- Fixed an ICE caused by recursive types (Fixes #1686)
- Added additional iteration and recursion limits to stop the type solver before system resources are used up
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: Sora Kanosue skanosue@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
Full Changelog: 0.686...0.687
0.686
What's Changed
This week has been spent mostly on fixing bugs in incremental autocomplete as well as making the new Type Solver more stable.
- Fixes a bug where registered "require" aliases were case-sensitive instead of case-insensitive (resolves #1931)
New Type Solver
- Adjust literal sub typing logic to account for unreduced type functions
- Implement a number of subtyping stack utilization improvements
- Emit a single error if an internal type escapes a module's interface
- Checked function errors in the New Non Strict warn about incorrect argument use with one-indexed positions, e.g.
argument #1 was used incorrectly
instead ofargument #0 was used incorrectly
. - Improvements to type function reduction that let us progress further while reducing
- Augment the generalization system to not emit duplicate constraints.
- Fix a bug where we didn't seal tables in modules that failed to complete typechecking.
Fragment Autocomplete
- Provide richer autocomplete suggestions inside of for loops
- Provide richer autocomplete suggestions inside of interpolated string expressions
- Improve the quality of error messages when typing out interpolated strings.
Compiler
- Fixes REX encoding of extended byte registers for the x86 assembly code generation.
- Fixes for table shape constant data encoding
Co-authored-by: Andy Friesen afriesen@roblox.com
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
Full Changelog: 0.685...0.686
0.685
What's Changed
Another week, another release!
General
Analysis
- Do not warn on unknown
require
s in non-strict mode. - Improve
Luau::dump
's output forDenseHashMap
. - Raise type checking errors when we would otherwise be leaking internal error types from modules.
- Fix a crash that would sometimes occur when calling a function with an incomplete type.
- Replace uses of
FFlag::LuauSolverV2
inClonePublicInterface
with asolverMode
field. - Limit the number of constraints that can be dynamically created to fail more gracefully in complex cases.
- Fix #1932.
New Contributors
Co-authored-by: Alexander Youngblood ayoungblood@roblox.com
Co-authored-by: Andy Friesen afriesen@roblox.com
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: Talha Pathan tpathan@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
Full Changelog: 0.684...0.685
0.684
It's Luau release time!
General
- Support AstStatDeclareGlobal output as a source string (via @karl-police in #1889)
- Luau heap dump correctly reports the size of a string, now including overhead for the string type
- Prevent yields from Luau
xpcall
error handling function.
Analysis
- Avoid exponential blowup when normalizing union of normalized free variables.
- Fix type pack-related bugs that caused infinite recursion when:
- A generic type pack was bound to itself during subtyping.
- In type pack flattening, when that same generic type pack was now being bound another generic type pack which contained it.
- Properly simplify
any & (*error-type* | string)
to*error-type* | *error-type* | string
instead of hanging due to creating a huge union type.
Co-authored-by: Andy Friesen afriesen@roblox.com
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: Vyacheslav Egorov vegorov@roblox.com
Full Changelog: 0.683...0.684
0.683
Another week, another release!
Analysis
- Hide errors in all solver modes (not just strict mode) if the only error is that type inference failed to complete.
- Make various analysis components solver-agnostic (
setType
,visit
,Scope
methods). - Fix an issue where type inference may fail to complete when assigning a table's member to the table itself.
- Fix a bug when accessing a table member on a local after the local is assigned to in an if-else block, loop, or other similar language construct.
- Fixes #1914.
- Fix type-checking of if-then-else expressions.
- Fixes #1815.
Co-authored-by: Hunter Goldstein hgoldstein@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
0.682
What's changed?
Another somewhat quiet week! Don't let the large PR fool you, this is mostly ...
New Solver
- The code for type functions has been re-organized: instead of everything living in
TypeFunction.h
andTypeFunction.cpp
, we now have separate files for the type function inference machinery (TypeFunction.h
), definitions of built-in type functions (BuiltinTypeFunctions.h
), and the implementation of user defined type functions (UserDefinedTypeFunction.h
). - Refinements against
*no-refine*
, a sentinel type indicating that no refinements should occur, are now always resolved, even if the target of the refinement would be otherwise pending, such as another type function.
Autocomplete
- Fixed autocomplete to prefer table property completion to string singleton completion. In the below example, the types associated with each member of
foo
will be displayed in autocomplete popups.
local foo = {
["Item/Foo"] = 42,
["Item/Bar"] = "it's true",
["Item/Baz"] = true,
}
foo["|"] -- cursor at `|`
Native Codegen
- Fixed native compilation lowering of the new global lookup instruction, which caused code generation to fail with an error or to evaluate incorrect results. Issue affected 678-681 releases when all flags were enabled.
Co-authored-by: Andy Friesen afriesen@roblox.com
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: Talha Pathan tpathan@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
0.681
What's Changed?
Short week, so a slightly shorter release! This one has been focused on improving polish in fragment autocomplete and the new solver.
New Type Solver
- Fix a bug where we didn't infer self types correctly under bidirectional type inference.
- Improve the memory consumption of the new solver by reducing the number of expensive allocations performed by
Substitution
. - The New non strict Mode shouldn't issue errors when we call checked functions with
never
values. - Extend the number of cases in which the new non strict mode can report unknown symbols.
- Fix a bug where
and
andor
expressions didn't correctly forward information computed by their operands. This should allow more programs using these expressions to complete typechecking correctly. - Small performance improvements for
Generalization
Fragment Autocomplete
- Fragment autocomplete provides richer autofill information when typing
self.|
- Fragment autocomplete now uses refinement information computed in the new solver to provide more accurate incremental completion.
Code Generation
- Fix a bug where Codegen could sometimes try to execute a non-executable page
Co-authored-by: Ariel Weiss aaronweiss@roblox.com
Co-authored-by: Hunter Goldstein hgoldstein@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com
Full Changelog: 0.680...0.681
0.680
What's Changed?
This week includes many changes to bring the behaviours of the Old and
New Luau Type Solver more in line.
- The old solver now stringifies tables identically to the new solver.
Sealed tables are stringified as{ ... }
and unsealed tables are
represented by{| ... |}
, regardless of your choice of solver.
New Type Solver
- Miscellaneous fixes to make the Luau Frontend able to dynamically
toggle which solve is used. - Small fixes to reduce instances of nondeterminism of the New Type
Solver. - Issue an error when a function that has multiple non-viable overloads
is used. - Subtyping now returns more information about the generics for type
inference to consume. - Stop stuck type-functions from blocking type inference. This should
lead to fewer instances of 'type inference failed to complete'.
Fragment Autocomplete
- Fixed a bug where incremental autocomplete wouldn't be able to provide
results directly on a required module script.
require(script.Module).{request completions here}
will now recommend
the properties returned by the required object.
Full Changelog: 0.679...0.680
Co-authored-by: Andy Friesen afriesen@roblox.com
Co-authored-by: Hunter Goldstein hgoldstein@roblox.com
Co-authored-by: Sora Kanosue skanosue@roblox.com
Co-authored-by: Talha Pathan tpathan@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
0.679
What's Changed?
We've been hard at work fixing bugs and introducing new features!
VM
- Include constant-folding information in Luau cost model for inlining and loop unrolling
- ~1% improvement in compile times
New Type Solver
Luau::shallowClone
's last argument, whether to clone persistent (builtin) types, is now non-optional.- Refinements on properties of tables are now computed with a
read
table property. This resolves some issues around refining table properies and then trying to set them. Fixes #1344. Fixes #1651.
if foo.bar then
-- Prior to this release, this would be `typeof(foo) & { bar: ~(false?) }
-- Now, this is `typeof(foo) & { read bar: ~(false?) }
end
- The type function
keyof
should respect the empty string as a property, as in:
-- equivalent to type Foo =""
type Foo = keyof<{ [""]: number }>
- Descend into literals to report subtyping errors for function calls: this both improves bidirectional inference and makes errors more specific. Before, the error reporting for a table with incorrect members passed to a function would cite the entire table, but now it only cites the members that are incorrectly typed.
- Fixes a case where intersecting two tables without any common properties would create
never
, instead of a table with both of their properties.
Internal Contributors
Co-authored-by: Ariel Weiss aaronweiss@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: Talha Pathan tpathan@roblox.com
Co-authored-by: Vighnesh Vijay vvijay@roblox.com
Co-authored-by: Vyacheslav Egorov vegorov@roblox.com