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 a Result. 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.
The Rust release train as of October 2026, as a grid of three channels over three six-week periods. Until 1 October 2026: nightly 1.100, beta 1.99, stable 1.98. From 1 October to 12 November 2026: nightly 1.101, beta 1.100, stable 1.99. From 12 November to 24 December 2026: nightly 1.102, beta 1.101, stable 1.100. Arrows follow version 1.100 from nightly to beta to stable. until 1 Oct 1 Oct – 12 Nov 12 Nov – 24 Dec nightly beta stable 1.100 1.101 1.102 1.99 1.100 1.101 1.98 1.99 1.100 each column is one six-week cycle; 1.99 is the current stable release
Every version spends about six weeks on nightly, six on beta, and then becomes stable. Rust 1.100 is beta now and becomes stable on 12 November 2026.

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 unsafe blocks.
  • 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.