unsolicited Dave: Rust Is Not Memory Safe
Thursday, July 2, 2026
Rust Is Not Memory Safe
Rust Is Not a Memory-Safe Language
David Jeske (Artificial Necessity LLC), with Claude (Anthropic)
Status: Draft Last Updated: 2026-07-02
Abstract
Rust is not a memory-safe language. Memory safety, as the term has always meant in language design — the property that programs in the language cannot violate memory integrity — is a compositional property of a language and its runtime: it holds for all programs, over all data shapes, unconditionally. Rust does not have this property. What Rust has is a static checker that verifies an ownership discipline over tree-shaped data only, plus a set of unsafe escape hatches whose use is not optional but structurally mandatory: any cyclic, self-referential, or densely shared data structure — doubly-linked lists, graphs, DOMs, scene graphs, caches, entity systems — is inexpressible under the checker and forces the program into hand-written unsafe, runtime reference counting, or unchecked index schemes. Because these structures dominate real systems software, the unverified surface of a Rust program grows with the program's structural complexity, and at engine scale the observed end state — in Servo, Bevy, and Zed alike — is that every large Rust project builds its own bespoke, unverified object-lifetime runtime. A language whose safety property is conditional on universally quantified, undischarged proof obligations across its entire ecosystem, whose checker cannot express the core data structures of the domain it targets, and whose flagship projects manage memory through hand-audited runtimes, is not a memory-safe language under any definition of the term that does not also admit reference-counted C++. Garbage-collected platforms are memory safe. Rust is a memory-disciplined language with a memory-safe subset for trees — and the difference is not pedantry; it is the difference between a property of the language and a property of small programs.
1. Thesis
Rust is not a memory-safe language. This paper defends that statement literally, under the ordinary meaning "memory-safe language" has carried since the term was coined: a language in which programs cannot commit memory-safety violations — no use-after-free, no dangling dereference, no out-of-bounds access — as a property of the language, holding for all programs a developer can write in it.
The prevailing description of Rust — in its own project materials, in vendor adoption cases, and in US federal cybersecurity guidance, which classify Rust alongside garbage-collected languages under the label "memory-safe" [8][9] — is wrong, and wrong in a way that matters. It equates two safety architectures that differ not in degree but in kind, and it awards the categorical label to a language whose guarantee is conditional, non-compositional, incomplete over data shapes, and — decisively — weakest in exactly the software domains the label is invoked to justify.
Three facts, developed in the sections that follow, establish the thesis:
The checked subset is incomplete. Rust's borrow checker verifies programs whose data ownership forms a tree. Cyclic and self-referential structures are inexpressible under it. (§3)
The guarantee is non-compositional. Code fully accepted by the checker can trigger undefined behavior by calling unsound unsafe code anywhere in its dependency closure — and the ecosystem measurably fails these proof obligations, including in the standard library. (§2, [1])
At scale, Rust converges to C++'s shape. Every flagship large Rust system has been forced to construct its own unverified object-lifetime runtime — arriving at the same safety architecture the equivalent C++ systems use. The claimed categorical difference from C++ disappears precisely in the domains it was claimed for. (§4)
A language of which all three are true does not satisfy the definition. The remainder of the paper is the demonstration.
2. What "Memory Safe" Means, and Why Rust Does Not Meet It
2.1 The definition
A memory-safe language is one in which memory-safety violations are inexpressible by construction for all programs. Garbage-collected languages meet this definition through their runtime: the collector guarantees no reachable object is reclaimed, bounds checks cover access, and consequently:
Completeness: every data shape — cyclic, shared, self-referential — is safe. class Node { Node? Parent; List Children; } is safe, done.
Compositionality: safe code calling safe code is safe, unconditionally. No library can export an API that safe callers can use to corrupt memory.
Fixed trusted base: the trusted surface is one runtime artifact, institutionally hardened for decades, whose failure modes are uncorrelated with application logic — a JIT bug is triggered by codegen patterns, not by an application "holding an API wrong."
This is the property the term "memory safe" was minted for. C#, Java, Go, and JavaScript have it. (C#...