Skip to content

Instantly share code, notes, and snippets.

@cynthia2006
Last active March 12, 2026 07:40
Show Gist options
  • Select an option

  • Save cynthia2006/584f518161cfcba9a745afd94c903304 to your computer and use it in GitHub Desktop.

Select an option

Save cynthia2006/584f518161cfcba9a745afd94c903304 to your computer and use it in GitHub Desktop.

Criticism of Rust

Venturing into the holy lands of Rust, we often hear the chants of fearless concurrency, memory safety and zero-cost abstractions, but truth could seldom be so lofty. These chantings are as hollow as the priests themselves.

Myth of Zero-Cost Abstractions

There's nothing such as zero-cost abstractions. Any abstraction, no matter how transparent, brings both a performance and cognitive penalty. It applies not only to Rust, but also to carcinogens like C++.

Cognitive penalty is especially applicable to bindings that dramatically change the original paradigm of the underlying library without (properly) documenting it; in that case, source code must be read to ascertain correct behaviour. This needless effort makes abstractions not zero-cost, but sometimes more cost than if you had just used the library without the binding.

Hostility towards unsafe

I've seen Rustaceans act with hostility towards unsafe code. And, I understand that often there's no need for unsafety, but in certain cases it has been shown in the past that performance is achieved through unsafety.

And not just that, sometimes unsafety is a necessity, such as when dealing with FFI (Foreign Function Interface), which is foundation of bindings. Bindings exist because not all code has been rewritten in Rust, much to dismay of the Rust community. Many take safety for granted without considering the circumstances where the unsafe code used to implement the safe interface may non-deterministically malfunction, which is the case with a lot binding libraries out there. Debugging this requires to scrutinize the source code as mentioned before.

Infallibility of Ownership

People hailing to a background in low-level languages (e.g. C or FORTRAN) find Rust rather hard to understand at first, because in those languages the norm is to manually manage memory or resources (sockets, files, etc). However, Rust is based off of RAII and ownership; i.e. a resource may have a single owner, and it can be mutably borrowed once, but immutably borrowed an infinite number of times.

Ownership model unfortunately isn't silver bullet for all problems regarding memory safety. There exist valid cases, when a reference is semantically immutable, but it requires mutability for bookkeeping; e.g. Rc<T> or Arc<T> — smart pointers for a heap-allocated reference-counted object; former one for single-threaded and latter for multi-threaded scenarios, using Cell<T> for counting references. Additionally, Arc<T> is allowed to be shared between threads1, because immutable (read-only) references could be sent between threads.

Debunking Fearless Concurrency

What rustaceans call concurrency is actually parallelism. And, parallelism is no child's play. It might be easy to spawn a pool of threads to do a perform a task, but whether if it's actually beneficial, or worse yet, detrimental to performance. The topic of parallelism is complicated and hard to get right, and it demands experimentation, profiling and optimisations. The algorithm that is designed to do the task in a sequential scenario, may often be suboptimal in a parallel scenario, and must be modified accordingly, given that it's even possible.

Getting trained in a rayon bootcamp isn't going to get you past making toy programs. Life is more harder than that.

Async & Pin<P>

Similar to many languages (e.g. Python), Rust has adopted a model of explicit cooperative multitasking. Rust's futures are a hybrid version of Python's coroutines and futures, but ultimately represent a deferred computation whose result will be available “in the future.” Python's coroutines are generators in disguise; as generators enable bidirectional communication with the event-loop. A coroutine suspends execution at an await-point, and is then resumed when the awaitable resolves. Generators store state (local variables with their values) of the execution in a generator frame.

While this is no problem for Python — because all data is reference-counted — it becomes a problem for Rust, as storing the state of the future, referring to it an a status field (e.g. an enum) is not possible unless either the values are reference counted, or raw pointers are used to make a self-reference. Yes, raw pointers are necessary because the ownership model is (again) not flexible enough to accommodate for self-referential types (i.e. our future).

