Tags: luau-lang/luau
Tags
Sync to upstream/release/694 (#2033) ## 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>
Sync to upstream/release/693 (#2021) # 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>
Sync to origin/release/692 (#2012) 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>
Sync to upstream/release/691 (#1998) # New Type Solver * Fixed #1983 by adding additional context to permit some expressions otherwise not allowed * We now skip issuing CheckedFunctionWarnings on use of unreduced type functions * Fix gcc compile error * Handle expressions `a == b` and `a ~= b` more efficiently * Subtyping now correctly handles generics over unions and intersections in cases such as ``` local function a<T>(arr: { T }) end a({ 'one', 'two' }) ``` * Rearrange unification cases to avoid free type generalization to never * Improve generic bounds mismatch error message * Fix Ancestry bug in visitor for incomplete repeat blocks such as ``` local t = {} function t:Foo() end repeat t:| ``` * Support autocomplete for attributes # Native Codegen * Unwind info has support on Android * Introduced a separate ctypeof function which does not constant-fold for vector arguments. * We now perform string concatenation at compile time if possible (there is a known issue with the optimization that we will address next week) * Make vector.lerp and math.lerp more efficient with FMA * Record STORE_SPLIT_TVALUE as a potential restore operation to reduce number of spills to stack * When native execution is disabled, we now mark the call frame as not executing natively, making resumption safer --- 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: Varun Saini <vsaini@roblox.com> Co-authored-by: Vighnesh Vijay <vvijay@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: 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>
Sync to upstream/release/690 (#1992) # New Type Solver * Improve the error message for an uninstantiated type alias, as in: ```luau type Packed<T...> = (T...) -> T... local a: Packed -- Now has a single, specific, error ``` * Improve refinements of extern types against table types, ensuring the extern part is dropped less often, as in: ```luau local function update(foo: Instance) assert(foo.Name == "bubbles") -- Previously might have been `{ read Name: "bubbles" }`, -- will now be `Instance & { read Name: "bubbles" }` return foo end ``` * Resolve an internal complier exception when attempting to use `typeof` inside the generic type default of an alias. Fixes #1462. * No longer throw an internal compiler exception for exceptionally large ASTs, though a `CodeTooComplex` error will still be raised. * Broadly rework generic pack subtyping to allow code like the following to type check without errors: ```luau function f(foo: (number) -> number): () end type T = <A...>(A...) -> number local t: T -- OK, as a function that takes some generic pack of arguments can receive a `number` as well. f(t) ``` * Report an error when a type pack is provided to a generic alias that can receive a type _and_ a type pack, as in: ```luau type Y<T = string, U... = ...string> = { a: (T) -> U... } -- Now errors as you must provide a type before the pack. local a: Y<...number> ``` * Fix an instance of generics leaking when returning a function from another function with explicitly defined generics. Fixes #1971. * Cache `HasPropConstraint`s such that for every pair of subject type and desired property, we only emit a single constraint and blocked type; this incidentally fixes some bugs around inferring the types of properties on `self`. * Table types associated with table literals are now tracked specially to make type checking more permissive, such as in: ```luau type Foo = { name: string?, flag: boolean? } local arr: {Foo} = {} local function foo(arg: {name: string}?) local name = if arg and arg.name then arg.name else nil -- Previously would error as bidirectional inference would not -- kick in as often. table.insert(arr, { name = name or "", flag = name ~= nil and name ~= "", }) end ``` # Native Codegen * Lowering to arm64 for some local heavy functions will now succeed whereas prior they failed due to running out of registers for live values. --- 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: Sora Kanosue <skanosue@roblox.com> Co-authored-by: Vighnesh Vijay <vvijay@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
Sync to upstream/release/689 (#1981) # General Improvements * Fix a crash that could occur when the `deprecated` attribute is used in a syntactically incorrect way. * Improve stack utilization in the parser. This should make it harder for deeply nested constructs to exhaust the C stack. * Fixed the `xpcall` continuation to handle errors handling the same way as main execution path. * The fuzzer now enables all Luau flags.. * The fuzzer will now add attributes and create table literal expressions. * The type of `rawget` is now `<K, V>(tab: {[K]: V}, k: K) -> V?` to reflect the fact that it returns `nil` when the key is not present. * Implement native codegen lowering for `vector.lerp` # Autocomplete * Autocomplete will also now suggest hot comments like `--!strict` and `--!optimize` * Incremental autocomplete had a bug where it wasn't selecting the correct refinement of the autocomplete subject. This is now fixed. # New Solver * Fix an incorrect refinement that caused autocomplete to fail on statements of the following form: `if #some_local.` * Improve the error feedback when a type function is not passed required arguments. (ie no `<>` afterward at all) * Improvements to bidirectional table inference ## 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: Varun Saini <vsaini@roblox.com> Co-authored-by: Vighnesh Vijay <vvijay@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: Ariel Weiss <aaronweiss@roblox.com>
Sync to upstream/release/687 (#1954) ## 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](https://rfcs.luau.org/syntax-attribute-functions-deprecated.html) For example: ```luau @[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)) return -1; lua_pushcfunction(L, test, nullptr); 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>
Sync to upstream/release/686 (#1948) ## General 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. ### 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 of `argument #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>
Sync to upstream/release/685 (#1940) Another week, another release! ## Analysis - Do not warn on unknown `require`s in non-strict mode. - Improve `Luau::dump`'s output for `DenseHashMap`. - 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` in `ClonePublicInterface` with a `solverMode` field. - Limit the number of constraints that can be dynamically created to fail more gracefully in complex cases. - Fix #1932. --------- 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>
PreviousNext