Skip to content

0.693

Choose a tag to compare

@github-actions github-actions released this 26 Sep 20:36
0084576

New Solver

  • Avoid bidirectional inference always forcing constraints for simple code such as the example below. Fixes #2017.
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.
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:
-- 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 thetable type to be a subtype of generic tables. This means code like the following no longer raises a type error:
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:
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" }
  • Fix perfect forwarding in TypedAllocator::allocate by @alexmccord in #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:
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

Full Changelog: 0.692...0.693