What Is Rust?
What Rust is and why it matters: memory safety without a garbage collector, its path from Mozilla research project to Rust 1.0 and the Rust Foundation, editions and the six-week release train, and where Rust runs today.
What Rust is
Rust is a general-purpose programming language for the same work C does: operating system components, drivers, network services, command-line tools and firmware. Its own description is "a language empowering everyone to build reliable and efficient software". A few properties shape how it feels:
-
Compiled. The compiler,
rustc, turns source code into machine code in advance. The result is a native executable that needs no interpreter or virtual machine, just like a C program (see Installing Rust and Using Cargo). - Statically and strictly typed. Every value has a type the compiler knows, and it converts almost nothing implicitly (see static typing and Variables, Types and Mutability).
- Memory-safe without a garbage collector. Rules about who owns a value and who may borrow it are checked while the program is compiled. Memory is freed at a predictable moment, and the bugs C is known for (use after free, double free, reading past the end of a buffer) are refused or caught.
-
No null and no exceptions. A value that may be
missing has the type
Option; an operation that may fail returns aResult. Both are ordinary types that the compiler makes you deal with (see Error Handling).
Here is a complete Rust program. It works out the average of some daily meter readings, stored as whole watt-hours, the same task as the first program on What Is C?:
// Daily electricity use of one Kestrel Energy household, in watt-hours
fn main() {
let readings = [11_200, 9_800, 12_500, 10_100, 13_400];
let days = readings.len();
let mut total = 0;
for reading in readings {
total += reading;
}
println!("Days measured: {days}");
println!("Average per day: {:.1} kWh", total as f64 / 1000.0 / days as f64);
}
Days measured: 5 Average per day: 11.4 kWh
Every program starts in the function main.
let introduces a variable; the compiler works out the
types itself. let mut marks the one variable that
changes: in Rust, variables cannot change unless you say so. An
array knows its length (readings.len()), and
for walks through it without an index.
println! prints a line; the exclamation mark shows it
is a macro, which the compiler expands before compiling.
{days} inserts a variable, {:.1} a number
with one decimal. The as f64 conversions are spelled
out because Rust never turns whole numbers into floating-point
numbers by itself.
The difference with C shows as soon as something goes wrong. Reading element 4 of a four-element array in C is undefined behavior; usually it quietly returns whatever lies in memory next to it. Rust checks every index while the program runs and stops with a clear message instead:
fn main() {
let readings = [120, 95, 130, 110];
let day = 4; // imagine this came from user input
println!("Reading for day {day}:");
println!("{}", readings[day]); // there is no readings[4]
}
Reading for day 4: thread 'main' (48213) panicked at example.rs:5:20: index out of bounds: the len is 4 but the index is 4
This is a panic: the program stops in a controlled way,
names the file, line and column, and exits with status 101. A panic
is still a bug, but a contained one: no memory outside the array was
read. (The number after 'main' is a thread ID that
differs on every run.) Code that expects a missing element uses
readings.get(day), which returns an
Option instead of panicking; see
Error Handling.
A short history
Rust started as a personal project of Graydon Hoare, then a programmer at Mozilla, around 2006. Mozilla began to sponsor it a few years later and presented it publicly in 2010 as a research project. The language changed a great deal in the five years before it was declared stable.
Rust 1.0 was released on 15 May 2015. The announcement called it "a new programming language aiming to make it easier to build reliable, efficient systems", "without requiring a garbage collector or runtime". It was also a promise: "This release is the official beginning of our commitment to stability", with breaking changes "largely out of scope". Code that compiled on Rust 1.0 is expected to compile on today's compiler, and that promise still shapes how the language changes (see editions below).
On 8 February 2021 the
Rust Foundation was
announced: an independent non-profit organization "to steward the
Rust programming language and ecosystem". Its founding members were
Amazon Web Services (AWS), Huawei, Google, Microsoft and Mozilla,
and Mozilla transferred the trademarks and infrastructure to it,
including the crates.io package registry. The
Foundation pays for infrastructure, security work and some
developers; it does not design the language. That is the job of the
Rust Project: open teams (language, compiler,
library, Cargo and others) that decide through public proposals
called RFCs (requests for comments).
Memory safety without a garbage collector
Programs need memory for data whose size is only known while they run. Languages have long chosen between two answers (see Memory Management):
- Manual management, as in C: the programmer requests and releases memory. Fast and predictable, but one mistake gives a use after free, a double free or a leak.
- A garbage collector, as in Python, Java and C#: a runtime finds and frees memory that is no longer reachable. Safe, but with a runtime that runs at moments the program does not choose.
Rust takes a third way, summarized in ownership in Rust: every value has one owner and is freed when the owner goes out of scope; other code may borrow it, and the compiler proves before the program runs that no borrow outlives the value and that nothing changes a value while others are reading it. The pages on ownership, borrowing and lifetimes explain the rules. A first taste: in C, keeping a pointer into an array and then growing the array (which may move it in memory) leaves a dangling pointer. The Rust version does not compile:
fn main() {
let mut readings = vec![120, 95, 130];
let first = &readings[0]; // borrow the first element
readings.push(110); // may move the whole list in memory
println!("first reading: {first}");
}
example.rs:4:5: error[E0502]: cannot borrow `readings` as mutable because it is also borrowed as immutable: mutable borrow occurs here
That is the short form of the message. In a terminal the compiler draws the whole story, pointing at the borrow, the change and the later use:
error[E0502]: cannot borrow `readings` as mutable because it is also borrowed as immutable
--> example.rs:4:5
|
3 | let first = &readings[0]; // borrow the first element
| -------- immutable borrow occurs here
4 | readings.push(110); // may move the whole list in memory
| ^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
5 | println!("first reading: {first}");
| ----- immutable borrow later used here
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0502`.
The same idea removes null. A function that may have no
answer returns an Option, and the compiler will not let
you use it as if the answer were always there:
// The reading of a home, if the meter sent one today
fn latest_reading(home: &str) -> Option<u32> {
if home == "h0017" { Some(412) } else { None }
}
fn main() {
let total = 100 + latest_reading("h0042");
println!("{total} kWh");
}
example.rs:7:21: error[E0277]: cannot add `Option<u32>` to `{integer}`: no implementation for `{integer} + Option<u32>`
You have to say what happens when there is no reading, for example
with match, which must cover both cases:
// The reading of a home, if the meter sent one today
fn latest_reading(home: &str) -> Option<u32> {
if home == "h0017" { Some(412) } else { None }
}
fn main() {
for home in ["h0017", "h0042"] {
match latest_reading(home) {
Some(kwh) => println!("{home}: {kwh} kWh"),
None => println!("{home}: no reading today"),
}
}
}
h0017: 412 kWh h0042: no reading today
These checks cost nothing while the program runs: they happen in the compiler. Only a few checks remain in the running program: array indexes are checked in every build and integer overflow in debug builds (see integer overflow).
Editions
A language that promises not to break old code still needs to fix mistakes and add keywords. Rust's answer is the edition: a named set of language rules that a crate (a library or program) chooses for itself. Changes that would break existing code are only made in a new edition, and every compiler supports all editions released up to its own version. In the words of the edition guide, crates in one edition "must seamlessly interoperate with those compiled with other editions", so a 2024 program can use a library written in 2015 Rust.
| Edition | Since | What it changed (selection) |
|---|---|---|
| 2015 | Rust 1.0, 15 May 2015 | The original language |
| 2018 | Rust 1.31, 6 December 2018 |
async, await and
dyn become keywords; simpler module paths
|
| 2021 | Rust 1.56, 21 October 2021 |
Trait objects without dyn become errors;
several warnings become errors
|
| 2024 | Rust 1.85, 20 February 2025 |
Stricter rules around unsafe, a reserved
gen keyword, let chains (since 1.88) and more;
the largest edition so far
|
The keyword async shows how this works. In edition 2015
it was an ordinary word, so this program compiles and runs:
fn main() {
let async = 1;
println!("async = {}", async);
}
async = 1
The same file compiled as edition 2024 is refused:
fn main() {
let async = 1;
println!("async = {}", async);
}
example.rs:2:9: error: expected identifier, found keyword `async`: expected identifier, found keyword
Moving a project to a new edition is a deliberate step:
cargo fix --edition rewrites most affected code
automatically, and then the edition in Cargo.toml is
raised. As of October 2026 the next edition is being discussed for
around 2027; nothing about it is decided yet.
The release train
Rust does not have big releases. It follows a release train: every six weeks a new version leaves for the stable channel, carrying whatever was ready, like a train that leaves on schedule whether or not every passenger made it. Rust 1.0 announced this "train-based release model", with releases "every six weeks, just like the Firefox and Chrome web browsers". A feature that misses one train takes the next.
Three channels exist at the same time:
-
Nightly: the
nightly channel is built
every night from the main development branch. Unfinished features
can be tried there, switched on one by one with
#![feature(…)]lines, which the other channels refuse. Some tools, such as Miri, run only on nightly. - Beta: the next stable release, frozen for six weeks of testing; only fixes go in.
- Stable: the stable channel carries the released versions covered by the stability promise. Production code and these pages use stable.
As of October 2026 the stable version is 1.99.0,
released on 1 October 2026; 1.100.0 is due on 12 November 2026. The
numbering simply continues: 1.100 is a normal six-week release, not
a "Rust 2.0", and there is no plan for one. Because every stable
release keeps old code working, the usual advice is to stay on the
latest stable release and update regularly (rustup update, see
Installing Rust and Using Cargo). Patch releases such as 1.94.1 appear between trains only for
serious problems, including security fixes in Cargo.
Where Rust is used
Most people meet Rust through software they install and run. As of October 2026:
- The Linux kernel. Linux 6.1 (December 2022) was the first release that could contain Rust code. Rust is used mainly for drivers, next to the C core (see kernels on the C pages); according to LWN's report on the December 2025 Maintainers Summit, it is no longer considered an experiment. The kernel documentation lists Rust 1.85.0 as the minimum version for building it.
-
Android. In November 2025 Google reported that
memory-safety bugs had fallen below 20% of Android's
vulnerabilities for the first time, and measured "a 1000x
reduction in memory safety vulnerability density" in its Rust code
compared with its C and C++ code. About 4% of that Rust code sits
inside
unsafeblocks. - Windows. A Windows 11 Insider build of July 2023 shipped a part of the kernel's graphics code reimplemented in Rust, as a first trial.
- Cloud infrastructure. AWS's Firecracker, the lightweight virtual machine manager behind AWS Lambda and AWS Fargate, is written in Rust.
-
Command-line tools. Search tools such as ripgrep
(
rg) and many other utilities that admins install from their package manager are written in Rust; they arrive as a single executable. - Version control. Git itself is moving toward requiring Rust to build (see Git today).
- Embedded and safety-critical systems. Rust also runs on microcontrollers, without an operating system. Ferrocene, a Rust toolchain from Ferrous Systems, is qualified for use under safety standards such as ISO 26262 (cars) and IEC 61508 (industrial systems).
Why the interest: security agencies such as the US National Security Agency (NSA) and the Cybersecurity and Infrastructure Security Agency (CISA) have recommended memory-safe languages for new software since 2022, and memory-safety bugs have long been the largest group of serious vulnerabilities in C and C++ code. Microsoft's often-quoted figure from 2019, that about 70% of the security vulnerabilities it fixed were memory-safety bugs, describes its C and C++ code; Android's 1000x is a measured result for Rust. The two numbers come from different sources and measure different things.
Popularity rankings show the same growth. The TIOBE Index of September 2026, which counts search-engine results, put Rust in 10th place (1.34%), up from 18th a year earlier; C was second. The 2025 State of Rust Survey (7,156 responses, published in March 2026) again named slow compile times and disk usage among the biggest problems.
Kestrel Energy does not run Rust in production. The P1 dongles of
the Kestrel Home pilot are ESP32-C3 devices from an outside
manufacturer, and their firmware is C (see
the CRC check in C); that stays the manufacturer's code. Some pages of this topic
follow one example: after BUG-1060, where a meter sent its checksum
as three digits (B9F) and the dongle's parser accepted
exactly four (see
tolerant parsing), a developer on the platform team writes a small Rust prototype
of that parser to compare with the manufacturer's C fix. It is a
learning exercise, not a plan to replace the firmware.
What Rust asks of you
Rust's guarantees have a price, mostly paid while learning:
- A strict compiler. Code that C would compile and Python would run is often refused. The refusals are the point: most of them are bugs that would otherwise show up later, in production. Rust's error messages are known for being helpful; most say what is wrong, where, and how to fix it.
- New concepts. Ownership, borrowing and lifetimes have no direct equivalent in most languages. Many learners need some weeks before the borrow checker feels like a colleague rather than an obstacle.
- Compile times. Building a large Rust project takes minutes, and survey respondents name slow compiles as a top problem. On the 64-bit Linux machine (ARM64) that runs the examples here, a small example compiles in about 0.2 seconds.
- Dependencies. The standard library is small on purpose; JSON, HTTP or command-line parsing come from third-party crates. That makes choosing and checking dependencies part of the job (see The Crate Ecosystem and Supply-Chain Safety).
Every compiler error has a code, such as E0502 above.
rustc --explain E0502 prints a longer explanation with
examples, offline, and the same texts are in the online error index.
Learning Rust and certification
This topic follows the usual path: installing Rust and Cargo, then variables and types, control flow and pattern matching, functions and modules, then ownership, borrowing and lifetimes, which are the heart of the language. After that come structs and enums, error handling, collections and strings, traits and generics, iterators and closures, smart pointers and concurrency, and finally testing and tooling, the crate ecosystem and its supply-chain risks, and unsafe Rust with calls into C. The standard free book, The Rust Programming Language ("the Book"), follows a similar order.
Every example on these pages is a complete program, compiled with Rust 1.99 as edition 2024, with warnings treated as errors, and run on a 64-bit Linux machine (ARM64). Where the compiler refuses a program, the page shows the first error line; full compiler messages are labeled as recorded.
As of October 2026 there is no widely recognized exam for individual Rust developers. The Rust Foundation's Trusted Training program (since June 2026) accredits training providers, not individuals, and the Linux Foundation's free LFEL1002 course ends with a badge. The pages of this topic therefore carry no certification tag.