Recent from talks
Contribute something
Nothing was collected or created yet.
Rust (programming language)
View on Wikipedia
| Rust | |
|---|---|
| Paradigms | |
| Developer | The Rust Team |
| First appeared | January 19, 2012 |
| Stable release | 1.91.0[1] |
| Typing discipline | |
| Implementation language | OCaml (2006–2011) Rust (2012–present) |
| Platform | Cross-platform[note 1] |
| OS | Cross-platform[note 2] |
| License | MIT, Apache 2.0[note 3] |
| Filename extensions | .rs, .rlib |
| Website | rust-lang.org |
| Influenced by | |
| Influenced | |
Rust is a general-purpose programming language. It is noted for its emphasis on performance, type safety, concurrency, and memory safety.
Rust supports multiple programming paradigms. It was influenced by ideas from functional programming, including immutability, higher-order functions, algebraic data types, and pattern matching. It also supports object-oriented programming via structs, enums, traits, and methods. Rust is noted for enforcing memory safety (i.e., that all references point to valid memory) without a conventional garbage collector; instead, memory safety errors and data races are prevented by the "borrow checker", which tracks the object lifetime of references at compile time.
Software developer Graydon Hoare created Rust in 2006 while working at Mozilla, which officially sponsored the project in 2009. The first stable release, Rust 1.0, was published in May 2015. Following a layoff of Mozilla employees in August 2020, four other companies joined Mozilla in sponsoring Rust through the creation of the Rust Foundation in February 2021.
Rust has been adopted by many software projects, especially web services and system software, and is the first language other than C and assembly to be supported in the development of the Linux kernel. It has been studied academically and has a growing community of developers.
History
[edit]2006–2009: Early years
[edit]Rust began as a personal project by Mozilla employee Graydon Hoare in 2006, who started the project due to his frustration with a broken elevator in his apartment building.[15] Hoare named Rust after the group of fungi that is "over-engineered for survival".[15] During the time period between 2006 and 2009, Rust was not publicized to others at Mozilla and was written in Hoare's free time;[16]: 7:50 Hoare began speaking about the language around 2009 after a small group at Mozilla became interested in the project.[17] Hoare cited languages from the 1970s, 1980s, and 1990s as influences — including CLU, BETA, Mesa, NIL,[note 4] Erlang, Newsqueak, Napier, Hermes, Sather, Alef, and Limbo.[17] He described the language as "technology from the past come to save the future from itself."[16]: 8:17 [17] Early Rust developer Manish Goregaokar similarly described Rust as being based on "mostly decades-old research."[15]
During the early years, the Rust compiler was written in about 38,000 lines of OCaml.[16]: 15:34 [18] Features of early Rust that were later removed include explicit object-oriented programming via an obj keyword,[16]: 10:08 and a typestates system that would allow variables of a type to be tracked along with state changes (such as going from uninitialized to initialized).[16]: 13:12
2009–2012: Mozilla sponsorship
[edit]Mozilla officially sponsored the Rust project in 2009.[15] Brendan Eich and other executives, intrigued by the possibility of using Rust for a safe web browser engine, placed engineers on the project including Patrick Walton, Niko Matsakis, Felix Klock, and Manish Goregaokar.[15] A conference room taken by the project developers was dubbed "the nerd cave," with a sign placed outside the door.[15]
During this time period, work had shifted from the initial OCaml compiler to a self-hosting compiler, i.e., written in Rust, based on LLVM.[19][note 5] The Rust ownership system was also in place by 2010.[15]
The first public release, Rust 0.1, was released on January 20, 2012[21] for Windows, Linux, and MacOS.[22] The early 2010s saw increasing involvement from open source volunteers outside of Mozilla and outside of the United States. At Mozilla, executives would eventually employ over a dozen engineers to work on Rust full time over the next decade.[15] The Rust logo was developed in 2011 based on a bicycle chainring.[23]
2012–2015: Evolution
[edit]The years from 2012 to 2015 were marked by substantial changes to the Rust type system, including the removal of the typestate system and garbage collector.[16]: 18:36 [15] Memory management through the ownership system was gradually consolidated and expanded to prevent memory-related bugs. By 2013, the garbage collector feature was rarely used, and was removed by the team in favor of the ownership system.[15] Other changes during this time included the removal of pure functions, which were declared by an explicit pure annotation, in March 2013.[24] Specialized syntax support for channels and various pointer types were removed to simplify the language.[16]: 22:32
According to Rust developer Steve Klabnik, Rust was influenced during this period by developers coming from C++ (e.g., low-level performance of features), scripting languages (e.g., Cargo and package management), and functional programming (e.g., type systems development).[16]: 30:50
Graydon Hoare stepped down from Rust in 2013.[15] After Hoare's departure, it evolved organically under a federated governance structure, with a "core team" of initially six people,[16]: 21:45 around 30-40 developers total across various other teams,[16]: 22:22 and a Request for Comments (RFC) process for new language features added in March 2014.[16]: 33:47 The core team would grow to nine people by 2016[16]: 21:45 with over 1600 proposed RFCs.[16]: 34:08
According to Andrew Binstock writing for Dr. Dobb's Journal in January 2014, while Rust was "widely viewed as a remarkably elegant language", adoption slowed because it radically changed from version to version.[25] Rust development at this time was focused on finalizing the language features and moving towards 1.0 so it could begin promising backward compatibility.[16]: 41:26
Six years after Mozilla sponsored its development, the first stable release, Rust 1.0, was published on May 15, 2015.[15] A year after the release, the Rust compiler had accumulated over 1,400 contributors and there were over 5,000 third-party libraries published on the Rust package management website Crates.io.[16]: 43:15
2015–2020: Servo and early adoption
[edit]
The development of the Servo browser engine continued in parallel with Rust, jointly funded by Mozilla and Samsung.[26] The teams behind the two projects worked in close collaboration; new features in Rust were tested out by the Servo team, and new features in Servo were used to give feedback back to the Rust team.[16]: 5:41 The first version of Servo was released in 2016.[15] The Firefox web browser shipped with Rust code as of 2016 (version 45),[16]: 53:30 [27] but components of Servo did not appear in Firefox until September 2017 (version 57) as part of the Gecko and Quantum projects.[28]
Improvements were made to the Rust toolchain ecosystem during the years following 1.0 including Rustfmt, integrated development environment integration,[16]: 44:56 and a regular compiler testing and release cycle.[16]: 46:48 Rust also gained a community code of conduct and an IRC chat for community discussion.[16]: 50:36
The earliest known adoption outside of Mozilla was by individual projects at Samsung, Facebook (now Meta Platforms), Dropbox, and Tilde, Inc. (the company behind ember.js).[16]: 55:44 [15] Amazon Web Services followed in 2020.[15] Engineers acknowledged the risks of adopting a new technology; they cited performance, lack of a garbage collector, safety, and pleasantness of working in the language as reasons for the adoption. Amazon developers cited a finding by Portuguese researchers that Rust code used less energy compared to similar code written in Java.[15][29]
2020–present: Mozilla layoffs and Rust Foundation
[edit]In August 2020, Mozilla laid off 250 of its 1,000 employees worldwide, as part of a corporate restructuring caused by the COVID-19 pandemic.[30][31] The team behind Servo was disbanded. The event raised concerns about the future of Rust.[32] In the following week, the Rust Core Team acknowledged the severe impact of the layoffs and announced that plans for a Rust foundation were underway. The first goal of the foundation would be to take ownership of all trademarks and domain names and to take financial responsibility for their costs.[33]
On February 8, 2021, the formation of the Rust Foundation was announced by five founding companies: Amazon Web Services, Google, Huawei, Microsoft, and Mozilla.[34][35] The foundation would provide financial support for Rust developers in the form of grants and server funding.[15] In a blog post published on April 6, 2021, Google announced support for Rust within the Android Open Source Project as an alternative to C/C++.[36]
On November 22, 2021, the Moderation Team, which was responsible for enforcing the community code of conduct, announced their resignation "in protest of the Core Team placing themselves unaccountable to anyone but themselves".[37] In May 2022, the Rust Core Team, other lead programmers, and members of the Rust Foundation board implemented governance reforms in response to the incident.[38]
The Rust Foundation posted a draft for a new trademark policy on April 6, 2023, which resulted in widespread negative reactions from Rust users and contributors.[39] The trademark policy included rules for how the Rust logo and name could be used.[39]
On February 26, 2024, the U.S. White House Office of the National Cyber Director released a 19-page press report urging software development to move away from C and C++ to memory-safe languages like C#, Go, Java, Ruby, Swift, and Rust.[40][41][42]
Syntax and features
[edit]Rust's syntax is similar to that of C and C++,[43][44] although many of its features were influenced by functional programming languages such as OCaml.[45] Hoare has described Rust as targeted at frustrated C++ developers and emphasized features such as safety, control of memory layout, and concurrency.[17] Safety in Rust includes the guarantees of memory safety, type safety, and lack of data races.
Hello World program
[edit]Below is a "Hello, World!" program in Rust. The fn keyword denotes a function, and the println! macro (see § Macros) prints the message to standard output.[46] Statements in Rust are separated by semicolons.
fn main() {
println!("Hello, World!");
}
Variables
[edit]Variables in Rust are defined through the let keyword.[47] The example below assigns a value to the variable with name foo of type i32 and outputs its value; the type annotation : i32 can also be omitted.
fn main() {
let foo: i32 = 10;
println!("The value of foo is {foo}");
}
Variables are immutable by default, but adding the mut keyword allows the variable to be mutated.[48] The following example uses //, which denotes the start of a comment.[49]
fn main() {
// This code would not compile without adding "mut".
let mut foo = 10;
println!("The value of foo is {foo}");
foo = 20;
println!("The value of foo is {foo}");
}
Multiple let expressions can define multiple variables with the same name, known as variable shadowing. Variable shadowing allows transforming variables without having to name the variables differently.[50] The example below declares a new variable with the same name that is double the original value:
fn main() {
let foo = 10;
// This will output "The value of foo is 10"
println!("The value of foo is {foo}");
let foo = foo * 2;
// This will output "The value of foo is 20"
println!("The value of foo is {foo}");
}
Variable shadowing is also possible for values of different types. For example, going from a string to its length:
fn main() {
let letters = "abc";
let letters = letters.len();
}
Block expressions and control flow
[edit]A block expression is delimited by curly brackets. When the last expression inside a block does not end with a semicolon, the block evaluates to the value of that trailing expression:[51]
fn main() {
let x = {
println!("this is inside the block");
1 + 2
};
println!("1 + 2 = {x}");
}
Trailing expressions of function bodies are used as the return value:[52]
fn add_two(x: i32) -> i32 {
x + 2
}
if expressions
[edit]An if conditional expression executes code based on whether the given value is true. else can be used for when the value evaluates to false, and else if can be used for combining multiple expressions.[53]
fn main() {
let x = 10;
if x > 5 {
println!("value is greater than five");
}
if x % 7 == 0 {
println!("value is divisible by 7");
} else if x % 5 == 0 {
println!("value is divisible by 5");
} else {
println!("value is not divisible by 7 or 5");
}
}
if and else blocks can evaluate to a value, which can then be assigned to a variable:[53]
fn main() {
let x = 10;
let new_x = if x % 2 == 0 { x / 2 } else { 3 * x + 1 };
println!("{new_x}");
}
while loops
[edit]while can be used to repeat a block of code while a condition is met.[54]
fn main() {
// Iterate over all integers from 4 to 10
let mut value = 4;
while value <= 10 {
println!("value = {value}");
value += 1;
}
}
for loops and iterators
[edit]For loops in Rust loop over elements of a collection.[55]
for expressions work over any iterator type.
fn main() {
// Using `for` with range syntax for the same functionality as above
// The syntax 4..=10 means the range from 4 to 10, up to and including 10.
for value in 4..=10 {
println!("value = {value}");
}
}
In the above code, 4..=10 is a value of type Range which implements the Iterator trait. The code within the curly braces is applied to each element returned by the iterator.
Iterators can be combined with functions over iterators like map, filter, and sum. For example, the following adds up all numbers between 1 and 100 that are multiples of 3:
(1..=100).filter(|x: &u32| -> bool { x % 3 == 0 }).sum()
loop and break statements
[edit]More generally, the loop keyword allows repeating a portion of code until a break occurs. break may optionally exit the loop with a value. In the case of nested loops, labels denoted by 'label_name can be used to break an outer loop rather than the innermost loop.[56]
fn main() {
let value = 456;
let mut x = 1;
let y = loop {
x *= 10;
if x > value {
break x / 10;
}
};
println!("largest power of ten that is smaller than or equal to value: {y}");
let mut up = 1;
'outer: loop {
let mut down = 120;
loop {
if up > 100 {
break 'outer;
}
if down < 4 {
break;
}
down /= 2;
up += 1;
println!("up: {up}, down: {down}");
}
up *= 2;
}
}
Pattern matching
[edit]The match and if let expressions can be used for pattern matching. For example, match can be used to double an optional integer value if present, and return zero otherwise:[57]
fn double(x: Option<u64>) -> u64 {
match x {
Some(y) => y * 2,
None => 0,
}
}
Equivalently, this can be written with if let and else:
fn double(x: Option<u64>) -> u64 {
if let Some(y) = x {
y * 2
} else {
0
}
}
Types
[edit]Rust is strongly typed and statically typed, meaning that the types of all variables must be known at compilation time. Assigning a value of a particular type to a differently typed variable causes a compilation error. Type inference is used to determine the type of variables if unspecified.[58]
The type (), called the "unit type" in Rust, is a concrete type that has exactly one value. It occupies no memory (as it represents the absence of value). All functions that do not have an indicated return type implicitly return (). It is similar to void in other C-style languages, however void denotes the absence of a type and cannot have any value.
The default integer type is i32, and the default floating point type is f64. If the type of a literal number is not explicitly provided, it is either inferred from the context or the default type is used.[59]
Primitive types
[edit]Integer types in Rust are named based on the signedness and the number of bits the type takes. For example, i32 is a signed integer that takes 32 bits of storage, whereas u8 is unsigned and only takes 8 bits of storage. isize and usize take storage depending on the memory address bus width of the compilation target. For example, when building for 32-bit targets, both types will take up 32 bits of space.[60][61]
By default, integer literals are in base-10, but different radices are supported with prefixes, for example, 0b11 for binary numbers, 0o567 for octals, and 0xDB for hexadecimals. By default, integer literals default to i32 as its type. Suffixes such as 4u32 can be used to explicitly set the type of a literal.[62] Byte literals such as b'X' are available to represent the ASCII value (as a u8) of a specific character.[63]
The Boolean type is referred to as bool which can take a value of either true or false. A char takes up 32 bits of space and represents a Unicode scalar value:[64] a Unicode codepoint that is not a surrogate.[65] IEEE 754 floating point numbers are supported with f32 for single precision floats and f64 for double precision floats.[66]
Compound types
[edit]Compound types can contain multiple values. Tuples are fixed-size lists that can contain values whose types can be different. Arrays are fixed-size lists whose values are of the same type. Expressions of the tuple and array types can be written through listing the values, and can be accessed with .index or [index]:[67]
let tuple: (u32, bool) = (3, true);
let array: [i8; 5] = [1, 2, 3, 4, 5];
let value = tuple.1; // true
let value = array[2]; // 3
Arrays can also be constructed through copying a single value a number of times:[68]
let array2: [char; 10] = [' '; 10];
Ownership and references
[edit]Rust's ownership system consists of rules that ensure memory safety without using a garbage collector. At compile time, each value must be attached to a variable called the owner of that value, and every value must have exactly one owner.[69] Values are moved between different owners through assignment or passing a value as a function parameter. Values can also be borrowed, meaning they are temporarily passed to a different function before being returned to the owner.[70] With these rules, Rust can prevent the creation and use of dangling pointers:[70][71]
fn print_string(s: String) {
println!("{}", s);
}
fn main() {
let s = String::from("Hello, World");
print_string(s); // s consumed by print_string
// s has been moved, so cannot be used any more
// another print_string(s); would result in a compile error
}
The function print_string takes ownership over the String value passed in; Alternatively, & can be used to indicate a reference type (in &String) and to create a reference (in &s):[72]
fn print_string(s: &String) {
println!("{}", s);
}
fn main() {
let s = String::from("Hello, World");
print_string(&s); // s borrowed by print_string
print_string(&s); // s has not been consumed; we can call the function many times
}
Because of these ownership rules, Rust types are known as linear or affine types, meaning each value can be used exactly once. This enforces a form of software fault isolation as the owner of a value is solely responsible for its correctness and deallocation.[73]
When a value goes out of scope, it is dropped by running its destructor. The destructor may be programmatically defined through implementing the Drop trait. This helps manage resources such as file handles, network sockets, and locks, since when objects are dropped, the resources associated with them are closed or released automatically.[74]
Lifetimes
[edit]Object lifetime refers to the period of time during which a reference is valid; that is, the time between the object creation and destruction.[75] These lifetimes are implicitly associated with all Rust reference types. While often inferred, they can also be indicated explicitly with named lifetime parameters (often denoted 'a, 'b, and so on).[76]
Lifetimes in Rust can be thought of as lexically scoped, meaning that the duration of an object lifetime is inferred from the set of locations in the source code (i.e., function, line, and column numbers) for which a variable is valid.[77] For example, a reference to a local variable has a lifetime corresponding to the block it is defined in:[77]
fn main() {
let x = 5; // ------------------+- Lifetime 'a
// |
let r = &x; // -+-- Lifetime 'b |
// | |
println!("r: {}", r); // | |
// | |
// -+ |
} // ------------------+
The borrow checker in the Rust compiler then enforces that references are only used in the locations of the source code where the associated lifetime is valid.[78][79] In the example above, storing a reference to variable x in r is valid, as variable x has a longer lifetime ('a) than variable r ('b). However, when x has a shorter lifetime, the borrow checker would reject the program:
fn main() {
let r; // ------------------+- Lifetime 'a
// |
{ // |
let x = 5; // -+-- Lifetime 'b |
r = &x; // ERROR: x does | |
} // not live long -| |
// enough |
println!("r: {}", r); // |
} // ------------------+
Since the lifetime of the referenced variable ('b) is shorter than the lifetime of the variable holding the reference ('a), the borrow checker errors, preventing x from being used from outside its scope.[80]
Lifetimes can be indicated using explicit lifetime parameters on function arguments. For example, the following code specifies that the reference returned by the function has the same lifetime as original (and not necessarily the same lifetime as prefix):[81]
fn remove_prefix<'a>(mut original: &'a str, prefix: &str) -> &'a str {
if original.starts_with(prefix) {
original = original[prefix.len()..];
}
original
}
In the compiler, ownership and lifetimes work together to prevent memory safety issues such as dangling pointers.[82][83]
User-defined types
[edit]User-defined types are created with the struct or enum keywords. The struct keyword is used to denote a record type that groups multiple related values.[84] enums can take on different variants at runtime, with its capabilities similar to algebraic data types found in functional programming languages.[85] Both records and enum variants can contain fields with different types.[86] Alternative names, or aliases, for the same type can be defined with the type keyword.[87]
The impl keyword can define methods for a user-defined type. Data and functions are defined separately. Implementations fulfill a role similar to that of classes within other languages.[88]
Standard library
[edit]
The Rust standard library defines and implements many widely used custom data types, including core data structures such as Vec, Option, and HashMap, as well as smart pointer types. Rust also provides a way to exclude most of the standard library using the attribute #![no_std], for applications such as embedded devices. Internally, the standard library is divided into three parts, core, alloc, and std, where std and alloc are excluded by #![no_std].[89]
Rust uses the option type Option<T> to define optional values, which can be matched using if let or match to access the inner value:[90]
fn main() {
let name1: Option<&str> = None;
// In this case, nothing will be printed out
if let Some(name) = name1 {
println!("{name}");
}
let name2: Option<&str> = Some("Matthew");
// In this case, the word "Matthew" will be printed out
if let Some(name) = name2 {
println!("{name}");
}
}
Similarly, Rust's result type Result<T, E> holds either a successfully computed value (the Ok variant) or an error (the Err variant)[91]. Like Option, the use of Result means that the inner value cannot be used directly; programmers must use a match expression, syntactic sugar such as ? (the “try” operator), or an explicit unwrap assertion to access it. Both Option and Result are used throughout the standard library and are a fundamental part of Rust's explicit approach to handling errors and missing data.
Pointers
[edit]The & and &mut reference types are guaranteed to not be null and point to valid memory.[92] The raw pointer types *const and *mut opt out of the safety guarantees, thus they may be null or invalid; however, it is impossible to dereference them unless the code is explicitly declared unsafe through the use of an unsafe block.[93] Unlike dereferencing, the creation of raw pointers is allowed inside safe Rust code.[94]
Type conversion
[edit]Rust provides no implicit type conversion (coercion) between most primitive types. But, explicit type conversion (casting) can be performed using the as keyword.[95]
let x: i32 = 1000;
println!("1000 as a u16 is: {}", x as u16);
Polymorphism
[edit]Rust supports bounded parametric polymorphism through traits and generic functions.[96] Common behavior between types may be declared using traits and impls:[97]
trait Zero: Sized {
fn zero() -> Self;
fn is_zero(&self) -> bool
where
Self: PartialEq,
{
self == &Zero::zero()
}
}
impl Zero for u32 {
fn zero() -> u32 { 0 }
}
impl Zero for f32 {
fn zero() -> Self { 0.0 }
}
The example above also includes a method is_zero which provides a default implementation that is not required when implementing the trait.[97]
A function can then be made generic by adding type parameters inside angle brackets (<Num>), which only allow types that implement the trait:
// zero is a generic function with one type parameter, Num
fn zero<Num: Zero>() -> Num {
Num::zero()
}
fn main() {
let a: u32 = zero();
let b: f32 = zero();
assert!(a.is_zero() && b.is_zero());
}
In the examples above, Num: Zero as well as where Self: PartialEq are trait bounds that constrain the type to only allow types that implement Zero or PartialEq.[97] Within a trait or impl, Self refers to the type that the code is implementing.[98]
Generics can be used in functions to allow implementing a behavior for different types without repeating the same code. Generic functions can be written in relation to other generics, without knowing the actual type.[99]
Trait objects
[edit]Rust supports two ways to call trait methods. With generics and trait bounds, calls use static dispatch: the compiler monomorphizes the function for each concrete type, yielding performance comparable to hand-written, type-specific code, at the cost of longer compile times and potentially larger binaries.[100] When the exact type is not known at compile time, or when heterogeneous collections are needed, Rust provides trait objects (e.g., &dyn Trait, Box<dyn Trait>). Trait-object calls use dynamic dispatch via a vtable; a trait object is a "fat pointer" carrying both a data pointer and a method table pointer.[100] This indirection can inhibit inlining and add a small runtime cost, but it keeps a single copy of the code and can reduce binary size. Only object-safe traits are eligible to be used as trait objects.[101]
However, Rust also uses a feature known as trait objects to accomplish dynamic dispatch, a type of polymorphism where the implementation of a polymorphic operation is chosen at runtime. This allows for behavior similar to duck typing, where all data types that implement a given trait can be treated as functionally equivalent.[102] Trait objects are declared using the syntax dyn Tr where Tr is a trait. Trait objects are dynamically sized, therefore they must be put behind a pointer, such as Box.[103] The following example creates a list of objects where each object can be printed out using the Display trait:
use std::fmt::Display;
let v: Vec<Box<dyn Display>> = vec![
Box::new(3),
Box::new(5.0),
Box::new("hi"),
];
for x in v {
println!("{x}");
}
If an element in the list does not implement the Display trait, it will cause a compile-time error.[104]
Memory safety
[edit]Rust is designed to be memory safe. It does not permit null pointers, dangling pointers, or data races.[105][106][107][108] Data values can be initialized only through a fixed set of forms, all of which require their inputs to be already initialized.[109]
Memory management
[edit]Rust does not use garbage collection. Memory and other resources are instead managed through the "resource acquisition is initialization" convention,[110] with optional reference counting. Rust provides deterministic management of resources, with very low overhead.[111] Values are allocated on the stack by default, and all dynamic allocations must be explicit.[112]
The built-in reference types using the & symbol do not involve run-time reference counting. The safety and validity of the underlying pointers is verified at compile time, preventing dangling pointers and other forms of undefined behavior.[113] Rust's type system separates shared, immutable references of the form &T from unique, mutable references of the form &mut T. A mutable reference can be coerced to an immutable reference, but not vice versa.[114]
Unsafe
[edit]Rust's memory safety checks may be circumvented through the use of unsafe blocks. This allows programmers to dereference arbitrary raw pointers, call external code, or perform other low-level functionality not allowed by safe Rust.[115] Some low-level functionality enabled in this way includes volatile memory access, architecture-specific intrinsics, type punning, and inline assembly.[116]
Unsafe code is sometimes needed to implement complex data structures.[117] A frequently cited example is that it is difficult or impossible to implement doubly linked lists in safe Rust.[118][119][120][121]
Programmers using unsafe Rust are considered responsible for upholding Rust's memory and type safety requirements, for example, that no two mutable references exist pointing to the same location.[122] If programmers write code which violates these requirements, this results in undefined behavior.[122] The Rust documentation includes a list of behavior considered undefined, including accessing dangling or misaligned pointers, or breaking the aliasing rules for references.[123]
Macros
[edit]Macros allow generation and transformation of Rust code to reduce repetition. Macros come in two forms, with declarative macros defined through macro_rules!, and procedural macros, which are defined in separate crates.[124][125]
Declarative macros
[edit]A declarative macro (also called a "macro by example") is a macro, defined using the macro_rules! keyword, that uses pattern matching to determine its expansion.[126][127] Below is an example that sums over all its arguments:
macro_rules! sum {
( $initial:expr $(, $expr:expr )* $(,)? ) => {
$initial $(+ $expr)*
}
}
fn main() {
let x = sum!(1, 2, 3);
println!("{x}"); // prints 6
}
Procedural macros
[edit]Procedural macros are Rust functions that run and modify the compiler's input token stream, before any other components are compiled. They are generally more flexible than declarative macros, but are more difficult to maintain due to their complexity.[128][129]
Procedural macros come in three flavors:
- Function-like macros
custom!(...) - Derive macros
#[derive(CustomDerive)] - Attribute macros
#[custom_attribute]
Interface with C and C++
[edit]Rust supports the creation of foreign function interfaces (FFI) through the extern keyword. A function that uses the C calling convention can be written using extern "C" fn. Symbols can be exported from Rust to other languages through the #[no_mangle] attribute, and symbols can be imported into Rust through extern blocks:[note 6][131]
#[no_mangle]
pub extern "C" fn exported_from_rust(x: i32) -> i32 { x + 1 }
unsafe extern "C" {
fn imported_into_rust(x: i32) -> i32;
}
The #[repr(C)] attribute enables deterministic memory layouts for structs and enums for use across FFI boundaries.[131] External libraries such as bindgen and cxx can generate Rust bindings for C/C++.[131][132]
Ecosystem
[edit]The Rust ecosystem includes its compiler, its standard library, and additional components for software development. Component installation is typically managed by rustup, a Rust toolchain installer developed by the Rust project.[133]
Compiler
[edit]The Rust compiler, rustc, compiles Rust code into binaries. First, the compiler parses the source code into an AST. Next, this AST is lowered to IR. The compiler backend is then invoked as a subcomponent to apply optimizations and translate the resulting IR into object code. Finally, a linker is used to combine the object(s) into a single executable image.[134]
rustc uses LLVM as its compiler backend by default, but it also supports using alternative backends such as GCC and Cranelift.[135] The intention of those alternative backends is to increase platform coverage of Rust or to improve compilation times.[136][137]
Cargo
[edit]
Cargo is Rust's build system and package manager. It downloads, compiles, distributes, and uploads packages—called crates—that are maintained in an official registry. It also acts as a front-end for Clippy and other Rust components.[138]
By default, Cargo sources its dependencies from the user-contributed registry crates.io, but Git repositories, crates in the local filesystem, and other external sources can also be specified as dependencies.[139]
Rustfmt
[edit]Rustfmt is a code formatter for Rust. It formats whitespace and indentation to produce code in accordance with a common style, unless otherwise specified. It can be invoked as a standalone program, or from a Rust project through Cargo.[140]
Clippy
[edit]
Clippy is Rust's built-in linting tool to improve the correctness, performance, and readability of Rust code. As of 2025[update], it has 795 rules.[141][142]
Versioning system
[edit]Following Rust 1.0, new features are developed in nightly versions which are released daily. During each six-week release cycle, changes to nightly versions are released to beta, while changes from the previous beta version are released to a new stable version.[143]
Every two or three years, a new "edition" is produced. Editions are released to allow making limited breaking changes, such as promoting await to a keyword to support async/await features. Crates targeting different editions can interoperate with each other, so a crate can upgrade to a new edition even if its callers or its dependencies still target older editions. Migration to a new edition can be assisted with automated tooling.[144]
IDE support
[edit]rust-analyzer is a set of utilities that provides integrated development environments (IDEs) and text editors with information about a Rust project through the Language Server Protocol. This enables features including autocomplete, and compilation error display, while editing code.[145]
Performance
[edit]Since it performs no garbage collection, Rust is often faster than other memory-safe languages.[146][73][147] Most of Rust's memory safety guarantees impose no runtime overhead,[148] with the exception of array indexing which is checked at runtime by default.[149] The performance impact of array indexing bounds checks varies, but can be significant in some cases.[149]
Many of Rust's features are so-called zero-cost abstractions, meaning they are optimized away at compile time and incur no runtime penalty.[150] The ownership and borrowing system permits zero-copy implementations for some performance-sensitive tasks, such as parsing.[151] Static dispatch is used by default to eliminate method calls, except for methods called on dynamic trait objects.[152] The compiler also uses inline expansion to eliminate function calls and statically-dispatched method invocations.[153]
Since Rust uses LLVM, all performance improvements in LLVM apply to Rust also.[154] Unlike C and C++, Rust allows the compiler to reorder struct and enum elements unless a #[repr(C)] representation attribute is applied.[155] This allows the compiler to optimize for memory footprint, alignment, and padding, which can be used to produce more efficient code in some cases.[156]
Adoption
[edit]
Rust is used in software across different domains. Components from the Servo browser engine (funded by Mozilla and Samsung) were incorporated in the Gecko browser engine underlying Firefox.[157] In January 2023, Google (Alphabet) announced support for using third party Rust libraries in Chromium.[158][159]
Rust is used in several backend software projects of large web services. OpenDNS, a DNS resolution service owned by Cisco, uses Rust internally.[160][161] Amazon Web Services uses Rust in "performance-sensitive components" of its several services. In 2019, AWS open-sourced Firecracker, a virtualization solution primarily written in Rust.[162] Microsoft Azure IoT Edge, a platform used to run Azure services on IoT devices, has components implemented in Rust.[163] Microsoft also uses Rust to run containerized modules with WebAssembly and Kubernetes.[164] Cloudflare, a company providing content delivery network services, used Rust to build a new web proxy named Pingora for increased performance and efficiency.[165] The npm package manager used Rust for its production authentication service in 2019.[166][167][168]

