Blog – Rust is a disappointment

I used to call myself a Rust hater, but really I was just doing it to compensate for the laudable fanboyism that for example Rust tops Stackoverflow surveys as the most liked language. There are many reasons to hate C++, and I hate C++ too. Many people were waiting for a better programming language, but they got Rust instead.

There are several main problems with Rust:

  1. Its compilation is slow. I mean slow. Slower than C++. I know Rust has become many times faster over the years, but objectively we need it to be not just two times, but two orders of magnitude faster.
  2. It’s complicated. Just as complex as C++. But C++ had inheritance and Rust did not. The complexity of making your way through the forest Arc>> The quality of the logic being applied at each step has a direct impact i.e. you can’t see the forest for the trees. Again, C++ has the same problem, so what’s the point of changing the language anyway?
  3. Memory safety is not that sacred. In fact, for many applications a malfunction is better than a crash – especially in the embedded world where Rust wants to exist. You can’t get 99.999% reliability with Rust – it crashes all the time.
  4. When handling a lot of mutable shared state (GUI, DB, stateful services, OS/hardware), the native Rust memory model has low performance, and non-native unsafe gives you slower compilation, higher complexity, and finally no memory safety – which makes Rust practically meaningless for heavy mutable state jobs.

There is no doubt about it. Undefined behavior (UB) is a fundamental aspect of the language, you don’t just encounter UB – the entire language is built on UB. You do array indexing and you immediately encounter UB because the language does not check bound access. I want to emphasize that a lot of UB-S isn’t even justified in terms of performance – it’s a completely sloppy design of C that has been ported over and extended into C++. I can talk all day about how C++ sucks:

  • Built-in type conversions, built-in copies, built-in constructors, built-in object slicing, and almost all built-in things;
  • Function overloading (implicit), especially considering its ubiquity in the STL;
  • Non-uniform error handling with exceptions as an afterthought;
  • 40 years after C and the one definition rule, text files are still being #included despite being barely checked by compilers;
  • wrong combination of patterns (good luck overriding a normal function in descendant classes);
  • SFINAE nuisance as the main mechanism of general programming;
  • t, t&, t*, std::optionalstd::unique_ptr To describe similar things, each is broken down in its own way. Place consommé cherries on top.

Therefore C++ is complex, insecure and its compiler is slow. How does Rust (not) fix those issues?

This isn’t a temporary problem – it’s by design. Here one of the designers explains why the Rust development team sacrificed compilation speed every time:
https://pingcap.medium.com/the-rust-compilation-model-calamity-1a8ce781cf6c

The Rust FAQ states that many efforts have been made to optimize it, such as a better frontend, MIR, etc. But the MIR effort was started in 2015 and it still fails to speed up compilation (although it does speed up compiler checking).

Unfortunately, it is impossible to compile Rust faster. The problem is inherent in all similar generic-heavy languages ​​like Haskell. Arguably, Rust is closer to Haskell than C++. You could even say it’s closer to template-heavy C++ – and template-heavy C++ code exhibits the same problem of slow compilation.
when will you do for i in 0..limit {} – You don’t just iterate, you create a class, you create an iterator, you iterate over it – it’s all monomorphized to your concrete types and has to be optimized individually (non-optimized Rust code is extremely slow, it’s mostly unusable even for debugging).
Put a non-optional borrow-checker on top of it – and there you have an extremely slow compiler. And you’ll be recompiling a lot, because the borrow checker is relentless.

You can’t avoid it. You can’t go like “I’m writing a cold path high-level code, I don’t need performance, I don’t need to go deep into lifetime handling, I just want to write a high-level logic”. Every time you write a single line of Rust you’ll be forced into low-level granularity. There is no garbage collector for Rust and there never will be – you have to semi-manually pack all your data into the ownership tree. You have to be well versed in ownership, borrowing, properties to write a few lines of code.

As I already mentioned, this makes it very difficult to write high-level logic in Rust. This is why many early Rust adopters actually return to Node.js and Go for less performance-sensitive services – the high complexity combined with slow compilation makes it impractical to write anything complex in sole Rust.

There are two constants in the Rust fundamentals: performance and memory safety. I would argue that the Rust designers have gone too far with memory safety. You know what containers are actually implemented with unsafe Functions, because no absolute correctness is possible in the Turing machine model – you have to build secure programs from carefully arranged insecure building blocks. Node.js and Go are considered practically secure languages. Jung sacrificed sanity and practicality for memory safety – and at the end of the day you get nothing out of them, it’s still not 100% memory safe.

Now talking about practicality – many use cases don’t require perfect memory protection. There are ways to implement insecure programs that still don’t execute remote code or leak secrets – they simply corrupt user data and function sporadically. If the pacemaker stops – telling the victim “but the memory was not corrupted in the accident” is a weak consolation. We actually had a Cloudflare outage recently due to a crash unwrap() Celebration:
https://blog.cloudflare.com/18-november-2025-outage/

This is probably my strongest point of crying: Rust memory is secure and unreliable. The price of memory safety was reliability. Apart from developer wisdom – that’s why I’m telling language designers they overdid it. He sacrificed the original practical quality for an abstract theory of memory protection. Just like Haskell designers sacrificed practicality for correctness – that’s why I reiterate the similarity between Rust and Haskell.

It’s possible, but it doesn’t make sense to employ mutable shared state in Rust. You lose most of the benefits and all the drawbacks of Rust. Almost all successful Rust projects are employing shared read-only state, one-way data flows, acyclic data structures: the RustC compiler, mdbook and pulldown-cmark markdown tools, actix and exem for stateless handlers, append-only blockchains, single-threaded WASM. The model, once again, is similar to Haskell, which also excels in parsers, stateless handlers, mostly non-interactive CLI tools, and was employed in blockchains.

Early prototypes of Rust actually had software transactional memory (STM) as an alternative to safe concurrency, however, STM has performance penalties and requires simple but important runtime support.

Step into shared variable state – and memory corruption there is no exception, it’s a rule. You have to handle corruption, you can’t just crash. Borrow checker, ownership? Absolutely useless, you can’t analyze ownership in acyclic graphs without a GC-like algorithm.

Sync/Send, Mutex and Reference Counting (Arc)? Unfortunately, they badly lock or mess up the CPU cache, so they are inefficient for multithreaded communication, at least for intensive communication. They are safe, but ineffective. Which destroys the first non-compromise in Rust – performance. So, to repeat, as soon as you move into shared variable state, you lose every single benefit of Rust. This is a bit logical considering that the core concept of Rust was never to employ a shared mutable state.

In particular, the GUI is a mutable shared state. That’s why we don’t see any big GUI projects in Rust. The Z IDE is still beta after so many years – I can almost feel the pain of developers hacking their way through the borrowed checker jungle, only to realize that their logic is bug-ridden, and they still have dozens of other features to implement.
Large databases, scalable stateful services, operating systems, least critical Linux modules? It still remains to be seen.

So, is war bad or good? It’s neither of those. It’s a mediocre programming language that took thousands of man-months to develop – this very fact makes Rust a viable tool, simply because you can pick it up off the shelf and use it as is. This blog was created with Zola written in Rust – I didn’t have to write a single line of Rust code to use it. And Rust is suitable for Zola SSG due to its non-interactive nature with one-way flow of immutable data. Just please, don’t run around screaming “We should all switch our development to Rust because it’s the best programming language”.



<a href

Leave a Comment