On-Ramp to Rust

Rust prevents bug classes but is not a silver bullet

It is tempting, after meeting ownership and the borrow checker, to come away believing Rust means no more bugs. It does not, and selling it that way does the language a disservice. What Rust actually delivers is sharp and limited: in its safe subset, it eliminates a specific, costly family of bugs at compile time — use-after-free, double-free, dangling references, buffer overruns, and data races. Those are not minor; they are the source of a large share of security vulnerabilities in C and C++ codebases. Removing them by construction is a genuine and important win. But it is one category of bug, not all bugs.

Be precise about what remains. Rust does not stop logic errors — code that compiles cleanly and runs safely can still compute the wrong answer, because correctness of your logic is not something the type system checks. It does not prevent deadlocks: two threads can each wait forever for a lock the other holds, and that program is perfectly memory-safe while being completely stuck. It does not prevent all memory leaks — you can keep a value alive forever or call forget on purpose, and reference cycles in Rc can leak. It does not stop panics, integer overflow in release builds wrapping silently, or resource exhaustion. And the safety guarantee covers safe code only: inside an unsafe block, or when calling out to C through the foreign-function interface, you can cause exactly the undefined behaviour Rust otherwise forbids — and a single unsafe bug can corrupt memory anywhere in the program.

Why this honest framing matters: it tells you where to keep your guard up. Rust frees you from constantly worrying about a class of memory bugs, which lets you spend that attention on the bugs it cannot catch — your logic, your concurrency design, your error handling, the correctness of any unsafe you write. Treat Rust as a powerful tool that makes whole categories of mistakes impossible in safe code, not as a guarantee of correct software. The right mindset is the careful engineer's: grateful for the bugs the compiler catches, clear-eyed about the ones it never will, and still writing tests, reviewing unsafe blocks, and thinking hard about what your program is actually supposed to do.

// Compiles, memory-safe, and still wrong/stuck: fn area(w: u32, h: u32) -> u32 { w + h } // logic bug: should be w * h // Two locks taken in opposite orders by two threads -> deadlock. // Both threads are 100% memory-safe and 100% stuck forever.

Memory-safe does not mean correct: logic errors and deadlocks compile and run just fine.

Rust eliminates a specific bug class in safe code, not all bugs. Logic errors, deadlocks, intentional leaks, and undefined behaviour inside unsafe or across FFI all remain — never read Rust as a promise of correct software.

Also called
the honest limits of Rustwhat Rust does not fixRust 的誠實界限Rust 不保證什麼