In operating systems, the Rust for Linux project, launched in 2020, merged initial support into the Linux kernel version 6.1 in late 2022.[169][170][171] The project is active with a team of 6–7 developers, and has added more Rust code with kernel releases from 2022 to 2024,[172] aiming to demonstrate the minimum viability of the project and resolve key compatibility blockers.[169][173] The first drivers written in Rust were merged into the kernel for version 6.8.[169] The Android developers used Rust in 2021 to rewrite existing components.[174][175] Microsoft has rewritten parts of Windows in Rust.[176] The r9 project aims to re-implement Plan 9 from Bell Labs in Rust.[177] Rust has been used in the development of new operating systems such as Redox, a "Unix-like" operating system and microkernel,[178] Theseus, an experimental operating system with modular state management,[179][180] and most of Fuchsia.[181] Rust is also used for command-line tools and operating system components, including stratisd, a file system manager[182][183] and COSMIC, a desktop environment by System76.[184]
In web development, Deno, a secure runtime for JavaScript and TypeScript, is built on top of V8 using Rust and Tokio.[185] Other notable adoptions in this space include Ruffle, an open-source SWF emulator,[186] and Polkadot, an open source blockchain and cryptocurrency platform.[187]
Discord, an instant messaging software company, rewrote parts of its system in Rust for increased performance in 2020. In the same year, Dropbox announced that its file synchronization had been rewritten in Rust. Facebook (Meta) used Rust to redesign its system that manages source code for internal projects.[15]
In the 2025 Stack Overflow Developer Survey, 14.8% of respondents had recently done extensive development in Rust.[188] The survey named Rust the "most admired programming language" annually from 2016 to 2025 (inclusive), as measured by the number of existing developers interested in continuing to work in the language.[189][note 7] In 2025, 29.2% of developers not currently working in Rust expressed an interest in doing so.[188]
DARPA has a project TRACTOR (Translating All C to Rust) automatically translating C to Rust using techniques such as static analysis, dynamic analysis, and large language models.[190]
In academic research
[edit]Rust's safety and performance have been investigated in programming language theory research.[191][117][192]
Rust's applicability to writing research software has been examined in other fields. A journal article published to Proceedings of the International Astronomical Union used Rust to simulate multi-planet systems.[193] An article published in Nature shared stories of bioinformaticians using Rust.[138] Both articles found that Rust has advantages for its performance and safety, but cited the learning curve as being a primary drawback to its adoption.
Community
[edit]
According to the MIT Technology Review, the Rust community has been seen as "unusually friendly" to newcomers and particularly attracted people from the queer community, partly due to its code of conduct which outlined a set of expectations for Rust community members to follow.[15] Inclusiveness of the community has been cited as an important factor for some Rust developers.[138] The official Rust blog collects and publishes demographic data each year.[196]
Rust Foundation
[edit]The Rust Foundation is a non-profit membership organization incorporated in United States, with the primary purposes of backing the technical project as a legal entity and helping to manage the trademark and infrastructure assets.[197][44]
Key Information
It was established on February 8, 2021, with five founding corporate members (Amazon Web Services, Huawei, Google, Microsoft, and Mozilla).[198] The foundation's board is chaired by Shane Miller.[199] Starting in late 2021, its Executive Director and CEO is Rebecca Rumbul.[200] Prior to this, Ashley Williams was interim executive director.[44]
Governance teams
[edit]The Rust project is composed of teams that are responsible for different subareas of the development. The compiler team develops, manages, and optimizes compiler internals; and the language team designs new language features and helps implement them. The Rust project website lists 6 top-level teams as of July 2024[update].[201] Representatives among teams form the Leadership council, which oversees the Rust project as a whole.[202]
See also
[edit]Notes
[edit]- ^ Including build tools, host tools, and standard library support for x86-64, ARM, MIPS, RISC-V, WebAssembly, i686, AArch64, PowerPC, and s390x.[2]
- ^ Including Windows, Linux, macOS, FreeBSD, NetBSD, and Illumos. Host build tools on Android, iOS, Haiku, Redox, and Fuchsia are not officially shipped; these operating systems are supported as targets.[2]
- ^ Third-party dependencies, e.g., LLVM or MSVC, are subject to their own licenses.[3][4]
- ^ a b NIL is cited as an influence for Rust in multiple sources; this likely refers to Network Implementation Language developed by Robert Strom and others at IBM, which pioneered typestate analysis,[5][6] not to be confused with New Implementation of LISP.
- ^ The list of Rust compiler versions (referred to as a bootstrapping chain) has history going back to 2012.[20]
- ^ wrapping
no_manglewithunsafeas well as prefacing theextern "C"block withunsafeare required in the 2024 edition or later.[130] - ^ That is, among respondents who have done "extensive development work [with Rust] in over the past year" (14.8%), Rust had the largest percentage who also expressed interest to "work in [Rust] over the next year" (72.4%).[188]
References
[edit]Book sources
[edit]- Gjengset, Jon (2021). Rust for Rustaceans (1st ed.). No Starch Press. ISBN 9781718501850. OCLC 1277511986.
- Klabnik, Steve; Nichols, Carol (2019-08-12). The Rust Programming Language (Covers Rust 2018). No Starch Press. ISBN 978-1-7185-0044-0.
- Blandy, Jim; Orendorff, Jason; Tindall, Leonora F. S. (2021). Programming Rust: Fast, Safe Systems Development (2nd ed.). O'Reilly Media. ISBN 978-1-4920-5254-8. OCLC 1289839504.
- McNamara, Tim (2021). Rust in Action. Manning Publications. ISBN 978-1-6172-9455-6. OCLC 1153044639.
- Klabnik, Steve; Nichols, Carol (2023). The Rust programming language (2nd ed.). No Starch Press. ISBN 978-1-7185-0310-6. OCLC 1363816350.
Others
[edit]- ^ "Announcing Rust 1.91.0". 2025-10-30. Retrieved 2025-10-31.
- ^ a b "Platform Support". The rustc book. Archived from the original on 2022-06-30. Retrieved 2022-06-27.
- ^ "Copyright". GitHub. The Rust Programming Language. 2022-10-19. Archived from the original on 2023-07-22. Retrieved 2022-10-19.
- ^ "Licenses". The Rust Programming Language. Archived from the original on 2025-02-23. Retrieved 2025-03-07.
- ^ Strom, Robert E. (1983). "Mechanisms for compile-time enforcement of security". Proceedings of the 10th ACM SIGACT-SIGPLAN symposium on Principles of programming languages - POPL '83. pp. 276–284. doi:10.1145/567067.567093. ISBN 0897910907. S2CID 6630704.
- ^ Strom, Robert E.; Yemini, Shaula (1986). "Typestate: A programming language concept for enhancing software reliability" (PDF). IEEE Transactions on Software Engineering. 12. IEEE: 157–171. doi:10.1109/tse.1986.6312929. S2CID 15575346.
- ^ "Uniqueness Types". Rust Blog. Archived from the original on 2016-09-15. Retrieved 2016-10-08.
Those of you familiar with the Elm style may recognize that the updated --explain messages draw heavy inspiration from the Elm approach.
- ^ "Influences". The Rust Reference. Archived from the original on 2023-11-26. Retrieved 2023-12-31.
- ^ "Uniqueness Types". Idris 1.3.3 documentation. Archived from the original on 2018-11-21. Retrieved 2022-07-14.
They are inspired by ... ownership types and borrowed pointers in the Rust programming language.
- ^ Tung, Liam. "Microsoft opens up Rust-inspired Project Verona programming language on GitHub". ZDNET. Archived from the original on 2020-01-17. Retrieved 2020-01-17.
- ^ Jaloyan, Georges-Axel (2017-10-19). "Safe Pointers in SPARK 2014". arXiv:1710.07047 [cs.PL].
- ^ Lattner, Chris. "Chris Lattner's Homepage". Nondot. Archived from the original on 2018-12-25. Retrieved 2019-05-14.
- ^ "V documentation (Introduction)". GitHub. The V Programming Language. Retrieved 2023-11-04.
- ^ Yegulalp, Serdar (2016-08-29). "New challenger joins Rust to topple C language". InfoWorld. Archived from the original on 2021-11-25. Retrieved 2022-10-19.
- ^ a b c d e f g h i j k l m n o p q r s Thompson, Clive (2023-02-14). "How Rust went from a side project to the world's most-loved programming language". MIT Technology Review. Archived from the original on 2024-09-19. Retrieved 2023-02-23.
- ^ a b c d e f g h i j k l m n o p q r s t u Klabnik, Steve (2016-06-02). "The History of Rust". Applicative 2016. New York, NY, USA: Association for Computing Machinery. p. 80. doi:10.1145/2959689.2960081. ISBN 978-1-4503-4464-7.
- ^ a b c d Hoare, Graydon (July 2010). Project Servo: Technology from the past come to save the future from itself (PDF). Mozilla Annual Summit. Archived from the original (PDF) on 2021-12-26. Retrieved 2024-10-29.
- ^ Hoare, Graydon (November 2016). "Rust Prehistory (Archive of the original Rust OCaml compiler source code)". GitHub. Retrieved 2024-10-29.
- ^ "0.1 first supported public release Milestone · rust-lang/rust". GitHub. Retrieved 2024-10-29.
- ^ Nelson, Jynn (2022-08-05). RustConf 2022 - Bootstrapping: The once and future compiler. Portland, Oregon: Rust Team. Retrieved 2024-10-29 – via YouTube.
- ^ Anderson, Brian (2012-01-24). "[rust-dev] The Rust compiler 0.1 is unleashed". rust-dev (Mailing list). Archived from the original on 2012-01-24. Retrieved 2025-01-07.
- ^ Anthony, Sebastian (2012-01-24). "Mozilla releases Rust 0.1, the language that will eventually usurp Firefox's C++". ExtremeTech. Retrieved 2025-01-07.
- ^ "Rust logo". Bugzilla. Archived from the original on 2024-02-02. Retrieved 2024-02-02.
- ^ "Purity by pcwalton · Pull Request #5412 · rust-lang/rust". GitHub. Retrieved 2024-10-29.
- ^ Binstock, Andrew (2014-01-07). "The Rise And Fall of Languages in 2013". Dr. Dobb's Journal. Archived from the original on 2016-08-07. Retrieved 2022-11-20.
- ^ Lardinois, Frederic (2015-04-03). "Mozilla And Samsung Team Up To Develop Servo, Mozilla's Next-Gen Browser Engine For Multicore Processors". TechCrunch. Archived from the original on 2016-09-10. Retrieved 2017-06-25.
- ^ "Firefox 45.0, See All New Features, Updates and Fixes". Mozilla. Archived from the original on 2016-03-17. Retrieved 2024-10-31.
- ^ Lardinois, Frederic (2017-09-29). "It's time to give Firefox another chance". TechCrunch. Archived from the original on 2023-08-15. Retrieved 2023-08-15.
- ^ Pereira, Rui; Couto, Marco; Ribeiro, Francisco; Rua, Rui; Cunha, Jácome; Fernandes, João Paulo; Saraiva, João (2017-10-23). "Energy efficiency across programming languages: How do energy, time, and memory relate?". Proceedings of the 10th ACM SIGPLAN International Conference on Software Language Engineering. SLE 2017. New York, NY, USA: Association for Computing Machinery. pp. 256–267. doi:10.1145/3136014.3136031. hdl:1822/65359. ISBN 978-1-4503-5525-4.
- ^ Cimpanu, Catalin (2020-08-11). "Mozilla lays off 250 employees while it refocuses on commercial products". ZDNET. Archived from the original on 2022-03-18. Retrieved 2020-12-02.
- ^ Cooper, Daniel (2020-08-11). "Mozilla lays off 250 employees due to the pandemic". Engadget. Archived from the original on 2020-12-13. Retrieved 2020-12-02.
- ^ Tung, Liam (2020-08-21). "Programming language Rust: Mozilla job cuts have hit us badly but here's how we'll survive". ZDNET. Archived from the original on 2022-04-21. Retrieved 2022-04-21.
- ^ "Laying the foundation for Rust's future". Rust Blog. 2020-08-18. Archived from the original on 2020-12-02. Retrieved 2020-12-02.
- ^ "Hello World!". Rust Foundation. 2020-02-08. Archived from the original on 2022-04-19. Retrieved 2022-06-04.
- ^ "Mozilla Welcomes the Rust Foundation". Mozilla Blog. 2021-02-09. Archived from the original on 2021-02-08. Retrieved 2021-02-09.
- ^ Amadeo, Ron (2021-04-07). "Google is now writing low-level Android code in Rust". Ars Technica. Archived from the original on 2021-04-08. Retrieved 2021-04-08.
- ^ Anderson, Tim (2021-11-23). "Entire Rust moderation team resigns". The Register. Archived from the original on 2022-07-14. Retrieved 2022-08-04.
- ^ Levick, Ryan; Bos, Mara. "Governance Update". Inside Rust Blog. Archived from the original on 2022-10-27. Retrieved 2022-10-27.
- ^ a b Claburn, Thomas (2023-04-17). "Rust Foundation apologizes for trademark policy confusion". The Register. Archived from the original on 2023-05-07. Retrieved 2023-05-07.
- ^ Gross, Grant (2024-02-27). "White House urges developers to dump C and C++". InfoWorld. Retrieved 2025-01-26.
- ^ Warminsky, Joe (2024-02-27). "After decades of memory-related software bugs, White House calls on industry to act". The Record. Retrieved 2025-01-26.
- ^ "Press Release: Future Software Should Be Memory Safe". The White House. 2024-02-26. Archived from the original on 2025-01-18. Retrieved 2025-01-26.
- ^ Proven, Liam (2019-11-27). "Rebecca Rumbul named new CEO of The Rust Foundation". The Register. Archived from the original on 2022-07-14. Retrieved 2022-07-14.
Both are curly bracket languages, with C-like syntax that makes them unintimidating for C programmers.
- ^ a b c Vigliarolo, Brandon (2021-02-10). "The Rust programming language now has its own independent foundation". TechRepublic. Archived from the original on 2023-03-20. Retrieved 2022-07-14.
- ^ Klabnik & Nichols 2019, p. 263.
- ^ Klabnik & Nichols 2019, pp. 5–6.
- ^ Klabnik & Nichols 2023, p. 32.
- ^ Klabnik & Nichols 2023, pp. 32–33.
- ^ Klabnik & Nichols 2023, pp. 49–50.
- ^ Klabnik & Nichols 2023, pp. 34–36.
- ^ Klabnik & Nichols 2023, pp. 6, 47, 53.
- ^ Klabnik & Nichols 2023, pp. 47–48.
- ^ a b Klabnik & Nichols 2023, pp. 50–53.
- ^ Klabnik & Nichols 2023, p. 56.
- ^ Klabnik & Nichols 2023, pp. 57–58.
- ^ Klabnik & Nichols 2023, pp. 54–56.
- ^ Klabnik & Nichols 2019, pp. 104–109.
- ^ Klabnik & Nichols 2019, pp. 24.
- ^ Klabnik & Nichols 2019, pp. 36–38.
- ^ "isize". doc.rust-lang.org. Retrieved 2025-09-28.
- ^ "usize". doc.rust-lang.org. Retrieved 2025-09-28.
- ^ Klabnik & Nichols 2023, pp. 36–38.
- ^ Klabnik & Nichols 2023, p. 502.
- ^ "Primitive Type char". The Rust Standard Library documentation. Retrieved 2025-09-07.
- ^ "Glossary of Unicode Terms". Unicode Consortium. Archived from the original on 2018-09-24. Retrieved 2024-07-30.
- ^ Klabnik & Nichols 2019, pp. 38–40.
- ^ Klabnik & Nichols 2023, pp. 40–42.
- ^ Klabnik & Nichols 2023, p. 42.
- ^ Klabnik & Nichols 2019, pp. 59–61.
- ^ a b Klabnik & Nichols 2019, pp. 63–68.
- ^ Klabnik & Nichols 2019, pp. 74–75.
- ^ Klabnik & Nichols 2023, pp. 71–72.
- ^ a b Balasubramanian, Abhiram; Baranowski, Marek S.; Burtsev, Anton; Panda, Aurojit; Rakamarić, Zvonimir; Ryzhyk, Leonid (2017-05-07). "System Programming in Rust". Proceedings of the 16th Workshop on Hot Topics in Operating Systems. HotOS '17. New York, NY, US: Association for Computing Machinery. pp. 156–161. doi:10.1145/3102980.3103006. ISBN 978-1-4503-5068-6. S2CID 24100599. Archived from the original on 2022-06-11. Retrieved 2022-06-01.
- ^ Klabnik & Nichols 2023, pp. 327–30.
- ^ "Lifetimes". Rust by Example. Archived from the original on 2024-11-16. Retrieved 2024-10-29.
- ^ "Explicit annotation". Rust by Example. Retrieved 2024-10-29.
- ^ a b Klabnik & Nichols 2019, p. 194.
- ^ Klabnik & Nichols 2019, pp. 75, 134.
- ^ Shamrell-Harrington, Nell (2022-04-15). "The Rust Borrow Checker – a Deep Dive". InfoQ. Archived from the original on 2022-06-25. Retrieved 2022-06-25.
- ^ Klabnik & Nichols 2019, pp. 194–195.
- ^ Klabnik & Nichols 2023, pp. 208–12.
- ^ Klabnik & Nichols 2023, 4.2. References and Borrowing.
- ^ Pearce, David (2021-04-17). "A Lightweight Formalism for Reference Lifetimes and Borrowing in Rust". ACM Transactions on Programming Languages and Systems. 43: 1–73. doi:10.1145/3443420. Archived from the original on 2024-04-15. Retrieved 2024-12-11.
- ^ Klabnik & Nichols 2019, p. 83.
- ^ Klabnik & Nichols 2019, p. 97.
- ^ Klabnik & Nichols 2019, pp. 98–101.
- ^ Klabnik & Nichols 2019, pp. 438–440.
- ^ Klabnik & Nichols 2019, pp. 93.
- ^ Gjengset 2021, pp. 213–215.
- ^ Klabnik & Nichols 2023, pp. 108–110, 113–114, 116–117.
- ^ "Rust error handling is perfect actually". Bitfield Consulting. Archived from the original on 2025-08-07. Retrieved 2025-09-15.
- ^ Gjengset 2021, p. 155-156.
- ^ Klabnik & Nichols 2023, pp. 421–423.
- ^ Klabnik & Nichols 2019, pp. 418–427.
- ^ "Casting". Rust by Example. Retrieved 2025-04-01.
- ^ Klabnik & Nichols 2023, p. 378.
- ^ a b c Klabnik & Nichols 2023, pp. 192–198.
- ^ Klabnik & Nichols 2023, p. 98.
- ^ Klabnik & Nichols 2019, pp. 171–172, 205.
- ^ a b Klabnik & Nichols 2023, pp. 191–192.
- ^ Gjengset 2021, p. 25.
- ^ Klabnik & Nichols 2023, 18.2. Using Trait Objects That Allow for Values of Different Types.
- ^ Klabnik & Nichols 2019, pp. 441–442.
- ^ Klabnik & Nichols 2019, pp. 379–380.
- ^ Rosenblatt, Seth (2013-04-03). "Samsung joins Mozilla's quest for Rust". CNET. Archived from the original on 2013-04-04. Retrieved 2013-04-05.
- ^ Brown, Neil (2013-04-17). "A taste of Rust". LWN.net. Archived from the original on 2013-04-26. Retrieved 2013-04-25.
- ^ "Races". The Rustonomicon. Archived from the original on 2017-07-10. Retrieved 2017-07-03.
- ^ Vandervelden, Thibaut; De Smet, Ruben; Deac, Diana; Steenhaut, Kris; Braeken, An (2024-09-07). "Overview of Embedded Rust Operating Systems and Frameworks". Sensors. 24 (17): 5818. Bibcode:2024Senso..24.5818V. doi:10.3390/s24175818. PMC 11398098. PMID 39275729.
- ^ "The Rust Language FAQ". The Rust Programming Language. 2015. Archived from the original on 2015-04-20. Retrieved 2017-04-24.
- ^ "RAII". Rust by Example. Archived from the original on 2019-04-21. Retrieved 2020-11-22.
- ^ "Abstraction without overhead: traits in Rust". Rust Blog. Archived from the original on 2021-09-23. Retrieved 2021-10-19.
- ^ "Box, stack and heap". Rust by Example. Archived from the original on 2022-05-31. Retrieved 2022-06-13.
- ^ Klabnik & Nichols 2019, pp. 70–75.
- ^ Klabnik & Nichols 2019, p. 323.
- ^ Klabnik & Nichols 2023, pp. 420–429.
- ^ McNamara 2021, p. 139, 376–379, 395.
- ^ a b Astrauskas, Vytautas; Matheja, Christoph; Poli, Federico; Müller, Peter; Summers, Alexander J. (2020-11-13). "How do programmers use unsafe rust?". Proceedings of the ACM on Programming Languages. 4: 1–27. doi:10.1145/3428204. hdl:20.500.11850/465785. ISSN 2475-1421.
- ^ Lattuada, Andrea; Hance, Travis; Cho, Chanhee; Brun, Matthias; Subasinghe, Isitha; Zhou, Yi; Howell, Jon; Parno, Bryan; Hawblitzel, Chris (2023-04-06). "Verus: Verifying Rust Programs using Linear Ghost Types". Proceedings of the ACM on Programming Languages. 7: 85:286–85:315. doi:10.1145/3586037. hdl:20.500.11850/610518.
- ^ Milano, Mae; Turcotti, Julia; Myers, Andrew C. (2022-06-09). "A flexible type system for fearless concurrency". Proceedings of the 43rd ACM SIGPLAN International Conference on Programming Language Design and Implementation. New York, NY, USA: Association for Computing Machinery. pp. 458–473. doi:10.1145/3519939.3523443. ISBN 978-1-4503-9265-5.
- ^ "Introduction - Learning Rust With Entirely Too Many Linked Lists". rust-unofficial.github.io. Retrieved 2025-08-06.
- ^ Noble, James; Mackay, Julian; Wrigstad, Tobias (2023-10-16). "Rusty Links in Local Chains✱". Proceedings of the 24th ACM International Workshop on Formal Techniques for Java-like Programs. New York, NY, USA: Association for Computing Machinery. pp. 1–3. doi:10.1145/3611096.3611097. ISBN 979-8-4007-0784-1.
- ^ a b Evans, Ana Nora; Campbell, Bradford; Soffa, Mary Lou (2020-10-01). "Is rust used safely by software developers?". Proceedings of the ACM/IEEE 42nd International Conference on Software Engineering. New York, NY, USA: Association for Computing Machinery. pp. 246–257. arXiv:2007.00752. doi:10.1145/3377811.3380413. ISBN 978-1-4503-7121-6.
- ^ "Behavior considered undefined". The Rust Reference. Retrieved 2025-08-06.
- ^ Klabnik & Nichols 2023, pp. 449–455.
- ^ Gjengset 2021, pp. 101–102.
- ^ "Macros By Example". The Rust Reference. Archived from the original on 2023-04-21. Retrieved 2023-04-21.
- ^ Klabnik & Nichols 2019, pp. 446–448.
- ^ "Procedural Macros". The Rust Programming Language Reference. Archived from the original on 2020-11-07. Retrieved 2021-03-23.
- ^ Klabnik & Nichols 2019, pp. 449–455.
- ^ Baumgartner, Stefan (2025-05-23). "Programming language: Rust 2024 is the most comprehensive edition to date". heise online. Retrieved 2025-06-28.
- ^ a b c Gjengset 2021, pp. 193–209.
- ^ "Safe Interoperability between Rust and C++ with CXX". InfoQ. 2020-12-06. Archived from the original on 2021-01-22. Retrieved 2021-01-03.
- ^ Blandy, Orendorff & Tindall 2021, pp. 6–8.
- ^ "Overview of the compiler". Rust Compiler Development Guide. Rust project contributors. Archived from the original on 2023-05-31. Retrieved 2024-11-07.
- ^ "Code Generation". Rust Compiler Development Guide. Rust project contributors. Retrieved 2024-03-03.
- ^ "rust-lang/rustc_codegen_gcc". GitHub. The Rust Programming Language. 2024-03-02. Retrieved 2024-03-03.
- ^ "rust-lang/rustc_codegen_cranelift". GitHub. The Rust Programming Language. 2024-03-02. Retrieved 2024-03-03.
- ^ a b c Perkel, Jeffrey M. (2020-12-01). "Why scientists are turning to Rust". Nature. 588 (7836): 185–186. Bibcode:2020Natur.588..185P. doi:10.1038/d41586-020-03382-2. PMID 33262490. S2CID 227251258. Archived from the original on 2022-05-06. Retrieved 2022-05-15.
- ^ Simone, Sergio De (2019-04-18). "Rust 1.34 Introduces Alternative Registries for Non-Public Crates". InfoQ. Archived from the original on 2022-07-14. Retrieved 2022-07-14.
- ^ Klabnik & Nichols 2019, pp. 511–512.
- ^ "Clippy". GitHub. The Rust Programming Language. 2023-11-30. Archived from the original on 2021-05-23. Retrieved 2025-10-09.
- ^ "Clippy Lints". The Rust Programming Language. Retrieved 2023-11-30.
- ^ Klabnik & Nichols 2019, Appendix G – How Rust is Made and "Nightly Rust"
- ^ Blandy, Orendorff & Tindall 2021, pp. 176–177.
- ^ Klabnik & Nichols 2023, p. 623.
- ^ Anderson, Tim (2021-11-30). "Can Rust save the planet? Why, and why not". The Register. Archived from the original on 2022-07-11. Retrieved 2022-07-11.
- ^ Yegulalp, Serdar (2021-10-06). "What is the Rust language? Safe, fast, and easy software development". InfoWorld. Archived from the original on 2022-06-24. Retrieved 2022-06-25.
- ^ McNamara 2021, p. 11.
- ^ a b Popescu, Natalie; Xu, Ziyang; Apostolakis, Sotiris; August, David I.; Levy, Amit (2021-10-15). "Safer at any speed: automatic context-aware safety enhancement for Rust". Proceedings of the ACM on Programming Languages. 5 (OOPSLA). Section 2. doi:10.1145/3485480. S2CID 238212612. p. 5:
We observe a large variance in the overheads of checked indexing: 23.6% of benchmarks do report significant performance hits from checked indexing, but 64.5% report little-to-no impact and, surprisingly, 11.8% report improved performance ... Ultimately, while unchecked indexing can improve performance, most of the time it does not.
- ^ McNamara 2021, p. 19, 27.
- ^ Couprie, Geoffroy (2015). "Nom, A Byte oriented, streaming, Zero copy, Parser Combinators Library in Rust". 2015 IEEE Security and Privacy Workshops. pp. 142–148. doi:10.1109/SPW.2015.31. ISBN 978-1-4799-9933-0. S2CID 16608844.
- ^ McNamara 2021, p. 20.
- ^ "Code generation". The Rust Reference. Archived from the original on 2022-10-09. Retrieved 2022-10-09.
- ^ "How Fast Is Rust?". The Rust Programming Language FAQ. Archived from the original on 2020-10-28. Retrieved 2019-04-11.
- ^ Farshin, Alireza; Barbette, Tom; Roozbeh, Amir; Maguire, Gerald Q. Jr; Kostić, Dejan (2021). "PacketMill: Toward per-Core 100-GBPS networking". Proceedings of the 26th ACM International Conference on Architectural Support for Programming Languages and Operating Systems. pp. 1–17. doi:10.1145/3445814.3446724. ISBN 9781450383172. S2CID 231949599. Archived from the original on 2022-07-12. Retrieved 2022-07-12.
... While some compilers (e.g., Rust) support structure reordering [82], C & C++ compilers are forbidden to reorder data structures (e.g., struct or class) [74] ...
- ^ Gjengset 2021, p. 22.
- ^ Keizer, Gregg (2016-10-31). "Mozilla plans to rejuvenate Firefox in 2017". Computerworld. Archived from the original on 2023-05-13. Retrieved 2023-05-13.
- ^ Claburn, Thomas (2023-01-12). "Google polishes Chromium code with a layer of Rust". The Register. Retrieved 2024-07-17.
- ^ Jansens, Dana (2023-01-12). "Supporting the Use of Rust in the Chromium Project". Google Online Security Blog. Archived from the original on 2023-01-13. Retrieved 2023-11-12.
- ^ Shankland, Stephen (2016-07-12). "Firefox will get overhaul in bid to get you interested again". CNET. Archived from the original on 2022-07-14. Retrieved 2022-07-14.
- ^ Security Research Team (2013-10-04). "ZeroMQ: Helping us Block Malicious Domains in Real Time". Cisco Umbrella. Archived from the original on 2023-05-13. Retrieved 2023-05-13.
- ^ Cimpanu, Catalin (2019-10-15). "AWS to sponsor Rust project". ZDNET. Retrieved 2024-07-17.
- ^ Nichols, Shaun (2018-06-27). "Microsoft's next trick? Kicking things out of the cloud to Azure IoT Edge". The Register. Archived from the original on 2019-09-27. Retrieved 2019-09-27.
- ^ Tung, Liam (2020-04-30). "Microsoft: Why we used programming language Rust over Go for WebAssembly on Kubernetes app". ZDNET. Archived from the original on 2022-04-21. Retrieved 2022-04-21.
- ^ Claburn, Thomas (2022-09-20). "In Rust We Trust: Microsoft Azure CTO shuns C and C++". The Register. Retrieved 2024-07-07.
- ^ Simone, Sergio De (2019-03-10). "NPM Adopted Rust to Remove Performance Bottlenecks". InfoQ. Archived from the original on 2023-11-19. Retrieved 2023-11-20.
- ^ Lyu, Shing (2020). "Welcome to the World of Rust". In Lyu, Shing (ed.). Practical Rust Projects: Building Game, Physical Computing, and Machine Learning Applications. Berkeley, CA: Apress. pp. 1–8. doi:10.1007/978-1-4842-5599-5_1. ISBN 978-1-4842-5599-5. Retrieved 2023-11-29.
- ^ Lyu, Shing (2021). "Rust in the Web World". In Lyu, Shing (ed.). Practical Rust Web Projects: Building Cloud and Web-Based Applications. Berkeley, CA: Apress. pp. 1–7. doi:10.1007/978-1-4842-6589-5_1. ISBN 978-1-4842-6589-5. Retrieved 2023-11-29.
- ^ a b c Li, Hongyu; Guo, Liwei; Yang, Yexuan; Wang, Shangguang; Xu, Mengwei (2024-06-30). "An Empirical Study of Rust-for-Linux: The Success, Dissatisfaction, and Compromise". USENIX. Retrieved 2024-11-28.
- ^ Corbet, Jonathan (2022-10-13). "A first look at Rust in the 6.1 kernel". LWN.net. Archived from the original on 2023-11-17. Retrieved 2023-11-11.
- ^ Vaughan-Nichols, Steven (2021-12-07). "Rust takes a major step forward as Linux's second official language". ZDNET. Retrieved 2024-11-27.
- ^ Corbet, Jonathan (2022-11-17). "Rust in the 6.2 kernel". LWN.net. Retrieved 2024-11-28.
- ^ Corbet, Jonathan (2024-09-24). "Committing to Rust in the kernel". LWN.net. Retrieved 2024-11-28.
- ^ Amadeo, Ron (2021-04-07). "Google is now writing low-level Android code in Rust". Ars Technica. Archived from the original on 2021-04-08. Retrieved 2022-04-21.
- ^ Darkcrizt (2021-04-02). "Google Develops New Bluetooth Stack for Android, Written in Rust". Desde Linux. Archived from the original on 2021-08-25. Retrieved 2024-08-31.
- ^ Claburn, Thomas (2023-04-27). "Microsoft is rewriting core Windows libraries in Rust". The Register. Archived from the original on 2023-05-13. Retrieved 2023-05-13.
- ^ Proven, Liam (2023-12-01). "Small but mighty, 9Front's 'Humanbiologics' is here for the truly curious". The Register. Retrieved 2024-03-07.
- ^ Yegulalp, Serdar (2016-03-21). "Rust's Redox OS could show Linux a few new tricks". InfoWorld. Archived from the original on 2016-03-21. Retrieved 2016-03-21.
- ^ Anderson, Tim (2021-01-14). "Another Rust-y OS: Theseus joins Redox in pursuit of safer, more resilient systems". The Register. Archived from the original on 2022-07-14. Retrieved 2022-07-14.
- ^ Boos, Kevin; Liyanage, Namitha; Ijaz, Ramla; Zhong, Lin (2020). Theseus: an Experiment in Operating System Structure and State Management. pp. 1–19. ISBN 978-1-939133-19-9. Archived from the original on 2023-05-13. Retrieved 2023-05-13.
- ^ Zhang, HanDong (2023-01-31). "2022 Review | The adoption of Rust in Business". Rust Magazine. Retrieved 2023-02-07.
- ^ Sei, Mark (2018-10-10). "Fedora 29 new features: Startis now officially in Fedora". Marksei, Weekly sysadmin pills. Archived from the original on 2019-04-13. Retrieved 2019-05-13.
- ^ Proven, Liam (2022-07-12). "Oracle Linux 9 released, with some interesting additions". The Register. Archived from the original on 2022-07-14. Retrieved 2022-07-14.
- ^ Proven, Liam (2023-02-02). "System76 teases features coming in homegrown Rust-based desktop COSMIC". The Register. Archived from the original on 2024-07-17. Retrieved 2024-07-17.
- ^ Hu, Vivian (2020-06-12). "Deno Is Ready for Production". InfoQ. Archived from the original on 2020-07-01. Retrieved 2022-07-14.
- ^ Abrams, Lawrence (2021-02-06). "This Flash Player emulator lets you securely play your old games". Bleeping Computer. Archived from the original on 2021-12-25. Retrieved 2021-12-25.
- ^ Kharif, Olga (2020-10-17). "Ethereum Blockchain Killer Goes By Unassuming Name of Polkadot". Bloomberg News. Bloomberg L.P. Archived from the original on 2020-10-17. Retrieved 2021-07-14.
- ^ a b c "2025 Stack Overflow Developer Survey – Technology". Stack Overflow. Retrieved 2025-08-09.
- ^ Claburn, Thomas (2022-06-23). "Linus Torvalds says Rust is coming to the Linux kernel". The Register. Archived from the original on 2022-07-28. Retrieved 2022-07-15.
- ^ Wallach, Dan. "TRACTOR: Translating All C to Rust". DARPA. Retrieved 2025-08-03.
- ^ Jung, Ralf; Jourdan, Jacques-Henri; Krebbers, Robbert; Dreyer, Derek (2017-12-27). "RustBelt: securing the foundations of the Rust programming language". Proceedings of the ACM on Programming Languages. 2 (POPL): 1–34. doi:10.1145/3158154. hdl:21.11116/0000-0003-34C6-3. ISSN 2475-1421.
- ^ Popescu, Natalie; Xu, Ziyang; Apostolakis, Sotiris; August, David I.; Levy, Amit (2021-10-20). "Safer at any speed: automatic context-aware safety enhancement for Rust". Proceedings of the ACM on Programming Languages. 5 (OOPSLA): 1–23. doi:10.1145/3485480. ISSN 2475-1421.
- ^ Blanco-Cuaresma, Sergi; Bolmont, Emeline (2017-05-30). "What can the programming language Rust do for astrophysics?". Proceedings of the International Astronomical Union. 12 (S325): 341–344. arXiv:1702.02951. Bibcode:2017IAUS..325..341B. doi:10.1017/S1743921316013168. ISSN 1743-9213. S2CID 7857871. Archived from the original on 2022-06-25. Retrieved 2022-06-25.
- ^ Klabnik & Nichols 2019, p. 4.
- ^ "Getting Started". The Rust Programming Language. Archived from the original on 2020-11-01. Retrieved 2020-10-11.
- ^ The Rust Survey Team (2025-02-13). "2024 State of Rust Survey Results". The Rust Programming Language. Retrieved 2025-09-07.
- ^ Tung, Liam (2021-02-08). "The Rust programming language just took a huge step forwards". ZDNET. Archived from the original on 2022-07-14. Retrieved 2022-07-14.
- ^ Krill, Paul (2021-02-09). "Rust language moves to independent foundation". InfoWorld. Archived from the original on 2021-04-10. Retrieved 2021-04-10.
- ^ Vaughan-Nichols, Steven J. (2021-04-09). "AWS's Shane Miller to head the newly created Rust Foundation". ZDNET. Archived from the original on 2021-04-10. Retrieved 2021-04-10.
- ^ Vaughan-Nichols, Steven J. (2021-11-17). "Rust Foundation appoints Rebecca Rumbul as executive director". ZDNET. Archived from the original on 2021-11-18. Retrieved 2021-11-18.
- ^ "Governance". The Rust Programming Language. Archived from the original on 2022-05-10. Retrieved 2024-07-18.
- ^ "Introducing the Rust Leadership Council". Rust Blog. 2023-06-20. Retrieved 2024-01-12.
External links
[edit]Rust (programming language)
View on GrokipediaHistory
Origins and Early Development (2006–2012)
Rust originated as a personal hobby project initiated by Graydon Hoare in 2006, while he was employed as a programmer at Mozilla.[7][8] Hoare, then 29 years old, sought to address longstanding limitations in systems programming languages like C++, particularly the prevalence of memory safety bugs such as buffer overflows and dangling pointers that could lead to exploitable vulnerabilities without relying on garbage collection, which he viewed as inefficient for performance-critical applications.[7] His early prototype consisted of a compact 17,000-line native compiler implemented on his personal laptop during non-work hours, drawing inspiration from Cyclone's region-based memory management to enforce bounds checking and aliasing discipline at compile time.[9] Additional influences included functional languages such as OCaml and Haskell for traits and pattern matching, aiming to blend imperative systems-level control with safer abstractions.[10] This solo effort reflected Hoare's frustration with C++'s unchecked pointer arithmetic and manual memory management, which often resulted in subtle errors undetectable until runtime.[11] In 2009, Mozilla recognized the potential of Hoare's prototype and began officially sponsoring the project as an open-source initiative, providing resources while maintaining its independence under community governance.[7][3] The sponsorship aligned with Mozilla's interest in developing safer concurrency primitives for browser engines, where multithreaded code had contributed to crashes and security incidents in the early 2010s, though the core motivation remained rooted in Hoare's vision for GC-free safety rather than any predefined corporate mandate.[12] Under this support, the language evolved through iterative prototypes, incorporating channels for message-passing concurrency inspired by languages like Newsqueak and Limbo, while prioritizing compile-time verification of ownership and borrowing to prevent data races.[10] The project gained public visibility with its formal announcement in 2010, followed by the release of version 0.1 on January 20, 2012, which supported Windows, Linux, and macOS platforms and demonstrated core features like strong typing, memory safety guarantees, and lightweight concurrency.[13][14] This alpha release marked the transition from Hoare's individual experimentation to collaborative development, with initial volunteers contributing to toolchain refinements, though stability remained a work in progress ahead of the eventual 1.0 milestone.[15] Early efforts emphasized empirical validation through test suites, validating the feasibility of Hoare's design without compromising on systems-level performance.[12]Maturation Under Mozilla (2012–2020)
Mozilla's sponsorship facilitated Rust's transition from an experimental project to a stable language, with the 1.0 release occurring on May 15, 2015, after nine years of development emphasizing memory safety through the ownership model and borrow checker.[4] This milestone followed rigorous iterations to stabilize core features, including the borrow checker, which enforces compile-time rules to prevent data races and invalid memory accesses without runtime overhead.[4] Parallel to language stabilization, Mozilla initiated the Servo project in 2012 as an experimental browser engine written primarily in Rust, aiming to leverage the language's concurrency primitives for parallel rendering and layout.[16] Servo's development milestones, such as passing the Acid2 test by March 2014, demonstrated Rust's viability for high-performance, safe systems programming in browser contexts, influencing feature prioritization like thread-safe abstractions.[17] Components from Servo, including the Stylo CSS styling engine, were integrated into Firefox starting in 2017 as part of the Quantum rendering initiative, marking Rust's practical application within Mozilla's flagship browser and validating its design for production use. This integration causally linked Mozilla's browser engineering needs to Rust's evolution in parallelism and performance-oriented safety guarantees. The ecosystem matured with tools like Cargo, Rust's package manager and build system, which became integral by the 1.0 era, and crates.io, the public registry preview-launched on December 18, 2014, enabling dependency management and community contributions under Mozilla's oversight.[18] By 2019, advancements in concurrency support culminated in the stabilization of async/await syntax on November 7, as part of Rust 1.39.0, enhancing asynchronous programming without compromising the borrow checker's invariants.[19] These developments, driven by Mozilla's focus on reliable, efficient code for web technologies, positioned Rust for broader applicability while maintaining its core guarantees.Independence via Rust Foundation and Expansion (2020–present)
In August 2020, Mozilla Corporation announced layoffs affecting approximately 250 employees, including significant portions of the Rust and Wasmtime teams, raising concerns within the Rust community about the project's long-term sustainability under Mozilla's sponsorship.[20] [21] These reductions, part of broader cost-cutting amid Mozilla's financial challenges, prompted the Rust core team to accelerate plans for organizational independence to ensure continued development decoupled from any single corporate entity's priorities.[22] [23] On February 8, 2021, the Rust Foundation was established as a nonprofit to steward the language, with founding platinum members AWS, Google, Huawei, Microsoft, and Mozilla each committing initial funding of at least $250,000 annually for two years, alongside governance through a board including representatives from these entities and the Rust project directors.[24] [25] This structure provided Rust with neutral, multi-stakeholder support, enabling hiring of dedicated staff and reducing reliance on volunteer labor or Mozilla's resources, while the foundation focused on legal, financial, and community infrastructure.[26] Post-foundation, Rust's expansion accelerated with the stabilization of the 2024 edition alongside Rust 1.85.0 on February 20, 2025, introducing features such as async closures, revised lifetime capture rules in closures, and scoped pseudorandom number generators to enhance expressiveness and safety without backward incompatibility for prior editions.[27] Concurrently, Rust's integration into the Linux kernel advanced, with the first production-ready Rust drivers—such as an NVMe host controller—merged into Linux 6.8 in March 2024, followed by additional drivers like platform and GPIO in subsequent releases, marking a shift toward Rust as a viable option for kernel modules to mitigate memory safety vulnerabilities in C code. In September 2025, the Rust Foundation launched the Rust Innovation Lab to incubate critical ecosystem projects, starting with rustls—a memory-safe TLS library—as its inaugural initiative, providing governance, legal, and operational support to accelerate adoption in security-sensitive domains.[28] [29] This program underscores Rust's broadening influence beyond core language development, fostering specialized libraries while maintaining open-source principles.[30]Design Philosophy
Ownership, Borrowing, and Lifetimes
Rust's ownership model enforces that every value has a single owner responsible for its lifetime, ensuring automatic deallocation when the owner goes out of scope and preventing issues like memory leaks or double frees through compile-time rules rather than runtime garbage collection.[31] This approach draws from first-principles resource management, treating memory as a scarce resource where exclusive control by one entity at a time avoids causal conflicts such as concurrent modifications. Ownership transfers via moves, which invalidate the original binding, maintaining the invariant that no value can be accessed after relinquishment.[31] Borrowing extends this by allowing temporary references to values without transferring ownership, distinguishing between immutable borrows (multiple allowed simultaneously for read-only access) and mutable borrows (exclusive, preventing aliasing during mutation). The borrow checker, a core component of the Rust compiler, statically verifies these rules to preclude data races and invalid accesses, such as use-after-free, by tracking borrow scopes and ensuring mutable borrows do not overlap with any borrows.[32] This enforcement relies on affine typing semantics, where values are used at most once (though unused values are dropped), enabling safe resource handling without requiring explicit reference counting in most cases.[31] Lifetimes annotate references to guarantee they do not outlive the data they reference, with the compiler inferring most but requiring explicit markers in polymorphic or complex scenarios to resolve ambiguities. The 'static lifetime denotes references valid for the entire program duration, often used for string literals or global data. By design, this system causally prevents the majority of memory safety violations—such as buffer overflows and dangling pointers—that plague languages like C++, where undefined behavior permits exploitable errors. Microsoft analyses indicate that approximately 70% of security vulnerabilities in their products stem from memory safety issues, many of which Rust's model eliminates at compile time without runtime overhead.[33]Memory Safety Without Garbage Collection
Rust enforces memory safety through its ownership model, which assigns each value a single owner responsible for its lifetime; when the owner goes out of scope, the value is automatically dropped via a deterministic destructor call, freeing associated memory without runtime overhead or garbage collection pauses.[2] This compile-time mechanism prevents common errors like use-after-free and double-free by prohibiting multiple mutable owners or concurrent access violations, as verified by the borrow checker, which analyzes code for adherence to borrowing rules: immutable references (&T) allow multiple concurrent borrows, while mutable references (&mut T) permit only exclusive access.[2] Lifetimes, annotated with syntax like 'a, further ensure that references do not outlive the data they reference, eliminating dangling pointers at compilation rather than runtime. Unlike manual management in C, where deallocation errors account for a significant portion of vulnerabilities—such as 70% of Microsoft security bugs historically tied to memory issues—Rust's rules shift error detection to compile time, enabling real-time systems suitability due to predictable, non-pausing memory reclamation. Empirical analyses of Rust Common Vulnerabilities and Exposures (CVEs) confirm that all memory-safety violations occur in unsafe code blocks, which opt out of these guarantees, with buffer overflows and dangling pointers comprising the primary issues but confined to less than 10% of crates involving unsafe in typical audits.[34] Adoption in projects like the Linux kernel has yielded zero memory-safety CVEs in Rust components as of mid-2024, contrasting with persistent C-related flaws, though causal attribution requires noting selection bias in Rust's usage for new, safety-critical modules.[35] This approach trades ergonomic flexibility for causal prevention of entire bug classes, as moves transfer ownership explicitly (e.g., via std::mem::take) without implicit copying, ensuring no hidden aliasing; however, it does not address non-memory errors like integer overflows in safe code or logic flaws.[2] Unsafe code, required for foreign function interfaces (FFI) with C libraries, reintroduces risks by permitting raw pointer dereferences, necessitating manual audits since the compiler cannot verify external code's invariants.[36] Benchmarks transpiling C to Rust demonstrate up to 90% reduction in exploitable memory flaws post-verification, but full elimination demands minimizing unsafe exposure, as FFI boundaries remain a vector for imported vulnerabilities.[37] Thus, while Rust empirically curbs memory errors in safe subsets—evidenced by low CVE rates in audited ecosystems—it mandates developer discipline for edge cases, debunking overclaims of universal bug-proofing.[38]Performance-Oriented Abstractions
Rust's performance-oriented abstractions, such as generics, traits, and iterators, are designed to provide high-level expressiveness without runtime penalties, with all associated costs deferred to compile time through techniques like monomorphization, inlining, and dead code elimination.[39][40] This approach ensures that abstracted code compiles to machine instructions as efficient as equivalent manual implementations, rejecting the notion that higher-level constructs inherently sacrifice speed.[41] Generics and traits facilitate static polymorphism via monomorphization, where the compiler generates type-specific versions of functions, enabling method inlining and optimization that match the performance of monomorphic C code in targeted benchmarks.[42] For instance, trait implementations for concrete types are specialized and devirtualized at compile time, avoiding dynamic dispatch overhead unless explicitly using trait objects, thus achieving throughput comparable to hand-optimized C++ templates.[43] Iterator chains exemplify this through loop fusion, where sequential operations like mapping and filtering are merged into a single, allocation-free loop by the compiler, yielding causal efficiency improvements over naive intermediate collections.[44] Similarly, pattern matching on enums or values translates to direct jump tables or conditional branches with no extraneous runtime checks, preserving performance parity with explicit if-else chains while enhancing code safety and readability.[45] In practice, these abstractions have enabled projects like the Servo browser engine to employ iterator-heavy pipelines that compile to low-level loops rivaling C++ equivalents in throughput, as verified through assembly inspection and profiling.[46] Standard library iterators, leveraging specialized unsafe internals, often outperform equivalent manual loops in microbenchmarks due to tailored optimizations.[47]Language Features
Basic Syntax and Control Structures
Rust's basic syntax emphasizes explicitness and safety, with programs structured around functions and modules. The entry point is conventionally thefn main() function, which executes the program's primary logic. A simple "Hello, World!" example demonstrates this, using the standard library's println! macro for output:
fn main() {
println!("Hello, World!");
}
fn main() {
println!("Hello, World!");
}
rustc compiler, producing the specified string followed by a newline. Semicolons terminate most statements, except for expressions used as the last item in a block, which implicitly return their value.
Variables are introduced with the let keyword, creating immutable bindings by default to encourage bug-free code through prevention of unintended modifications. For example:
let guess: u32 = "42".parse().expect("Not a number!");
let guess: u32 = "42".parse().expect("Not a number!");
mut annotation:
let mut count = 0;
count += 1;
let mut count = 0;
count += 1;
u32 (unsigned 32-bit integer) above. Shadowing allows redefining a variable in the same scope without mut, enabling transformations like type conversion.
Control structures integrate seamlessly as expressions that evaluate to values, unlike statement-only constructs in languages like C. The if construct supports conditional execution and returns a value usable in assignments:
let condition = true;
let number = if condition {
5
} else {
6
};
let condition = true;
let number = if condition {
5
} else {
6
};
loop for indefinite iteration (escapable via break), while for condition-checked repetition, and for over iterators for ranged or collection traversal:
for i in 1..=5 {
println!("Iteration: {}", i);
}
for i in 1..=5 {
println!("Iteration: {}", i);
}
..= operator denotes inclusive ranges. Pattern matching via match provides exhaustive, destructuring control flow, requiring coverage of all cases (including wildcard _ for defaults) to compile:
let x = 5;
match x {
1 => println!("one"),
2..=5 => println!("two to five"),
_ => println!("something else"),
}
let x = 5;
match x {
1 => println!("one"),
2..=5 => println!("two to five"),
_ => println!("something else"),
}
if let and while let enable targeted matching without full match syntax.
To avoid null pointer dereferences common in other systems languages, Rust employs the Option enum from the prelude: Option<T> variants Some(T) and None. Usage requires explicit handling, such as via match or the unwrap() method (which panics on None), but patterns like if let Some(value) = maybe_some { ... } prevent runtime errors at compile time. Similarly, Result<T, E> encapsulates success (Ok(T)) or error (Err(E)), promoting checked operations over unchecked assumptions. These types empirically reduce null-induced crashes; for instance, in production systems adopting Rust, null-related panics are eliminated by design, contrasting with C/C++ where such bugs persist in approximately 70% of security vulnerabilities per historical analyses.
Types, Patterns, and Polymorphism
Rust employs a statically typed type system that enforces type safety at compile time, leveraging inference to minimize explicit annotations while providing guarantees against type-related errors without runtime checks. This system supports primitive scalar types—integers (signedi8 to i128, unsigned u8 to u128), floating-point f32 and f64, bool, and Unicode char—along with compound types such as tuples for fixed-size heterogeneous collections and arrays or slices for homogeneous sequences. Enumerations (enums) extend this with algebraic data types, allowing variants that may carry associated data, enabling expressive representations like option types (Option<T>) for nullable values or result types (Result<T, E>) for error handling, which prevent null pointer dereferences and unchecked errors through compile-time enforcement.
Pattern matching integrates deeply with types, particularly enums, via match expressions that destructure values and bind components to variables, with the compiler verifying exhaustiveness to ensure all possible variants are handled, thus averting runtime failures from unhandled cases. Patterns support nesting, guards (conditional if clauses on arms), and bindings, as in:
match value {
Ok(n @ 1..=5) if n > 0 => println!("Positive small number: {}", n),
Err(e) => println!("Error: {}", e),
_ => println!("Other"),
}
match value {
Ok(n @ 1..=5) if n > 0 => println!("Positive small number: {}", n),
Err(e) => println!("Error: {}", e),
_ => println!("Other"),
}
fn print_length<T: std::fmt::Debug + std::ops::Deref>(item: &T) {
println!("Length: {:?}", item.len());
}
fn print_length<T: std::fmt::Debug + std::ops::Deref>(item: &T) {
println!("Length: {:?}", item.len());
}
dyn Trait) use dynamic dispatch via virtual tables, incurring indirection overhead but allowing heterogeneous collections. This design prioritizes verifiable performance guarantees, as static dispatch inlines calls and optimizes aggressively, aligning with Rust's emphasis on compile-time verifiability over flexible but unpredictable runtime behavior.
Concurrency and Parallelism
Rust's concurrency model emphasizes compile-time guarantees against data races through its ownership system combined with theSend and Sync marker traits. The Send trait ensures that a type can safely transfer ownership across thread boundaries, while Sync guarantees that shared references (&T) to the type can be sent between threads, meaning the type is safe for concurrent access by multiple threads. These traits are automatically implemented for primitive types and most standard library types, but user-defined types must opt-in, enforcing thread-safety checks at compile time rather than runtime. This approach renders safe Rust code data-race free by construction, as the borrow checker prevents mutable shared state unless explicitly synchronized, contrasting with languages like C++ where data races from concurrent mutable access require runtime detection tools or careful manual synchronization.[48][49][50]
For communication between threads, Rust provides channels via std::sync::mpsc (multiple producer, single consumer), which transfer ownership of messages, avoiding shared mutable state and thus eliminating data races inherent in shared-memory models. Producers send values that are moved into the channel, and the receiver takes ownership upon receipt, leveraging Rust's linear types to ensure no aliasing. Mutexes, implemented as std::sync::Mutex<T>, protect shared mutable data but require wrapping in Arc (atomic reference counting) for multi-thread sharing; acquiring a lock yields a MutexGuard whose RAII drop semantics automatically release the lock, reducing deadlock risks from forgotten unlocks seen in manual-locking APIs like POSIX threads. Ownership transfer into the mutex upon creation further scopes access, as threads relinquish direct control, promoting scoped locking patterns that empirically lower deadlock incidence compared to lock hierarchies in C or Java.[51][50]
Parallelism in Rust is facilitated by libraries like Rayon, which extends sequential iterators with parallel counterparts (e.g., par_iter()) using a work-stealing thread pool for dynamic load balancing across cores. Rayon's design inherits Rust's safety guarantees, ensuring parallel operations on collections remain data-race free without explicit locks, as mutations are confined to disjoint data partitions verified at compile time. Benchmarks demonstrate Rayon's scalability: in matrix multiplication tests on multi-core systems, it achieves near-linear speedup up to 16 cores versus sequential code, with memory bandwidth utilization comparable to OpenMP in C++ but without race detectors needed, as confirmed in NAS Parallel Benchmarks ported to Rust using Rayon, where it matched or exceeded C++ performance in irregular workloads while maintaining zero data races.[52][53]
Macros and Metaprogramming
Rust provides two primary forms of macros for metaprogramming: declarative macros and procedural macros, both leveraging hygienic expansion to avoid unintended identifier capture and ensure contextual isolation.[54] Hygienic macros generate code at compile time, enabling reuse of syntactic patterns and reducing boilerplate, which contributes to developer productivity in the ecosystem by automating repetitive implementations without runtime overhead.[55] This approach contrasts with unhygienic systems in languages like C, where macro expansions can introduce subtle bugs via name clashes.[56] Declarative macros, defined using themacro_rules! construct and invoked with the ! suffix (e.g., vec![]), operate via pattern matching on input token trees to produce templated output.[54] They suit straightforward syntax extensions, such as the standard library's println! macro, which expands to formatted I/O calls tailored to argument counts and types. This form prioritizes simplicity and compile-time hygiene, where macro-defined identifiers remain scoped to their expansion site, preventing interference with surrounding code.[54]
Procedural macros extend this capability by accepting a TokenStream input, allowing parsing into abstract syntax trees (ASTs) for arbitrary manipulation before outputting new code.[55] Requiring a separate crate with the proc-macro attribute, they enable three subtypes: function-like, attribute-like, and derive macros, with the latter automating trait implementations via the #[derive(...)] attribute.[55] For instance, #[derive(Debug)] in the standard library generates fmt::Debug implementations for structs and enums, expanding to recursive formatting logic that handles fields by name or index, verifiable through compile-time checks. Similar derives like Clone and PartialEq eliminate manual repetition for common traits, as seen in over 80% of standard library types using them for interoperability.
While macros enhance expressiveness—evident in libraries like Serde, where procedural derives generate zero-cost serialization code—their power introduces trade-offs in opacity and debuggability. Expanded macro code resists straightforward inspection, complicating error diagnosis, as stack traces often point to generated rather than source lines, necessitating tools like cargo expand for visibility. Procedural variants amplify this, demanding familiarity with syn and quote crates for AST handling, yet empirical adoption in Rust's 100,000+ crates demonstrates net productivity gains despite the learning curve.[57] Critics note that over-reliance can obscure intent, favoring judicious use for verified boilerplate reduction over ad-hoc complexity.[58]
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
println!("{:?}", Point { x: 1, y: 2 }); // Expands to custom Debug impl
}
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
println!("{:?}", Point { x: 1, y: 2 }); // Expands to custom Debug impl
}
Debug would duplicate formatting for each type, but automation ensures consistency across the ecosystem.[54]
Memory Management and Safety
Safe vs. Unsafe Code
Rust enforces memory safety guarantees in its safe subset through compile-time checks on ownership, borrowing, and lifetimes, preventing common errors such as null pointer dereferences, buffer overflows, and data races without runtime overhead like garbage collection. This safe code operates under strict rules verified entirely by the compiler, ensuring that well-behaved programs adhere to the language's invariants.[59] Unsafe code, demarcated byunsafe blocks or functions, opts out of these guarantees, permitting operations that the compiler cannot fully verify, such as dereferencing raw pointers (*const T or *mut T), accessing or mutating static variables, invoking foreign function interfaces (FFI), implementing unsafe traits, or executing inline assembly. These capabilities are essential for scenarios where safe abstractions fall short, including custom memory allocators requiring raw pointer manipulation or architecture-specific optimizations via inline assembly, as in embedded systems or high-performance kernels. For instance, inline assembly might be used for direct CPU instructions unavailable in safe Rust:
unsafe {
asm!(
"nop",
options(noreturn)
);
}
unsafe {
asm!(
"nop",
options(noreturn)
);
}
unsafe keyword usage, typically for bindings or intrinsics rather than pervasive application logic.[61] Large projects like Diem have exceeded 250,000 lines of Rust without any unsafe code by forbidding it via attributes.[62]
Despite these safeguards, unsafe code introduces potential footguns, as misuse can lead to undefined behavior (UB) propagating through safe interfaces if invariants are violated, demanding rigorous manual auditing and expertise beyond compiler assistance.[63] Critics argue that Rust's unsafe subset imposes stricter discipline than equivalents in C or C++—such as upholding borrow checker rules manually—but still risks subtle errors like aliasing violations or lifetime mismatches that evade detection, complicating verification in complex systems.[64] Tools like Miri aid in detecting such UB during testing, yet reliance on programmer diligence persists as a limitation.[59]
Pointers, References, and Deallocation
In Rust, references provide safe access to data without transferring ownership, using borrowing rules enforced at compile time. Immutable references, denoted&T, allow multiple reads but no modifications, while mutable references, &mut T, permit exclusive writes but only one at a time, preventing data races and invalid accesses.[32][65] These references are akin to pointers in other languages but include lifetime annotations and borrow checker validation to ensure they never dangle or violate aliasing.[32]
Raw pointers, *const T and *mut T, offer lower-level control without borrow checker guarantees, requiring unsafe blocks for dereferencing.[66] The *const T variant signals immutability, though it can be cast to *mut T in unsafe code, while *mut T explicitly allows mutation; both lack null checks or bounds safety unless manually implemented.[67][68] Raw pointers are primarily for interfacing with foreign code or performance-critical sections where safety trade-offs are explicit.[66]
Deallocation occurs automatically via the ownership model, where heap-allocated data in types like Box<T> triggers the Drop trait implementation upon scope exit, releasing memory without garbage collection.[31][69] This RAII-inspired approach ensures deterministic cleanup tied to lexical scopes, avoiding runtime pauses but relying on acyclic ownership to prevent leaks.[31] For reference-counted types like Rc<T>, mutual cycles can evade automatic drops, necessitating Weak<T> references or manual arenas—pre-allocated pools that batch-deallocate groups of objects with shared lifetimes—to mitigate leaks explicitly.[70][71] Raw pointers demand manual deallocation via std::alloc in unsafe code, with no built-in automation beyond custom wrappers.[66]
let x = Box::new(5); // Heap allocation
// x drops here, deallocating automatically
let x = Box::new(5); // Heap allocation
// x drops here, deallocating automatically
Interoperability and Integration
C and C++ Bindings
Rust facilitates foreign function interface (FFI) interoperability with C primarily throughextern "C" blocks, which declare function signatures compatible with the C application binary interface (ABI).[73] These blocks, annotated with #[link] attributes, instruct the linker to connect to external C libraries, enabling Rust code to invoke C functions while assuming the called code adheres to C conventions.[74] Types exchanged across this boundary, such as structs or enums, must typically use the #[repr(C)] attribute to ensure layout compatibility with C's memory model, preventing undefined behavior from misalignment or padding differences.[75]
Calls to these foreign C functions require explicit unsafe blocks, as Rust cannot verify the safety invariants of external code, such as pointer validity or memory access bounds.[73] For exposing Rust functions to C callers, developers define extern "C" fn items with #[repr(C)] for arguments and return types, allowing compilation into shared libraries callable from C.[73] Tools like cbindgen automate header generation for such Rust libraries, producing C-compatible .h files from annotated Rust code to simplify integration without manual ABI specification.[76]
Interoperability with C++ builds on C FFI by wrapping C++ APIs in a C-compatible subset, often via extern "C" interfaces to maintain ABI stability.[77] However, C++ exceptions do not propagate across the boundary, necessitating manual error handling like return codes or callbacks to avoid termination.[77] Rust's ownership and lifetime system clashes with C++'s RAII and destructors, requiring unsafe code to manage deallocation and prevent use-after-free errors, as Rust cannot enforce lifetimes on foreign objects.[78]
The libc crate exemplifies successful C bindings, providing raw, platform-specific declarations for standard C library functions and types, used extensively for system calls and low-level operations without introducing Rust-specific overhead.[79] This enables incremental adoption, such as wrapping legacy C libraries in safe Rust abstractions while retaining FFI for performance-critical paths.[79]
Embeddings in Other Ecosystems
Rust code compiled to WebAssembly (WASM) integrates into web ecosystems by leveraging tools like wasm-bindgen, which generates JavaScript bindings for seamless interoperability between Rust modules and JavaScript environments.[80] This allows Rust functions to be called directly from JavaScript in browsers, enabling performance-critical computations on the web without relying on JavaScript's garbage collection, as Rust's ownership model ensures memory safety at compile time.[81] For instance, wasm-bindgen processes the compiled WASM binary to produce wrapper code that exposes Rust APIs as JavaScript classes or functions, supporting complex data types like strings and closures. In bare-metal and embedded systems, Rust employs theno_std attribute to disable the standard library, linking instead to the core crate for essential primitives while avoiding OS dependencies.[82] This configuration suits microcontroller programming, where code runs directly on hardware without an underlying operating system, as seen in applications targeting STM32 devices or UEFI firmware.[83] Bare-metal Rust thus provides type safety and concurrency guarantees in resource-constrained environments, with crates like embedded-hal abstracting hardware access for portability across vendors.[84]
Integration with Python occurs through PyO3, a library that generates bindings to expose Rust code as native Python extensions or embed Python interpreters within Rust binaries.[85] This facilitates hybrid projects where Rust handles compute-intensive or safety-critical components, such as data processing in libraries, while Python manages higher-level scripting; for example, PyO3 automates type conversion between Rust's ownership system and Python's references, enabling transparent calls like invoking Rust functions from Python modules.[86] In mixed codebases, this approach yields causal benefits for security, as Rust's compile-time checks eliminate entire classes of memory vulnerabilities—responsible for up to 70% of exploits in languages like C/C++—thereby shrinking the overall attack surface when Rust isolates untrusted or high-risk operations.[87] Empirical analyses confirm that embedding Rust reduces buffer overflows and use-after-free errors in hybrid systems, with Microsoft citing its efficacy in lowering low-level bug rates compared to traditional systems languages.[88]
Tools and Ecosystem
Compiler and Build System
The Rust compiler, rustc, serves as the primary front-end for parsing, type-checking, and performing initial optimizations on Rust source code before generating intermediate representation (IR). It employs a modular pipeline that includes lexical analysis, syntax parsing via a hand-written recursive descent parser, and borrow checking to enforce memory safety guarantees. Following these stages, rustc emits LLVM IR, leveraging the LLVM infrastructure for machine-code generation, vectorization, and advanced optimizations such as loop unrolling and dead code elimination.[89][90] This backend integration allows rustc to inherit LLVM's mature optimization passes while maintaining Rust-specific semantics, though it introduces dependencies on LLVM's versioning and occasional workarounds for limitations in LLVM's handling of Rust's ownership model.[91] Rust editions provide a mechanism for introducing language changes without disrupting existing codebases, enabling non-breaking evolution through opt-in compatibility modes. Each edition, such as the 2015, 2018, 2021, and the 2024 edition stabilized in February 2025, defines a set of syntactic and semantic defaults that crates can specify independently, ensuring interoperability across editions while allowing reserved keywords or syntax extensions like inherent methods on primitives in 2024.[92][93] This versioning strategy separates language evolution from compiler releases, which follow a six-week cycle on the stable channel (e.g., Rust 1.85.0 supporting the 2024 edition), facilitating gradual adoption and reducing migration friction for large projects.[92] Incremental compilation in rustc mitigates recompilation overhead by constructing a dependency graph of queries—such as type inference and monomorphization—that tracks changes and caches stable results across builds, employing a red-green algorithm to invalidate only affected nodes.[94][95] Enabled by default in debug profiles, this feature reuses disk-cached data for unchanged modules, but empirical measurements on macro-heavy or large-scale projects reveal persistent long compilation times, often exceeding several minutes per iteration due to query instability and LLVM's optimization demands.[96] Cross-compilation is inherent to rustc, which supports over 100 built-in targets by default via the--target flag, generating code for architectures like ARM, WebAssembly, or x86 without requiring host-specific toolchains beyond LLVM's portability.[97] This capability stems from rustc's target-agnostic IR emission, though it demands pre-built standard libraries for non-host targets and may encounter issues with platform-specific intrinsics or linker configurations.[98]
For reproducible builds, rustc incorporates versioning controls like pinned channel releases and deterministic query hashing to aim for bit-identical outputs across environments, but full reproducibility remains incomplete due to factors such as build timestamps, linker variations, and non-deterministic LLVM passes.[99] Efforts include backporting LLVM fixes for stability and community patches to strip non-deterministic metadata, enabling verification of compiler artifacts against source hashes in release pipelines.[100]
Package Management with Cargo
Cargo functions as Rust's integrated package manager and build tool, handling the declaration, resolution, and fetching of dependencies defined in theCargo.toml file. It primarily draws from Crates.io, the central registry for Rust crates, which as of October 2025 hosts over 200,000 crates and has enabled billions of total downloads, with daily peaks exceeding 492 million.[101] [57] [102] This infrastructure has directly accelerated ecosystem expansion by simplifying package distribution and integration, allowing developers to leverage a vast, reusable library of components without manual version tracking.[103]
Dependency resolution occurs via Cargo's built-in solver, which selects the minimal set of compatible versions based on semantic versioning (SemVer) requirements specified by authors, prioritizing recent updates while respecting constraints like ^1.0 for compatible minor and patch releases.[104] The process generates a Cargo.lock file that locks exact versions and hashes, ensuring build reproducibility across machines and CI environments; for applications, this file is committed to version control, whereas libraries typically omit it to defer resolution to downstream users.[104][103]
Workspaces in Cargo permit grouping multiple crates under a single root Cargo.toml, sharing a unified Cargo.lock and output artifacts to reduce redundancy and streamline builds for monorepos or related projects. Semantic versioning is strictly enforced during resolution and publishing, with Cargo validating version formats and compatibility before allowing uploads to Crates.io.
To address security, cargo-audit integrates with Cargo to scan Cargo.lock against the RustSec Advisory Database, flagging dependencies with disclosed vulnerabilities and their severity.[105][106] However, the registry's scale has exposed supply-chain vulnerabilities, including risks from maintainer account compromises enabling malicious crate updates, as discussed in analyses following early incidents and prompting mitigations like API key protections and trusted publishing workflows.[107][108]
Formatting, Linting, and IDE Support
Rust providesrustfmt, an official tool for automatically formatting code to adhere to established style guidelines, promoting consistency across projects.[109] Developers invoke it via cargo fmt, which integrates seamlessly with the Cargo build system to reformat source files in place.[110] Configuration occurs through a rustfmt.toml file, allowing customization of options such as line width and indentation while maintaining a default opinionated style derived from community consensus.[111]
For linting, Clippy extends the Rust compiler with over 750 specialized checks to detect common errors, enforce idiomatic patterns, and suggest improvements, including hints for resolving borrow checker issues.[112] Executed using cargo clippy, it categorizes lints by severity—such as correctness, style, and performance—and supports suppression or allowance via attributes in code.[113] This tooling aids in writing safer and more efficient code by catching subtle mistakes early, complementing the compiler's core diagnostics.
IDE support leverages rust-analyzer, the official Language Server Protocol (LSP) implementation, delivering real-time features like autocompletion, error highlighting, refactoring, and inlay hints in editors such as Visual Studio Code.[114] Integrated via extensions, it analyzes code incrementally without full recompilation, enhancing productivity for large codebases.[115] Compared to C++'s fragmented legacy tools, Rust's ecosystem prioritizes unified, modern integration from inception, though it trails in depth for niche domains due to its relative youth.[116]
Performance Characteristics
Runtime Efficiency and Benchmarks
Rust's ownership and borrowing system enables zero-cost abstractions and aggressive compiler inlining, yielding runtime performance comparable to C and C++ in compute-intensive tasks, without the pauses associated with garbage collection in languages like Go.[117] This is particularly evident in CPU-bound workloads, where benchmarks indicate Rust executes within 5-20% of optimized C++ code, depending on the domain, due to equivalent low-level control over memory and CPU utilization.[118] In TechEmpower Framework Benchmarks Round 23 (released 2024), Rust-based web frameworks such as Actix-web and Poem achieved top-tier throughput, often surpassing Go's Fiber by up to 5% in plaintext and JSON serialization tests while matching or exceeding many C++ implementations in requests per second under high load.[119][120] For instance, Actix-web handled over 1 million requests per second in optimized plaintext scenarios, benefiting from no runtime allocation overhead beyond explicit needs.[121]| Benchmark Category | Rust (e.g., Actix) Relative to C++ | Rust Relative to Go (e.g., Fiber) | Source |
|---|---|---|---|
| Plaintext Throughput | 90-110% (comparable, varies by framework) | 95-105% (slight edge) | TechEmpower Round 23[119] |
| JSON Serialization | Within 10% | 20-50% faster | TechEmpower Round 23[119] |
| CPU-Bound Compute (e.g., numerical) | 80-95% (C++ optimizer maturity advantage) | 1.5-3x faster (no GC pauses) | Independent comparisons[118] |
Compilation Trade-offs
Rust's compilation process involves monomorphization of generic code, which instantiates specialized versions of functions and types for each concrete use site, enabling zero-overhead abstractions at runtime but incurring significant upfront costs in terms of compile time and generated code volume.[125] This approach contrasts with dynamic dispatch in languages like C++, where virtual functions defer resolution to runtime, but Rust's strategy amplifies compile-time expenses, particularly in projects with heavy generic usage, as each instantiation requires separate optimization passes through LLVM.[126] In practice, this bloat can extend time-to-compile-from-zero (TCOZ) for clean builds from seconds in small programs to minutes or longer in complex crates, with reports of enterprise-scale dependencies pushing full rebuilds to 30-45 minutes before optimizations.[127] Empirical benchmarks reveal Rust's full compile times often align with or exceed those of C++ in large-scale projects, influenced by factors like template instantiation parallels to monomorphization and header inclusion overheads, though Rust's incremental compilation provides faster iterative development cycles.[128][129] Developers report Rust builds in substantial codebases taking comparably to C++ or occasionally 2-5 times longer for initial compiles due to LLVM's role in processing expanded intermediate representations, but mitigations such as sccache for distributed caching, ThinLTO for lighter link-time optimization, and profile-guided optimizations can reduce these by 50-75% in repeated workflows.[130][131] These techniques address the scalability issues but highlight that Rust's pursuit of compile-time safety and performance guarantees is not without developer productivity trade-offs, as prolonged TCOZ disrupts rapid prototyping in expansive systems. The emphasis on monomorphization underscores a deliberate causal trade-off: runtime efficiency gains come at the expense of extended build phases, challenging claims of uniformly "free" high performance when factoring in engineering cycles.[132] While incremental builds mitigate daily friction—often completing in seconds—full recompilations remain a bottleneck in continuous integration pipelines or after major refactors, prompting ongoing Rust compiler team efforts to optimize IR generation and parallelization without compromising guarantees.[133] This realism tempers hype around Rust's ergonomics, as empirical developer feedback consistently flags compile latency as a barrier in adoption for performance-critical domains beyond toy examples.[134]Adoption and Impact
Industry and Open-Source Usage
Discord began incorporating Rust into its backend infrastructure around 2016, initially for high-throughput services like video encoding and real-time communication, citing its ability to handle concurrency without garbage collection overhead while maintaining memory safety guarantees. AWS developed Firecracker, a lightweight virtualization hypervisor for multi-tenant serverless workloads, entirely in Rust starting in 2017, emphasizing reduced code size and attack surface compared to traditional C-based alternatives like QEMU. Microsoft has employed Rust for rewriting select Windows components and Azure services since 2019, focusing on secure systems programming to mitigate vulnerabilities inherent in C and C++ codebases. In cloud and infrastructure, Rust has facilitated replacements for C++ in performance-sensitive domains; for example, AWS's adoption in Firecracker prioritizes isolation and speed for Lambda functions, processing billions of requests daily with fewer security incidents than legacy implementations. Similarly, companies like Cloudflare have integrated Rust for edge computing proxies, leveraging its zero-cost abstractions to outperform C++ in throughput benchmarks while avoiding common buffer overflow errors. Open-source projects highlight Rust's role in CLI utilities as a safer, faster successor to C tools. Ripgrep, released in 2016, serves as a command-line search tool that surpasses GNU grep in speed and regex handling, processing large codebases with parallel execution and without the historical bugs plaguing C implementations. Alacritty, a terminal emulator launched in 2016, utilizes Rust's GPU rendering capabilities for cross-platform efficiency, offering lower latency than C++-based terminals like xterm. Servo, Mozilla's experimental browser engine prototyped in Rust since 2012, has influenced real-world browser development by providing embeddable web rendering components, though its full adoption remains limited to niche integrations rather than wholesale C++ replacements in production browsers. Despite these examples, Rust's open-source footprint in utilities remains specialized, contrasting with Python's broader dominance in scripting and prototyping due to Rust's compile-time rigor.[135]Kernel and Systems-Level Integration
The integration of Rust into the Linux kernel serves as empirical evidence of its suitability for systems-level programming, where memory safety features address common vulnerabilities in C-based code without sacrificing low-level control. Initial experimental support for Rust kernel modules was merged into the mainline Linux kernel on October 3, 2022, as part of version 6.1, enabling the development of drivers and abstractions in Rust alongside the existing C codebase.[6][136] By 2024, Rust had progressed beyond experimentation, with stable drivers upstreamed into the kernel, marking a tipping point for broader adoption. For instance, Linux 6.13, released in late 2024, incorporated infrastructure enhancements that facilitated the merging of production-ready Rust drivers, as noted by kernel maintainer Greg Kroah-Hartman, who emphasized the potential for new code in Rust to benefit overall kernel stability.[137][138] Tools like bindgen play a critical role in this integration by automatically generating Rust foreign function interface (FFI) bindings from C kernel headers, allowing Rust modules to interact seamlessly with the kernel's C APIs while leveraging Rust's type safety for the new components.[139][140] Ongoing efforts include porting core subsystems, but debates persist around complex areas such as the memory management (mm) framework, where Rust's borrow checker aids in preventing use-after-free and double-free errors prevalent in C implementations. However, the kernel's requirements for direct hardware manipulation and performance optimization necessitateunsafe blocks in Rust to bypass safety checks, limiting its ability to fully replace C in performance-critical paths like allocators and page fault handlers. This hybrid approach underscores Rust's causal role in reducing bug classes—empirically validated by fewer memory-related issues in Rust drivers—but highlights that unsafe code introduces verification burdens akin to C's manual management, tempering expectations for wholesale substitution.[141][142][143]
Usage Statistics and Surveys
In the 2025 Stack Overflow Developer Survey, Rust ranked as the most admired programming language among respondents, with 72% expressing a desire to continue using or adopt it, though its share of primary usage among developers remained under 5%.[144] This disparity underscores a persistent gap between enthusiasm for Rust's safety and performance features and its everyday application in broader development workflows. JetBrains' State of Developer Ecosystem report, drawing on 2024 data extended into 2025 analyses, estimated Rust's primary user base at 709,000 developers globally, representing steady but niche adoption amid a total developer population exceeding 28 million.[145] Complementing this, popularity indices like TIOBE and PYPL placed Rust in the 13-20 range through 2025: TIOBE recorded a 1.19% share in October (down 0.25% month-over-month but with prior peaks at #13 in February), while PYPL showed 2.59% in October, ranking it around 10th with flat year-over-year trends from a low baseline of under 2% historically.[146][147] These metrics reflect approximately 33% year-over-year growth in some tracked periods, yet Rust's overall market penetration trails dominant languages like Python (28.97% PYPL share) by orders of magnitude. Enterprise-focused surveys in 2025 highlighted higher relative adoption in specialized domains: 45% of polled organizations reported using Rust in production, often prioritizing it for memory-safe, safety-critical systems over general-purpose tasks.[148] Another analysis noted 38-45% majority usage in enterprise settings for similar high-stakes applications, though this remains concentrated rather than widespread across industries.[149] Such figures contrast with developer surveys, where Rust's appeal drives interest but faces barriers to scaling as a primary tool beyond targeted use cases.Research Contributions
Academic Studies on Safety and Correctness
Several peer-reviewed papers have established formal soundness properties for Rust's borrow checker. A 2024 study introduces a symbolic semantics model (LLBC) for Rust and proves its soundness relative to a low-level operational semantics, demonstrating that the borrow checker rejects programs with potential data races or use-after-free errors while accepting safe ones.[150] This work addresses gaps in prior informal models by providing mechanized proofs that the high-level borrow rules align with low-level pointer behaviors.[151] Deductive verification tools like Creusot extend these foundations by enabling formal proofs of correctness for Rust programs. Introduced in a 2022 paper, Creusot translates Rust code into Why3 for verification, supporting traits and ghost code to prove absence of panics, overflows, and assertion failures in safe Rust subsets.[152] It has been applied to verify parts of the Rust standard library, identifying and resolving potential soundness holes through prophecy variables that model non-deterministic behaviors like memory deallocation.[153] Empirical analyses confirm the borrow checker's effectiveness in reducing memory safety violations. A 2023 study of 128 popular Rust crates found that while unsafe code introduces risks, safe Rust code exhibited zero memory safety bugs, with issues primarily arising from improper unsafe abstractions rather than borrow checker failures.[154] Over the three years prior to 2024, the Rust standard library reported 57 soundness issues and 20 CVEs, predominantly logic errors rather than memory unsafety, underscoring the compile-time guarantees' role in minimizing runtime exploits compared to languages without such checks.[153] Rust's ownership and borrowing model has also advanced programming language theory by practically reviving affine types for resource management. Formalizations show how Rust's regions and lifetimes enable lightweight borrowing of linear data even in aliased contexts, influencing extensions in verification systems for large-scale programs.[155] This bridges theoretical linear logic constructs with deployable systems, proving termination and safety without garbage collection overhead.[156]Innovations in Type Systems and Verification
Rust's ownership model and borrow checker represent a key innovation in type systems, enforcing affine types that track resource lifetimes and prevent mutable aliasing, thereby eliminating entire classes of memory errors such as iterator invalidation and double frees at compile time without garbage collection.[157] This approach, inspired by Cyclone's region system and linear types from academic research, shifts error detection from runtime to static analysis, enabling C++-like performance with guarantees against data races in safe code.[157] However, these mechanisms remain incomplete for verifying arbitrary correctness properties, as unsafe blocks bypass ownership rules and logical bugs persist.[158] Formal verification tools have emerged to address these gaps, extending Rust's type safety to provable correctness. Prusti, developed by ETH Zurich researchers, applies deductive verification techniques from the Iris framework to safe Rust code, automatically generating proofs for loop invariants and functional specifications to ensure absence of panics and adherence to preconditions.[159] Released in 2020 with ongoing advancements, Prusti has verified components of libraries like the Rust standard library, demonstrating scalability for real-world modules up to thousands of lines.[153] Kani, an AWS-originated model checker integrated into Rust since 2022, exhaustively explores execution paths in Rust programs, verifying assertions and properties in both safe and unsafe code via bounded model checking with CBMC backend.[158] Adopted in projects like Linux kernel drivers, Kani detects overflows and concurrency issues missed by the type system alone.[160] Rust's type innovations have spurred research into dependent types, where types can encode value-dependent properties for finer-grained proofs. Const generics, stabilized in Rust 1.51 on March 25, 2021, via RFC 2000, allow generic parameters dependent on constant expressions, enabling compile-time array bounds checks and unit-sized types for dimensions. This partial dependent typing influences designs in languages like Lean and Idris by demonstrating practical usability in systems programming, though full value-dependent types remain experimental in Rust proposals due to inference complexity.[161] Empirical usability studies indicate Rust's advanced types foster transferable habits, such as explicit aliasing awareness, reducing error-prone patterns in developers transitioning from C++ to other languages.[157] A 2024 survey of verification tools confirms Rust's ecosystem leads in bit-precise checking for systems code, outpacing C verifiers in safe subsets.[162]Criticisms and Debates
Steep Learning Curve and Productivity Costs
Rust's ownership model, enforced by the borrow checker, imposes a steep initial learning curve compared to languages like C++, where developers report spending significantly more time resolving compilation errors during early stages of development. Surveys indicate that while 53% of Rust users consider themselves productive as of 2024, 20% can only write simple programs, reflecting persistent challenges for newcomers in mastering concepts like lifetimes and borrowing rules.[163] This friction often leads to frustration, with developers describing the process as "fighting the compiler" due to the borrow checker's strict enforcement, which rejects code that might be permissible in C++ but risks data races or invalid memory access.[164] Anecdotal accounts from programmers highlight extended debugging sessions, where even basic mutations require restructuring data flows to satisfy borrowing constraints.[165] The verbosity of Rust's compiler error messages exacerbates these productivity hurdles, providing detailed explanations that, while informative for experienced users, can overwhelm beginners with multi-paragraph diagnostics spanning lifetimes, trait bounds, and inference failures.[166] This contrasts with C++'s often concise but less explanatory errors, potentially prolonging resolution times; developers note that parsing Rust's output demands familiarity with the language's semantics, turning compilation into an iterative, time-intensive loop rather than rapid prototyping.[167] Empirical comparisons show Rust's development cycles for initial codebases exceeding those in C++ by factors tied to borrow resolution, with larger projects amplifying compile-time delays due to monomorphization and trait resolution.[128] Despite these upfront costs, data suggests long-term gains in maintenance productivity from reduced runtime bugs, as the borrow checker's upfront rejections prevent memory-related defects that plague C++ codebases.[168] Startups adopting Rust have reported slower feature velocity in early phases due to these constraints, prioritizing safety over speed in prototyping.[169] Overall, while initial productivity dips—evident in surveys where proficiency lags behind adoption intent—the model's causal emphasis on compile-time verification yields safer codebases, trading short-term effort for enduring reliability.[163]Technical Limitations and Workarounds
Rust lacks a stable application binary interface (ABI), preventing reliable dynamic linking between Rust crates compiled with different compiler versions or requiring full recompilation of dependent code. This stems from the language's evolving internals, where changes to data layout or calling conventions can break compatibility without compile-time detection. As a result, Rust projects often adopt a monolithic compilation model, bundling all dependencies into a single unit, which exacerbates build times and limits interoperability with other Rust libraries. Workarounds include exposing stable C-compatible ABIs via foreign function interface (FFI) for cross-language use or awaiting ongoing efforts like the proposed modular ABI, though stabilization remains uncertain as of 2024.[170][171][172] Frequent breaking changes, particularly before the introduction of editions in Rust 2015 and 2018, necessitated manual updates across codebases, with even post-edition releases introducing incompatibilities, such as the Rust 1.80 update affecting crates liketime due to altered semantics. Editions mitigate this by allowing opt-in to newer stable features without forcing breakage, but library maintainers must still handle version-specific divergences. Unsafe code serves as a common escape hatch for borrow checker restrictions, enabling low-level manipulations but introducing potential unsafety that undermines Rust's memory safety guarantees; developers often wrap such blocks in audited abstractions to minimize risks.[173][174]
Asynchronous programming in Rust, while providing zero-cost abstractions via async/await, suffers from ergonomic challenges in handling real-world concurrency, including pinning requirements, executor dependencies, and difficulties composing futures without runtime-specific APIs. Unlike synchronous code, async functions cannot be called directly without an executor, leading to fragmented ecosystems with runtimes like Tokio or async-std, and common pitfalls in error handling or cancellation. Developers workaround these by preferring synchronous alternatives where feasible, spawning OS threads for parallelism, or using libraries that abstract runtime differences, though this trades efficiency for simplicity.[124]
Compile times in Rust are prolonged by monomorphization of generics and traits, which generates specialized code for each type instantiation, alongside incremental compilation limitations from whole-program analysis. Heavy trait usage can inflate LLVM IR generation, contributing to code bloat and dependency rebuilds. Mitigation strategies include minimizing generic depth with newtypes or concrete types, enabling linker optimizations like LTO selectively, and structuring crates to reduce interdependency recompilations.[132][175][131]
In performance-critical domains like operating system kernels, Rust's abstractions have led to rejections or limited adoption; for instance, Linux kernel maintainers have restricted Rust to non-core subsystems due to needs for bypassing ownership checks and direct hardware control, favoring C's flexibility despite its vulnerabilities. Projects requiring maximal speed often retain C for its mature optimizations and stable ABI, viewing Rust's safety overhead as incompatible without extensive unsafe wrappers.[141][176][177]