This spring, the better part of a million lines of Zig quietly became a million lines of Rust. Bun, the JavaScript runtime that was the showcase for “you don’t need a borrow checker, you need good tools and a steady hand”, looked at its own memory bugs and switched teams. Around 99.8% of its test suite passed on the rewritten code, a clutch of memory leaks closed in the move, and the maintainers said the quiet part out loud: the previous release would be the last one written in Zig.
It’s tempting to read that as Rust winning, hoist the flag, and move on. I don’t think that’s quite the story, and the more interesting one is happening everywhere else at the same time.
Because Bun is the exception that went all the way. Everyone else is trying to get the safety without the Rust, and watching how they’re going about it tells you more than one runtime’s heroic rewrite does.
What everyone’s actually after
A quick level-set, because not everyone reading this writes systems code daily. “Memory safety” is the property that a program can’t read or write memory it has no business touching: no using a value after you’ve freed it, no running off the end of an array. It sounds niche. It is, by most counts, behind something like 70% of serious security vulnerabilities, which is why governments and trillion-dollar companies suddenly care a great deal.
There are roughly three ways to get it. Rust uses a borrow checker: a compiler
that flatly refuses to build your program unless it can prove, before it ever runs,
that you never touch memory after you’re done with it. The price is that it argues
with you the entire time you’re writing. The product is that an entire category of
bug becomes literally unwriteable. Go (and most managed languages) uses a garbage
collector: a runtime janitor that frees memory for you, so you mostly can’t get it
wrong, at the cost of some overhead and a little control. And then there’s the old
way, the one most code on Earth still uses: trust the developer to get it right,
and add an escape hatch, usually a keyword like unsafe, for the bits where they
promise they have.
The retrofit trend is everyone in that third camp trying to inch toward the first two without rewriting the world.
Rust didn’t invent any of this
Worth saying plainly, because the fan club rarely does: Rust invented almost none
of it. The borrow checker is, by Rust’s own admission,
Cyclone’s region-based memory management, from a safe-C experiment in the early
2000s, welded to affine types out of linear logic,
ideas that predate Rust by decades. And it goes beyond the borrow checker.
Rust’s exhaustive pattern matching came from ML and Haskell. Its “errors are
values, and there is no null” approach, Result and Option, is Haskell’s Maybe
and Either in work boots.
What Rust did, and did better than anyone before it, was taste and integration: it
curated thirty-odd years of academic research into one coherent language and proved
the ideas could carry real systems code rather than just research papers. That is
the genuine USP, and it’s why the rest of the industry is now shopping from the
same shelf. Pattern matching has landed in Python and Java, with a proposal in
flight for C++26. Swift 6 shipped
compile-time data-race safety,
its Sendable machinery a close cousin of Rust’s Send and Sync. The borrow
checker just gets the headlines because it’s the hardest bit to copy. Which makes
the title almost too literal: everyone wants Rust’s safety, and they are quietly
adopting its mechanisms one feature at a time.
Credit where it’s due: C# is doing this properly
The example that made me sit up is C#. In C# 16, Microsoft is
redefining the unsafe keyword
that’s been in the language since version one. Instead of unsafe marking a lump
of syntax, it now marks a contract: a promise the compiler can’t verify and a
human has to read and uphold, with documentation and static analysers nudging you
to take it seriously. They’re even floating badges on NuGet packages to show which
ones have opted in.
My first instinct with any retrofit is suspicion, because bolting safety onto a language after the fact has a long and miserable history, and an escape hatch that’s easy to reach is an escape hatch people will reach for the moment they’re in a hurry. But this isn’t a bolt-on. Taking the keyword that’s already there and giving it real teeth is working with the grain of the language instead of stapling a second safety system alongside the first. That’s honest engineering, and it deserves the credit. It genuinely raises the floor.
A contract is not a guarantee
Here’s where my enthusiasm meets its limit, and it’s a distinction I happen to have a lot of skin in.
C#’s redefined unsafe makes dangerous code visible and reviewable. That is a
real improvement, and most teams would be better off for it. But visible and
reviewable still means a human has to honour the promise. It’s a sign on the door.
Rust’s equivalent is a wall: in rust-tool-base
I put #![forbid(unsafe_code)] at the top of all eleven shipping crates, and
forbid is not advice, it’s a refusal. The compiler will not build a crate that
contains unsafe, full stop, and unlike its softer sibling deny, you can’t quietly
switch it back off in a corner of the code where it’s inconvenient. The whole reason
I use forbid and not deny is that I don’t trust future-me, in a hurry, not to
reach for the hatch.
So when I look at the C# work I think: good, genuinely good, and they should take it further. A contract a human upholds is not the same kind of thing as a proof a compiler enforces, and the trend, if it’s serious, points at enforcement. Visible is better than invisible. Impossible is better than visible.
Discipline never scaled, and that’s not an insult
The objection I keep hearing, and that a younger me would have made, is that any language can be memory-safe if you’re just disciplined enough. And it’s true, in the way that any house can be tidy if you never get busy. In the before times we shipped memory-safe C with code review and valgrind and sheer bloody-mindedness, and it worked, sort of, at small scale.
It doesn’t scale, and Bun is the proof sitting on the table. That wasn’t a sloppy team learning the basics. It was a strong team, betting publicly on the discipline-and-good-tools model, and the memory bugs piled up anyway until the honest move was to let a compiler take the job. Discipline failing at scale isn’t a moral failure of the engineers. It’s just what happens when you ask humans to hold a thousand invariants in their heads across a million lines. Delegating that to a machine that never gets tired or rushed isn’t laziness. It’s the entire point of having compilers at all.
The part that changed my mind
I learned most of my Rust by building rust-tool-base with an AI alongside me, leaning on it to explain the borrow checker, suggest the idiomatic shape, and check my work. And somewhere in that I noticed the thing I now can’t unsee: the borrow checker is exactly as good a guardrail for the AI as it is for me.
A model, like a tired human, will write a confident use-after-free without blinking. In Rust it simply doesn’t compile, so the mistake never reaches me. What that does is move the whole error surface. The bugs that survive into review aren’t memory bugs or lifetime bugs or data races, the language has eaten those, they’re errors of logic: the code is safe and wrong. And logic is precisely where I want my attention, and the AI’s, because it’s the part a human has to own and the part the models are getting better at every month. (I split my AI work across a few providers for their different strengths, so this is not a pitch for anyone’s logo. The effect is the same whoever’s doing the typing.)
Which dissolves the one argument that ever really kept people out of Rust. “The borrow checker is too much friction” was always the case for the defence. But Bun’s million-line rewrite was done largely with an AI, because an AI is very good at paying a tax that is tedious and mechanical rather than creative. The friction is getting cheaper to pay at exactly the moment the guarantee is getting more valuable to have. In an AI-assisted world, a language that proves safety is worth more, not less, because it fences in the machine’s mistakes as firmly as your own.
None of this means rewrite everything in Rust
I want to be careful not to land somewhere smug, because most software does not need what Rust offers and pretending otherwise is how you end up rewriting a CRUD app nobody asked you to. Garbage collection is not a failure state. Go’s collector keeps getting meaningfully better, my own go-tool-base is GC’d top to bottom and I have never once wished it weren’t, and “safe-by-default with a GC” is the right answer for a vast amount of the work most of us do. The borrow checker is a price, and you should only pay it when the thing you’re buying, that last class of guarantee with no runtime cost, is something your stakes actually need.
What it comes down to
The question was never “is it as safe as Rust”. That framing turns everything into a loss for everyone who isn’t Rust, which is silly. The useful question is: what does your language make the default, and how hard does it make the escape hatch to reach? Go makes safety the default and charges you a GC. Rust makes it the default and charges you the borrow checker. C# is moving its default in the right direction and, for now, leaves the hatch as a promise rather than a wall.
Credit the retrofits, they are raising the floor for an enormous amount of code that was never going to be rewritten. Just don’t mistake the floor for the ceiling, or a contract a human signs for a guarantee a compiler keeps. Everyone wants Rust’s safety, and the interesting question, now that an AI will pay the toll for you, is who still has a reason not to want it.
Widen the lens past Rust, though, because that’s where the news gets genuinely good. We’re at a turn in how languages evolve. Compile-time rigour is spreading rather than retreating: borrow checking is reaching the Python family through Mojo, static typing long since conquered JavaScript, and even the managed languages are turning their escape hatches into something you have to argue with. More of our safety is quietly moving from “remember to” into “can’t not”. And the one thing that always made the strict path hard to start down, the friction, is being absorbed by an AI that will happily learn the rules so you can lean on them. I’ve been at this long enough to distrust a rosy forecast, but I’ll put my name to this one: the outlook for software that’s safe and secure by default has never looked better.
