Written 2025-07-18
Among the 2010's cohort of programming languages, Rust is probably the most widely lauded.
The main selling point of Rust is that it manages to combine speed and low-level control with a high level of bug-resistance, more commonly referred to as safety. The main innovation of Rust - really, its claim to fame - is its borrowchecker: the part of its compiler that enforces Rust's ownership rules and thereby allows Rust to achieve all the memory safety that garbage collected language enjoy, but with zero runtime cost.
The evangelists proponents of Rust have made memory safety the central selling point of Rust, to the extent that the borrowchecker has become the defining feature of Rust's identity. I think the conflation of Rust's safety with the borrowchecker's guarantees is somewhat misguided. In this post, I want to make two arguments:
That the borrowchecker causes serious ergonomic problems for Rust. That the role of the borrowchecker in Rust's safety is overstated.
In a nutshell, the problem with Rust's borrowchecker is that it makes references a pain in the ass.
On an abstract level, the reason for the pain is that the borrowchecker needs to know the lifetimes of all references at compile time, and this is simply an unrealistic proposal. Lifetimes are often an inherently runtime property.
On an algorithmic level, the borrowchecker enforces a specific model, or set of rules around ownership, but this model is overly restrictive, and degrade Rust's ergonomics by rejecting far too many well-behaving programs.
At the implementation level, the borrowchecker's current instantiation is incomplete, and often rejects programs that adhere to the model of ownership, even as that model is too restrictive in the first place.
Borrowchecker frustration is like being brokenhearted - you can't easily demonstrate it, you have to suffer it yourself to understand what people are talking about. Real borrowchecker pain is not felt when your small, 20-line demonstration snippet fails to compile. It's when your existing project requires a small modification to ownership structure, and the borrowchecker then refuses to compile your code. Then, once you pull at the tiny loose fiber in your code's fabric, you find you have to unspool half your code before the borrowchecker is satisfied.
... continue reading