Luau is our new language that you can read more about at https://luau-lang.org.
Singleton types
We added support for singleton types! These allow you to use string or boolean literals in types. These types are only inhabited by the literal, for example, if a variable x
has type "foo"
, then x == "foo"
is guaranteed to be true.
Singleton types are particularly useful when combined with union types, for example:
type Animals = "Dog" | "Cat" | "Bird"
or:
type Falsey = false | nil
In particular, singleton types play well with unions of tables, allowing tagged unions (also known as discriminated unions):
type Ok<T> = { type: "ok", value: T }
type Err<E> = { type: "error", error: E }
type Result<T, E> = Ok<T> | Err<E>
local result: Result<number, string> = ...
if result.type == "ok" then
-- result :: Ok<number>
print(result.value)
elseif result.type == "error" then
-- result :: Err<string>
error(result.error)
end
The RFC for singleton types is https://github.com/Roblox/luau/blob/master/rfcs/syntax-singleton-types.md
Width subtyping
A common idiom for programming with tables is to provide a public interface type, but to keep some of the concrete implementation private, for example:
type Interface = {
name: string,
}
type Concrete = {
name: string,
id: number,
}
Within a module, a developer might use the concrete type, but export functions using the interface type:
local x: Concrete = {
name = "foo",
id = 123,
}
local function get(): Interface
return x
end
Previously examples like this did not typecheck but now they do!
This language feature is called width subtyping (it allows tables to get wider, that is to have more properties).
The RFC for width subtyping is https://github.com/Roblox/luau/blob/master/rfcs/sealed-table-subtyping.md
Typechecking improvements
- Generic function type inference now works the same for generic types and generic type packs.
- We improved some error messages.
- There are now fewer crashes (hopefully none!) due to mutating types inside the Luau type checker.
- We fixed a bug that could cause two incompatible copies of the same class to be created.
- Luau now copes better with cyclic metatable types (it gives a type error rather than hanging).
- Fixed a case where types are not properly bound to all of the subtypes when the subtype is a union.
- We fixed a bug that confused union and intersection types of table properties.
- Functions declared as
function f(x : any)
can now be called asf()
without a type error.
API improvements
- Implement
table.clone
which takes a table and returns a new table that has the same keys/values/metatable. The cloning is shallow - if some keys refer to tables that need to be cloned, that can be done manually by modifying the resulting table.
Debugger improvements
- Use the property name as the name of methods in the debugger.
Performance improvements
- Optimize table rehashing (~15% faster dictionary table resize on average)
- Improve performance of freeing tables (~5% lift on some GC benchmarks)
- Improve gathering performance metrics for GC.
- Reduce stack memory reallocation.