Elixir 1.20 Reaches RC.4 With Type Inference of All Constructs, Closing a Three-Year Push Toward a Set-Theoretic Type System
The fourth release candidate for Elixir 1.20 lands ahead of a planned May 2026 final, capping the largest type-system milestone in the language's history with whole-function inference, cross-clause analysis, and a roughly 10% compiler speedup.
Overview
The Elixir core team has shipped v1.20.0-rc.4, the fourth and likely final release candidate before the language’s biggest type-system release reaches general availability in May 2026. According to the Elixir 1.20 changelog, rc.4 was tagged on March 31, 2026 and requires Erlang/OTP 27 or later.
The headline feature is comprehensive type inference: as creator Jose Valim wrote in the January 9 announcement marking 15 years since Elixir’s first commit, “the first release candidate for Elixir v1.20 is out and includes type inference of all constructs.” The work is the latest milestone in a multi-year program to retrofit a sound, gradual type system onto a language that has been resolutely dynamic since its 2011 debut.
What 1.20 Actually Adds
Elixir’s type system is described in the project’s documentation as “sound, gradual, and developer friendly.” The implementation, detailed on the gradual set-theoretic types reference page, composes basic types using set operations — unions, intersections, and negations — and includes a dynamic() type for code that has not yet been annotated.
With 1.20, the compiler now performs inference of whole functions rather than only patterns and guards, which had been the limit through the 1.18 and 1.19 series. The January announcement notes that the system tracks type information from guard clauses such as is_list/1, is_binary/1, and is_map_key/2, and propagates negative type information through pattern matches — so once a clause matches on nil, subsequent clauses know the bound variable can no longer be nil.
The Elixir Merge release notes for rc.2 and rc.3 report that rc.2, released March 4, extended inference to work across clauses of the same function, “leading to the detection of more bugs and dead code.” The same release recorded a roughly 10% compilation speedup and an opt-in interpreted-compilation mode that the team says can be up to five times faster depending on available cores. Rc.3, released March 9, focused on regression fixes for Enum, File, and Float.
Beyond the type system, the changelog lists new standard-library helpers including Integer.popcount/1, Integer.ceil_div/2, List.first!/1, List.last!/1, IO.iodata_empty?/1, and Process.get_label/1, alongside expanded support for all key domains — integers, floats, and atoms — in map type representations.
There is one notable behavioral break: map.foo() and mod.foo field-access syntax that previously emitted warnings now raises errors, a change the changelog describes as aligning runtime behavior with the new type system’s expectations.
A Three-Year Project, Not a Sudden Pivot
The set-theoretic system did not appear in 1.20. As the Elixir Forum announcement thread for rc.0 and rc.1 recounts, the work began publicly in 2022 and has been delivered incrementally: 1.17 introduced the core type lattice, 1.18 added pattern inference, and the 1.19 series shipped guard-clause typing. The theoretical foundation is laid out in “The Design Principles of the Elixir Type System” by Giuseppe Castagna, Guillaume Duboc, and Valim, which the project cites as the academic basis for the implementation.
The deliberately staged rollout is reflected in the rc cadence. According to the January post, the planned schedule was inference of all constructs in January 2026 (with expected false positives), inference across clauses in February-March, and inference across dependencies in April-May ahead of the final release. Rc.2 and rc.3 hit the cross-clause milestone, and rc.4 covers the cross-dependency work.
Valim has framed 1.20 as the closing chapter of the first phase rather than the destination. The January announcement outlines a roughly 15-month roadmap for the next stage: typed structs in 1.21 (targeted for November 2026), set-theoretic function signatures replacing the inherited Erlang Typespecs in 1.22 (targeted for May 2027), and eventually a user-facing type-annotation API.
What Users Are Reporting
The Elixir Forum thread shows the practical caveats that come with a type system being rolled out across an entire ecosystem at once. The team explicitly warned that early release candidates would surface false-positive warnings and asked users to report compilation-time regressions, suggesting mix compile --force --profile time as a benchmark against 1.19. Early measurements posted in the thread reported compilation times in 1.20 rc that were marginally faster or roughly equivalent to 1.19.5.
The rc cycle has also exposed integration issues with the wider tooling stack. One reported case noted in the forum thread came from the Credo static-analysis project, which had to adjust how it reads block expressions because Elixir’s AST metadata now carries line and column information rather than empty lists. Compilation hangs on certain overlapping map-and-struct patterns were reported during rc.2 and rc.3, per the Elixir Merge notes; the team has been issuing follow-up patches against these reports.
What We Don’t Know
The final 1.20 release is targeted for May 2026, but a precise date has not been set publicly; the team has historically cut the final after a stabilization window once outstanding rc-level reports clear. It is also too early to assess how much existing Elixir code in the wild will surface new warnings under whole-function inference, or how aggressively library authors will adopt the eventual user-facing annotation API once it lands in 1.22.
The broader question — whether a gradual, opt-in type system can become idiomatic in a language whose ecosystem has spent 15 years writing untyped code — will not be answered by 1.20 alone. What 1.20 does establish is that the inference engine, the set-theoretic foundation, and the compiler integration now exist in shipping form, with two further releases on the roadmap to build the user-facing surface on top.