Here's the irony, the harbingers of fearless concurrency don't consider raw pointers a safety hazard here; raw pointers, however, are the root cause of all memory safety bugs. In this case, if a self-referential structure is moved, its raw pointers becoming dangling. Where's your safety now?

To solve this problem, sages who jotted down the holy scriptures of rustonomicon came up with a brilliantly stupid idea: introducing a new type Pin<P>, instead of just implementing move constructors like sane people2. Pin<P> is often misunderstood, because it's very non-intuitive; essentially it's just a wrapper over a smart-pointer (Rc<T> and Box<T>) or a reference (&T or &mut T), enforcing that a mutable reference to a pinned can't obtained safely. However, who's stopping a Tom, Dick or Harry vibe coder use a type like Pin<Box<RefCell<T>>> and invalidate this guarantee safely? Pin<P> only prevents you to obtain a mutable reference to RefCell<T>, however a mutable reference to T could be obtained safely; i.e. legally do a crime.

Sure, you don't directly implement Future<T> all the time, but who's there to guarantee that some profoundly stupid programmer this sort of atrocity behind your back, and the compiler silently let it slide?

Sloth Compile Times

The demigods of Rust, equipped with their omniscience, had dictated that dynamic linking is inferior to static linking, hence all Rust projects must be compiled along with all its dependencies must be compiled along with it.

Not having a stable ABI, it's often impossible to link a Rust library (.rlib) compiled with one version of rustc with another, because of ABI differences. Demigods might have all powerful machines, constantly whirring and buzzing, constantly compiling Rust code, but we the mortals don't have such luxuries, so we waste millions/billions of clock cycles compiling the same code, that could just have been compiled once.

Politics

The Rust community doesn't teach people to consider tradeoffs, and forces a singular authoritative opinion. The whole community thrives on meaningless politics3—always, right from the start. And, god forbid you make a remotely politically incorrect opinion, the entire community would cannibalise you!

Their appeasement policies towards non-binary people is apparent. I personally don't hate any LGBTQ, but I hate it when a certain group is pandered for vote bank politics. It's the reflection of late-stage capitalism prevalent in Western countries, its associated neo-liberal contemporary woke pandemic, and rise of social justice warriors patrolling the social media sphere, voluntarily taking the “responsibility” to ensure it's a “safe place for all” and all those first-world problems that hardly matter.


Checkout this blog by Arija A. (https://blog.ari.lt/b/rust-bad-ii/). She has done a great job of pin-pointing exactly where the deficits of Rust lie. Fuck Rust. Peace.

Footnotes

  1. Rc<T> explicitly implements !Send, because its counter is not atomic; as atomic types incur costs.

  2. All moves in Rust are bitwise copies; i.e. a plain and simple memcpy.

  3. https://x.com/rustlang/status/1267519582505512960

@matthewyang204
Copy link

This is a very fair point. As can be seen in things like DOOM, yes, performance is achieved through extreme unsafety. I do also think the ABI is a problem. Something made for Rust 1.7x.x may not work in 1.8x.x and vice versa. I also do hate the politics around Rust. There truly is a problem when the entire community thrives on criticising and bringing down others with opinions only slightly different (aka the complete opposite of freedom of opinion & speech).

@cynthia2006
Copy link
Author

@matthewyang204 I know, right? The Rust community is full of SJWs who've nothing better to do than virtue-signal everyone. They've taken a clear trans-appeasement policy.

@matthewyang204
Copy link

@cynthia2006 Exactly. I use Rust myself quite a bit, but it's definitely not the non-enforced "Idiomatic Rust" and I definitely do not agree with how the community treat their own members, let alone other people like me who write code in C, C++, plenty of other unsafe languages, and also interpreted languages like Python.

@cynthia2006
Copy link
Author

@matthewyang204 The Actix drama exposes how toxic the community really is. My experience with Rust has been mixed so far; found out that — atleast in my case — writing equivalent C code lead to more comprehensible and less verbose code.

@cynthia2006
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment