The Rust Programming Language › Appendix B: Operators and Symbols › Operators

| Operator                  | Example                                                 | Explanation                                                           | Overloadable?  |
| ------------------------- | ------------------------------------------------------- | --------------------------------------------------------------------- | -------------- |
| `!`                       | `ident!(...)`, `ident!{...}`, `ident![...]`             | Macro expansion                                                       |                |
| `!`                       | `!expr`                                                 | Bitwise or logical complement                                         | `Not`          |
| `!=`                      | `expr != expr`                                          | Nonequality comparison                                                | `PartialEq`    |
| `%`                       | `expr % expr`                                           | Arithmetic remainder                                                  | `Rem`          |
| `%=`                      | `var %= expr`                                           | Arithmetic remainder and assignment                                   | `RemAssign`    |
| `&`                       | `&expr`, `&mut expr`                                    | Borrow                                                                |                |
| `&`                       | `&type`, `&mut type`, `&'a type`, `&'a mut type`        | Borrowed pointer type                                                 |                |
| `&`                       | `expr & expr`                                           | Bitwise AND                                                           | `BitAnd`       |
| `&=`                      | `var &= expr`                                           | Bitwise AND and assignment                                            | `BitAndAssign` |
| `&&`                      | `expr && expr`                                          | Short-circuiting logical AND                                          |                |
| `*`                       | `expr * expr`                                           | Arithmetic multiplication                                             | `Mul`          |
| `*=`                      | `var *= expr`                                           | Arithmetic multiplication and assignment                              | `MulAssign`    |
| `*`                       | `*expr`                                                 | Dereference                                                           | `Deref`        |
| `*`                       | `*const type`, `*mut type`                              | Raw pointer                                                           |                |
| `+`                       | `trait + trait`, `'a + trait`                           | Compound type constraint                                              |                |
| `+`                       | `expr + expr`                                           | Arithmetic addition                                                   | `Add`          |
| `+=`                      | `var += expr`                                           | Arithmetic addition and assignment                                    | `AddAssign`    |
| `,`                       | `expr, expr`                                            | Argument and element separator                                        |                |
| `-`                       | `- expr`                                                | Arithmetic negation                                                   | `Neg`          |
| `-`                       | `expr - expr`                                           | Arithmetic subtraction                                                | `Sub`          |
| `-=`                      | `var -= expr`                                           | Arithmetic subtraction and assignment                                 | `SubAssign`    |
| `->`                      | `fn(...) -> type`, |...| -> type | Function and closure return type                                      |                |
| `.`                       | `expr.ident`                                            | Field access                                                          |                |
| `.`                       | `expr.ident(expr, ...)`                                 | Method call                                                           |                |
| `.`                       | `expr.0`, `expr.1`, and so on                           | Tuple indexing                                                        |                |
| `..`                      | `..`, `expr..`, `..expr`, `expr..expr`                  | Right-exclusive range literal                                         | `PartialOrd`   |
| `..=`                     | `..=expr`, `expr..=expr`                                | Right-inclusive range literal                                         | `PartialOrd`   |
| `..`                      | `..expr`                                                | Struct literal update syntax                                          |                |
| `..`                      | `variant(x, ..)`, `struct_type { x, .. }`               | “And the rest” pattern binding                                        |                |
| `...`                     | `expr...expr`                                           | (Deprecated, use `..=` instead) In a pattern: inclusive range pattern |                |
| `/`                       | `expr / expr`                                           | Arithmetic division                                                   | `Div`          |
| `/=`                      | `var /= expr`                                           | Arithmetic division and assignment                                    | `DivAssign`    |
| `:`                       | `pat: type`, `ident: type`                              | Constraints                                                           |                |
| `:`                       | `ident: expr`                                           | Struct field initializer                                              |                |
| `:`                       | `'a: loop {...}`                                        | Loop label                                                            |                |
| `;`                       | `expr;`                                                 | Statement and item terminator                                         |                |
| `;`                       | `[...; len]`                                            | Part of fixed-size array syntax                                       |                |
| `<<`                      | `expr << expr`                                          | Left-shift                                                            | `Shl`          |
| `<<=`                     | `var <<= expr`                                          | Left-shift and assignment                                             | `ShlAssign`    |
| `<`                       | `expr < expr`                                           | Less than comparison                                                  | `PartialOrd`   |
| `<=`                      | `expr <= expr`                                          | Less than or equal to comparison                                      | `PartialOrd`   |
| `=`                       | `var = expr`, `ident = type`                            | Assignment/equivalence                                                |                |
| `==`                      | `expr == expr`                                          | Equality comparison                                                   | `PartialEq`    |
| `=>`                      | `pat => expr`                                           | Part of match arm syntax                                              |                |
| `>`                       | `expr > expr`                                           | Greater than comparison                                               | `PartialOrd`   |
| `>=`                      | `expr >= expr`                                          | Greater than or equal to comparison                                   | `PartialOrd`   |
| `>>`                      | `expr >> expr`                                          | Right-shift                                                           | `Shr`          |
| `>>=`                     | `var >>= expr`                                          | Right-shift and assignment                                            | `ShrAssign`    |
| `@`                       | `ident @ pat`                                           | Pattern binding                                                       |                |
| `^`                       | `expr ^ expr`                                           | Bitwise exclusive OR                                                  | `BitXor`       |
| `^=`                      | `var ^= expr`                                           | Bitwise exclusive OR and assignment                                   | `BitXorAssign` |
| |       | pat | pat                             | Pattern alternatives                                                  |                |
| |       | expr | expr                           | Bitwise OR                                                            | `BitOr`        |
| |=      | var |= expr                           | Bitwise OR and assignment                                             | `BitOrAssign`  |
| || | expr || expr                     | Short-circuiting logical OR                                           |                |
| `?`                       | `expr?`                                                 | Error propagation                                                     |                |


The Rust Programming Language › Appendix B: Operators and Symbols › Non-operator Symbols

The following tables contain all symbols that don’t function as operators; that
is, they don’t behave like a function or method call.
Table B-2 shows symbols that appear on their own and are valid in a variety of
locations.
Table B-2: Stand-alone Syntax
| Symbol                                                                 | Explanation                                                            |
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| `'ident`                                                               | Named lifetime or loop label                                           |
| Digits immediately followed by `u8`, `i32`, `f64`, `usize`, and so on  | Numeric literal of specific type                                       |
| `"..."`                                                                | String literal                                                         |
| `r"..."`, `r#"..."#`, `r##"..."##`, and so on                          | Raw string literal; escape characters not processed                    |
| `b"..."`                                                               | Byte string literal; constructs an array of bytes instead of a string  |
| `br"..."`, `br#"..."#`, `br##"..."##`, and so on                       | Raw byte string literal; combination of raw and byte string literal    |
| `'...'`                                                                | Character literal                                                      |
| `b'...'`                                                               | ASCII byte literal                                                     |
| |...| expr                                      | Closure                                                                |
| `!`                                                                    | Always-empty bottom type for diverging functions                       |
| `_`                                                                    | “Ignored” pattern binding; also used to make integer literals readable |
Table B-3 shows symbols that appear in the context of a path through the module
hierarchy to an item.
Table B-3: Path-Related Syntax

Appendix B: Operators and Symbols
Non-operator Symbols


The Rust Programming Language › Appendix B: Operators and Symbols › Non-operator Symbols

| Symbol                                  | Explanation                                                                                |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------|
| `ident::ident`                          | Namespace path                                                                                |
| `::path`                                | Path relative to the crate root (that is, an explicitly absolute path)                                       |
| `self::path`                            | Path relative to the current module (that is, an explicitly relative path)                                   |
| `super::path`                           | Path relative to the parent of the current module                                                            |
| `type::ident`, `<type as trait>::ident` | Associated constants, functions, and types                                                                   |
| `<type>::...`                           | Associated item for a type that cannot be directly named (for example, `<&T>::...`, `<[T]>::...`, and so on) |
| `trait::method(...)`                    | Disambiguating a method call by naming the trait that defines it                                             |
| `type::method(...)`                     | Disambiguating a method call by naming the type for which it’s defined                                       |
| `<type as trait>::method(...)`          | Disambiguating a method call by naming the trait and type                                                    |
Table B-4 shows symbols that appear in the context of using generic type
parameters.
Table B-4: Generics


The Rust Programming Language › Appendix B: Operators and Symbols › Non-operator Symbols

| Symbol                         | Explanation                                                                                |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `path<...>`                    | Specifies parameters to a generic type in a type (for example, `Vec<u8>`)                                                                           |
| `path::<...>`, `method::<...>` | Specifies parameters to a generic type, function, or method in an expression; often referred to as _turbofish_ (for example, `"42".parse::<i32>()`) |
| `fn ident<...> ...`            | Define generic function                                                                                |
| `struct ident<...> ...`        | Define generic structure                                                                                |
| `enum ident<...> ...`          | Define generic enumeration                                                                                |
| `impl<...> ...`                | Define generic implementation                                                                                |
| `for<...> type`                | Higher ranked lifetime bounds                                                                                |
| `type<ident=type>`             | A generic type where one or more associated types have specific assignments (for example, `Iterator<Item=T>`)                                       |
Table B-5 shows symbols that appear in the context of constraining generic type
parameters with trait bounds.
Table B-5: Trait Bound Constraints


The Rust Programming Language › Appendix B: Operators and Symbols › Non-operator Symbols

| Symbol                        | Explanation                                                                                |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `T: U`                        | Generic parameter `T` constrained to types that implement `U`                                                                              |
| `T: 'a`                       | Generic type `T` must outlive lifetime `'a` (meaning the type cannot transitively contain any references with lifetimes shorter than `'a`) |
| `T: 'static`                  | Generic type `T` contains no borrowed references other than `'static` ones                                                                 |
| `'b: 'a`                      | Generic lifetime `'b` must outlive lifetime `'a`                                                                                |
| `T: ?Sized`                   | Allow generic type parameter to be a dynamically sized type                                                                                |
| `'a + trait`, `trait + trait` | Compound type constraint                                                                                |
Table B-6 shows symbols that appear in the context of calling or defining
macros and specifying attributes on an item.
Table B-6: Macros and Attributes
| Symbol                                      | Explanation        |
| ------------------------------------------- | ------------------ |
| `#[meta]`                                   | Outer attribute    |
| `#![meta]`                                  | Inner attribute    |
| `$ident`                                    | Macro substitution |
| `$ident:kind`                               | Macro metavariable |
| `$(...)...`                                 | Macro repetition   |
| `ident!(...)`, `ident!{...}`, `ident![...]` | Macro invocation   |
Table B-7 shows symbols that create comments.
Table B-7: Comments


The Rust Programming Language › Appendix B: Operators and Symbols › Non-operator Symbols

| Symbol     | Explanation             |
| ---------- | ----------------------- |
| `//`       | Line comment            |
| `//!`      | Inner line doc comment  |
| `///`      | Outer line doc comment  |
| `/*...*/`  | Block comment           |
| `/*!...*/` | Inner block doc comment |
| `/**...*/` | Outer block doc comment |
Table B-8 shows the contexts in which parentheses are used.
Table B-8: Parentheses
| Symbol                   | Explanation                                                                                |
| ------------------------ | ------------------------------------------------------------------------------------------- |
| `()`                     | Empty tuple (aka unit), both literal and type                                               |
| `(expr)`                 | Parenthesized expression                                                                    |
| `(expr,)`                | Single-element tuple expression                                                             |
| `(type,)`                | Single-element tuple type                                                                   |
| `(expr, ...)`            | Tuple expression                                                                            |
| `(type, ...)`            | Tuple type                                                                                |
| `expr(expr, ...)`        | Function call expression; also used to initialize tuple `struct`s and tuple `enum` variants |
Table B-9 shows the contexts in which curly brackets are used.
Table B-9: Curly Brackets
| Context      | Explanation      |
| ------------ | ---------------- |
| `{...}`      | Block expression |
| `Type {...}` | Struct literal   |
Table B-10 shows the contexts in which square brackets are used.
Table B-10: Square Brackets


The Rust Programming Language › Appendix B: Operators and Symbols › Non-operator Symbols

| Context                                            | Explanation                                                                                |
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `[...]`                                            | Array literal                                                                                |
| `[expr; len]`                                      | Array literal containing `len` copies of `expr`                                                                               |
| `[type; len]`                                      | Array type containing `len` instances of `type`                                                                               |
| `expr[expr]`                                       | Collection indexing; overloadable (`Index`, `IndexMut`)                                                                       |
| `expr[..]`, `expr[a..]`, `expr[..b]`, `expr[a..b]` | Collection indexing pretending to be collection slicing, using `Range`, `RangeFrom`, `RangeTo`, or `RangeFull` as the “index” |


The Rust Programming Language › Appendix C: Derivable Traits

In various places in the book, we’ve discussed the `derive` attribute, which
you can apply to a struct or enum definition. The `derive` attribute generates
code that will implement a trait with its own default implementation on the
type you’ve annotated with the `derive` syntax.
In this appendix, we provide a reference of all the traits in the standard
library that you can use with `derive`. Each section covers:
- What operators and methods deriving this trait will enable
- What the implementation of the trait provided by `derive` does
- What implementing the trait signifies about the type
- The conditions in which you’re allowed or not allowed to implement the trait
- Examples of operations that require the trait
If you want different behavior from that provided by the `derive` attribute,
consult the standard library documentation
for each trait for details on how to manually implement them.
The traits listed here are the only ones defined by the standard library that
can be implemented on your types using `derive`. Other traits defined in the
standard library don’t have sensible default behavior, so it’s up to you to
implement them in the way that makes sense for what you’re trying to accomplish.
An example of a trait that can’t be derived is `Display`, which handles
formatting for end users. You should always consider the appropriate way to
display a type to an end user. What parts of the type should an end user be
allowed to see? What parts would they find relevant? What format of the data
would be most relevant to them? The Rust compiler doesn’t have this insight, so
it can’t provide appropriate default behavior for you.


The Rust Programming Language › Appendix C: Derivable Traits

The list of derivable traits provided in this appendix is not comprehensive:
Libraries can implement `derive` for their own traits, making the list of
traits you can use `derive` with truly open ended. Implementing `derive`
involves using a procedural macro, which is covered in the “Custom `derive`
Macros” section in Chapter 20.


The Rust Programming Language › Appendix C: Derivable Traits › `Debug` for Programmer Output

The `Debug` trait enables debug formatting in format strings, which you
indicate by adding `:?` within `{}` placeholders.
The `Debug` trait allows you to print instances of a type for debugging
purposes, so you and other programmers using your type can inspect an instance
at a particular point in a program’s execution.
The `Debug` trait is required, for example, in the use of the `assert_eq!`
macro. This macro prints the values of instances given as arguments if the
equality assertion fails so that programmers can see why the two instances
weren’t equal.

Appendix C: Derivable Traits
`Debug` for Programmer Output


The Rust Programming Language › Appendix C: Derivable Traits › `PartialEq` and `Eq` for Equality Comparisons

The `PartialEq` trait allows you to compare instances of a type to check for
equality and enables use of the `==` and `!=` operators.
Deriving `PartialEq` implements the `eq` method. When `PartialEq` is derived on
structs, two instances are equal only if _all_ fields are equal, and the
instances are not equal if _any_ fields are not equal. When derived on enums,
each variant is equal to itself and not equal to the other variants.
The `PartialEq` trait is required, for example, with the use of the
`assert_eq!` macro, which needs to be able to compare two instances of a type
for equality.
The `Eq` trait has no methods. Its purpose is to signal that for every value of
the annotated type, the value is equal to itself. The `Eq` trait can only be
applied to types that also implement `PartialEq`, although not all types that
implement `PartialEq` can implement `Eq`. One example of this is floating-point
number types: The implementation of floating-point numbers states that two
instances of the not-a-number (`NaN`) value are not equal to each other.
An example of when `Eq` is required is for keys in a `HashMap<K, V>` so that
the `HashMap<K, V>` can tell whether two keys are the same.


The Rust Programming Language › Appendix C: Derivable Traits › `PartialOrd` and `Ord` for Ordering Comparisons

The `PartialOrd` trait allows you to compare instances of a type for sorting
purposes. A type that implements `PartialOrd` can be used with the `<`, `>`,
`<=`, and `>=` operators. You can only apply the `PartialOrd` trait to types
that also implement `PartialEq`.
Deriving `PartialOrd` implements the `partial_cmp` method, which returns an
`Option<Ordering>` that will be `None` when the values given don’t produce an
ordering. An example of a value that doesn’t produce an ordering, even though
most values of that type can be compared, is the `NaN` floating point value.
Calling `partial_cmp` with any floating-point number and the `NaN`
floating-point value will return `None`.
When derived on structs, `PartialOrd` compares two instances by comparing the
value in each field in the order in which the fields appear in the struct
definition. When derived on enums, variants of the enum declared earlier in the
enum definition are considered less than the variants listed later.
The `PartialOrd` trait is required, for example, for the `gen_range` method
from the `rand` crate that generates a random value in the range specified by a
range expression.
The `Ord` trait allows you to know that for any two values of the annotated
type, a valid ordering will exist. The `Ord` trait implements the `cmp` method,
which returns an `Ordering` rather than an `Option<Ordering>` because a valid
ordering will always be possible. You can only apply the `Ord` trait to types
that also implement `PartialOrd` and `Eq` (and `Eq` requires `PartialEq`). When
derived on structs and enums, `cmp` behaves the same way as the derived
implementation for `partial_cmp` does with `PartialOrd`.


The Rust Programming Language › Appendix C: Derivable Traits › `PartialOrd` and `Ord` for Ordering Comparisons

An example of when `Ord` is required is when storing values in a `BTreeSet<T>`,
a data structure that stores data based on the sort order of the values.


The Rust Programming Language › Appendix C: Derivable Traits › `Clone` and `Copy` for Duplicating Values

The `Clone` trait allows you to explicitly create a deep copy of a value, and
the duplication process might involve running arbitrary code and copying heap
data. See the “Variables and Data Interacting with
Clone” section in
Chapter 4 for more information on `Clone`.
Deriving `Clone` implements the `clone` method, which when implemented for the
whole type, calls `clone` on each of the parts of the type. This means all the
fields or values in the type must also implement `Clone` to derive `Clone`.
An example of when `Clone` is required is when calling the `to_vec` method on a
slice. The slice doesn’t own the type instances it contains, but the vector
returned from `to_vec` will need to own its instances, so `to_vec` calls
`clone` on each item. Thus, the type stored in the slice must implement `Clone`.
The `Copy` trait allows you to duplicate a value by only copying bits stored on
the stack; no arbitrary code is necessary. See the “Stack-Only Data:
Copy” section in Chapter 4 for more
information on `Copy`.
The `Copy` trait doesn’t define any methods to prevent programmers from
overloading those methods and violating the assumption that no arbitrary code
is being run. That way, all programmers can assume that copying a value will be
very fast.
You can derive `Copy` on any type whose parts all implement `Copy`. A type that
implements `Copy` must also implement `Clone` because a type that implements
`Copy` has a trivial implementation of `Clone` that performs the same task as
`Copy`.
The `Copy` trait is rarely required; types that implement `Copy` have
optimizations available, meaning you don’t have to call `clone`, which makes
the code more concise.


The Rust Programming Language › Appendix C: Derivable Traits › `Clone` and `Copy` for Duplicating Values

Everything possible with `Copy` you can also accomplish with `Clone`, but the
code might be slower or have to use `clone` in places.


The Rust Programming Language › Appendix C: Derivable Traits › `Hash` for Mapping a Value to a Value of Fixed Size

The `Hash` trait allows you to take an instance of a type of arbitrary size and
map that instance to a value of fixed size using a hash function. Deriving
`Hash` implements the `hash` method. The derived implementation of the `hash`
method combines the result of calling `hash` on each of the parts of the type,
meaning all fields or values must also implement `Hash` to derive `Hash`.
An example of when `Hash` is required is in storing keys in a `HashMap<K, V>`
to store data efficiently.


The Rust Programming Language › Appendix C: Derivable Traits › `Default` for Default Values

The `Default` trait allows you to create a default value for a type. Deriving
`Default` implements the `default` function. The derived implementation of the
`default` function calls the `default` function on each part of the type,
meaning all fields or values in the type must also implement `Default` to
derive `Default`.
The `Default::default` function is commonly used in combination with the struct
update syntax discussed in the “Creating Instances from Other Instances with
Struct Update
Syntax”
 section in Chapter 5. You can customize a few fields of a struct and
then set and use a default value for the rest of the fields by using
`..Default::default()`.
The `Default` trait is required when you use the method `unwrap_or_default` on
`Option<T>` instances, for example. If the `Option<T>` is `None`, the method
`unwrap_or_default` will return the result of `Default::default` for the type
`T` stored in the `Option<T>`.

Appendix C: Derivable Traits
`Default` for Default Values


The Rust Programming Language › Appendix D: Useful Development Tools

In this appendix, we talk about some useful development tools that the Rust
project provides. We’ll look at automatic formatting, quick ways to apply
warning fixes, a linter, and integrating with IDEs.


The Rust Programming Language › Appendix D: Useful Development Tools › Automatic Formatting with `rustfmt`

The `rustfmt` tool reformats your code according to the community code style.
Many collaborative projects use `rustfmt` to prevent arguments about which
style to use when writing Rust: Everyone formats their code using the tool.
Rust installations include `rustfmt` by default, so you should already have the
programs `rustfmt` and `cargo-fmt` on your system. These two commands are
analogous to `rustc` and `cargo` in that `rustfmt` allows finer grained control
and `cargo-fmt` understands conventions of a project that uses Cargo. To format
any Cargo project, enter the following:
```console
$ cargo fmt
```
Running this command reformats all the Rust code in the current crate. This
should only change the code style, not the code semantics. For more information
on `rustfmt`, see its documentation.

Appendix D: Useful Development Tools
Automatic Formatting with `rustfmt`


The Rust Programming Language › Appendix D: Useful Development Tools › Fix Your Code with `rustfix`

The `rustfix` tool is included with Rust installations and can automatically
fix compiler warnings that have a clear way to correct the problem that’s
likely what you want. You’ve probably seen compiler warnings before. For
example, consider this code:
Filename: src/main.rs
```rust
fn main() {
    let mut x = 42;
    println!("{x}");
}
```
Here, we’re defining the variable `x` as mutable, but we never actually mutate
it. Rust warns us about that:
```console
$ cargo build
   Compiling myprogram v0.1.0 (file:///projects/myprogram)
warning: variable does not need to be mutable
 --> src/main.rs:2:9
  |
2 |     let mut x = 0;
  |         ----^
  |         |
  |         help: remove this `mut`
  |
  = note: `#[warn(unused_mut)]` on by default
```
The warning suggests that we remove the `mut` keyword. We can automatically
apply that suggestion using the `rustfix` tool by running the command `cargo
fix`:
```console
$ cargo fix
    Checking myprogram v0.1.0 (file:///projects/myprogram)
      Fixing src/main.rs (1 fix)
    Finished dev [unoptimized + debuginfo] target(s) in 0.59s
```
When we look at _src/main.rs_ again, we’ll see that `cargo fix` has changed the
code:
Filename: src/main.rs
```rust
fn main() {
    let x = 42;
    println!("{x}");
}
```
The variable `x` is now immutable, and the warning no longer appears.
You can also use the `cargo fix` command to transition your code between
different Rust editions. Editions are covered in Appendix E
.

Appendix D: Useful Development Tools
Fix Your Code with `rustfix`


The Rust Programming Language › Appendix D: Useful Development Tools › More Lints with Clippy

The Clippy tool is a collection of lints to analyze your code so that you can
catch common mistakes and improve your Rust code. Clippy is included with
standard Rust installations.
To run Clippy’s lints on any Cargo project, enter the following:
```console
$ cargo clippy
```
For example, say you write a program that uses an approximation of a
mathematical constant, such as pi, as this program does:
Listing (src/main.rs)
```rust
fn main() {
    let x = 3.1415;
    let r = 8.0;
    println!("the area of the circle is {}", x * r * r);
}
```
Running `cargo clippy` on this project results in this error:
```text
error: approximate value of `f{32, 64}::consts::PI` found
 --> src/main.rs:2:13
  |
2 |     let x = 3.1415;
  |             ^^^^^^
  |
  = note: `#[deny(clippy::approx_constant)]` on by default
  = help: consider using the constant directly
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
```
This error lets you know that Rust already has a more precise `PI` constant
defined, and that your program would be more correct if you used the constant
instead. You would then change your code to use the `PI` constant.
The following code doesn’t result in any errors or warnings from Clippy:
Listing (src/main.rs)
```rust
fn main() {
    let x = std::f64::consts::PI;
    let r = 8.0;
    println!("the area of the circle is {}", x * r * r);
}
```
For more information on Clippy, see its documentation.

Appendix D: Useful Development Tools
More Lints with Clippy


The Rust Programming Language › Appendix D: Useful Development Tools › IDE Integration Using `rust-analyzer`

To help with IDE integration, the Rust community recommends using
`rust-analyzer`. This tool is a set of
compiler-centric utilities that speak Language Server Protocol
, which is a specification for IDEs and programming languages to
communicate with each other. Different clients can use `rust-analyzer`, such as
the Rust analyzer plug-in for Visual Studio Code.
Visit the `rust-analyzer` project’s home page
for installation instructions, then install the language server support in your
particular IDE. Your IDE will gain capabilities such as autocompletion, jump to
definition, and inline errors.

Appendix D: Useful Development Tools
IDE Integration Using `rust-analyzer`


The Rust Programming Language › Appendix E: Editions

In Chapter 1, you saw that `cargo new` adds a bit of metadata to your
_Cargo.toml_ file about an edition. This appendix talks about what that means!
The Rust language and compiler have a six-week release cycle, meaning users get
a constant stream of new features. Other programming languages release larger
changes less often; Rust releases smaller updates more frequently. After a
while, all of these tiny changes add up. But from release to release, it can be
difficult to look back and say, “Wow, between Rust 1.10 and Rust 1.31, Rust has
changed a lot!”
Every three years or so, the Rust team produces a new Rust _edition_. Each
edition brings together the features that have landed into a clear package with
fully updated documentation and tooling. New editions ship as part of the usual
six-week release process.
Editions serve different purposes for different people:
- For active Rust users, a new edition brings together incremental changes into
  an easy-to-understand package.
- For non-users, a new edition signals that some major advancements have
  landed, which might make Rust worth another look.
- For those developing Rust, a new edition provides a rallying point for the
  project as a whole.
At the time of this writing, four Rust editions are available: Rust 2015, Rust
2018, Rust 2021, and Rust 2024. This book is written using Rust 2024 edition
idioms.
The `edition` key in _Cargo.toml_ indicates which edition the compiler should
use for your code. If the key doesn’t exist, Rust uses `2015` as the edition
value for backward compatibility reasons.


The Rust Programming Language › Appendix E: Editions

Each project can opt in to an edition other than the default 2015 edition.
Editions can contain incompatible changes, such as including a new keyword that
conflicts with identifiers in code. However, unless you opt in to those
changes, your code will continue to compile even as you upgrade the Rust
compiler version you use.
All Rust compiler versions support any edition that existed prior to that
compiler’s release, and they can link crates of any supported editions
together. Edition changes only affect the way the compiler initially parses
code. Therefore, if you’re using Rust 2015 and one of your dependencies uses
Rust 2018, your project will compile and be able to use that dependency. The
opposite situation, where your project uses Rust 2018 and a dependency uses
Rust 2015, works as well.
To be clear: Most features will be available on all editions. Developers using
any Rust edition will continue to see improvements as new stable releases are
made. However, in some cases, mainly when new keywords are added, some new
features might only be available in later editions. You will need to switch
editions if you want to take advantage of such features.
For more details, see _The Rust Edition Guide_. This is a
complete book that enumerates the differences between editions and explains how
to automatically upgrade your code to a new edition via `cargo fix`.


The Rust Programming Language › Appendix F: Translations of the Book

For resources in languages other than English. Most are still in progress; see
the Translations label to help or let us know about a new translation!


The Rust Programming Language › Appendix F: Translations of the Book

- Português (BR)
- Português (PT)
- 简体中文: KaiserY/trpl-zh-cn, gnu4cn/rust-lang-Zh_CN
- 正體中文
- Українська
- Español, alternate, Español por RustLangES
- Русский
- 한국어
- 日本語
- Français
- Polski
- Cebuano
- Tagalog
- Esperanto
- ελληνική
- Svenska
- Farsi, Persian (FA)
- Deutsch
- हिंदी
- ไทย
- Danske
- O'zbek
- Tiếng Việt
- Italiano
- বাংলা


The Rust Programming Language › Appendix G - How Rust is Made and “Nightly Rust”

This appendix is about how Rust is made and how that affects you as a Rust
developer.


The Rust Programming Language › Appendix G - How Rust is Made and “Nightly Rust” › Stability Without Stagnation

As a language, Rust cares a _lot_ about the stability of your code. We want
Rust to be a rock-solid foundation you can build on, and if things were
constantly changing, that would be impossible. At the same time, if we can’t
experiment with new features, we may not find out important flaws until after
their release, when we can no longer change things.
Our solution to this problem is what we call “stability without stagnation”,
and our guiding principle is this: you should never have to fear upgrading to a
new version of stable Rust. Each upgrade should be painless, but should also
bring you new features, fewer bugs, and faster compile times.


The Rust Programming Language › Appendix G - How Rust is Made and “Nightly Rust” › Choo, Choo! Release Channels and Riding the Trains

Rust development operates on a _train schedule_. That is, all development is
done in the main branch of the Rust repository. Releases follow a software
release train model, which has been used by Cisco IOS and other software
projects. There are three _release channels_ for Rust:
- Nightly
- Beta
- Stable
Most Rust developers primarily use the stable channel, but those who want to
try out experimental new features may use nightly or beta.
Here’s an example of how the development and release process works: let’s
assume that the Rust team is working on the release of Rust 1.5. That release
happened in December of 2015, but it will provide us with realistic version
numbers. A new feature is added to Rust: a new commit lands on the main
branch. Each night, a new nightly version of Rust is produced. Every day is a
release day, and these releases are created by our release infrastructure
automatically. So as time passes, our releases look like this, once a night:
```text
nightly: * - - * - - *
```
Every six weeks, it’s time to prepare a new release! The `beta` branch of the
Rust repository branches off from the main branch used by nightly. Now,
there are two releases:
```text
nightly: * - - * - - *
                     |
beta:                *
```
Most Rust users do not use beta releases actively, but test against beta in
their CI system to help Rust discover possible regressions. In the meantime,
there’s still a nightly release every night:
```text
nightly: * - - * - - * - - * - - *
                     |
beta:                *
```


The Rust Programming Language › Appendix G - How Rust is Made and “Nightly Rust” › Choo, Choo! Release Channels and Riding the Trains

Let’s say a regression is found. Good thing we had some time to test the beta
release before the regression snuck into a stable release! The fix is applied
to the main branch, so that nightly is fixed, and then the fix is backported to
the `beta` branch, and a new release of beta is produced:
```text
nightly: * - - * - - * - - * - - * - - *
                     |
beta:                * - - - - - - - - *
```
Six weeks after the first beta was created, it’s time for a stable release! The
`stable` branch is produced from the `beta` branch:
```text
nightly: * - - * - - * - - * - - * - - * - * - *
                     |
beta:                * - - - - - - - - *
                                       |
stable:                                *
```
Hooray! Rust 1.5 is done! However, we’ve forgotten one thing: because the six
weeks have gone by, we also need a new beta of the _next_ version of Rust, 1.6.
So after `stable` branches off of `beta`, the next version of `beta` branches
off of `nightly` again:
```text
nightly: * - - * - - * - - * - - * - - * - * - *
                     |                         |
beta:                * - - - - - - - - *       *
                                       |
stable:                                *
```
This is called the “train model” because every six weeks, a release “leaves the
station”, but still has to take a journey through the beta channel before it
arrives as a stable release.


The Rust Programming Language › Appendix G - How Rust is Made and “Nightly Rust” › Choo, Choo! Release Channels and Riding the Trains

Rust releases every six weeks, like clockwork. If you know the date of one Rust
release, you can know the date of the next one: it’s six weeks later. A nice
aspect of having releases scheduled every six weeks is that the next train is
coming soon. If a feature happens to miss a particular release, there’s no need
to worry: another one is happening in a short time! This helps reduce pressure
to sneak possibly unpolished features in close to the release deadline.
Thanks to this process, you can always check out the next build of Rust and
verify for yourself that it’s easy to upgrade to: if a beta release doesn’t
work as expected, you can report it to the team and get it fixed before the
next stable release happens! Breakage in a beta release is relatively rare, but
`rustc` is still a piece of software, and bugs do exist.


The Rust Programming Language › Appendix G - How Rust is Made and “Nightly Rust” › Maintenance time

The Rust project supports the most recent stable version. When a new stable
version is released, the old version reaches its end of life (EOL). This means
each version is supported for six weeks.


The Rust Programming Language › Appendix G - How Rust is Made and “Nightly Rust” › Unstable Features

There’s one more catch with this release model: unstable features. Rust uses a
technique called “feature flags” to determine what features are enabled in a
given release. If a new feature is under active development, it lands on the
main branch, and therefore, in nightly, but behind a _feature flag_. If you, as
a user, wish to try out the work-in-progress feature, you can, but you must be
using a nightly release of Rust and annotate your source code with the
appropriate flag to opt in.
If you’re using a beta or stable release of Rust, you can’t use any feature
flags. This is the key that allows us to get practical use with new features
before we declare them stable forever. Those who wish to opt into the bleeding
edge can do so, and those who want a rock-solid experience can stick with
stable and know that their code won’t break. Stability without stagnation.
This book only contains information about stable features, as in-progress
features are still changing, and surely they’ll be different between when this
book was written and when they get enabled in stable builds. You can find
documentation for nightly-only features online.


The Rust Programming Language › Appendix G - How Rust is Made and “Nightly Rust” › Rustup and the Role of Rust Nightly

Rustup makes it easy to change between different release channels of Rust, on a
global or per-project basis. By default, you’ll have stable Rust installed. To
install nightly, for example:
```console
$ rustup toolchain install nightly
```
You can see all of the _toolchains_ (releases of Rust and associated
components) you have installed with `rustup` as well. Here’s an example on one
of your authors’ Windows computer:
```powershell
rustup toolchain list
stable-x86_64-pc-windows-msvc (default)
beta-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc
```
As you can see, the stable toolchain is the default. Most Rust users use stable
most of the time. You might want to use stable most of the time, but use
nightly on a specific project, because you care about a cutting-edge feature.
To do so, you can use `rustup override` in that project’s directory to set the
nightly toolchain as the one `rustup` should use when you’re in that directory:
```console
$ cd ~/projects/needs-nightly
$ rustup override set nightly
```
Now, every time you call `rustc` or `cargo` inside of
_~/projects/needs-nightly_, `rustup` will make sure that you are using nightly
Rust, rather than your default of stable Rust. This comes in handy when you
have a lot of Rust projects!


The Rust Programming Language › Appendix G - How Rust is Made and “Nightly Rust” › The RFC Process and Teams

So how do you learn about these new features? Rust’s development model follows
a _Request For Comments (RFC) process_. If you’d like an improvement in Rust,
you can write up a proposal, called an RFC.
Anyone can write RFCs to improve Rust, and the proposals are reviewed and
discussed by the Rust team, which is comprised of many topic subteams. There’s
a full list of the teams on Rust’s website, which includes teams for
each area of the project: language design, compiler implementation,
infrastructure, documentation, and more. The appropriate team reads the
proposal and the comments, writes some comments of their own, and eventually,
there’s consensus to accept or reject the feature.
If the feature is accepted, an issue is opened on the Rust repository, and
someone can implement it. The person who implements it very well may not be the
person who proposed the feature in the first place! When the implementation is
ready, it lands on the main branch behind a feature gate, as we discussed in
the “Unstable Features” section.
After some time, once Rust developers who use nightly releases have been able
to try out the new feature, team members will discuss the feature, how it’s
worked out on nightly, and decide if it should make it into stable Rust or not.
If the decision is to move forward, the feature gate is removed, and the
feature is now considered stable! It rides the trains into a new stable release
of Rust.


The Rustonomicon › The Rustonomicon

<div class="warning">
Warning:
This book is incomplete.
Documenting everything and rewriting outdated parts take a while.
See the [issue tracker] to check what's missing/outdated, and if there are any mistakes or ideas that haven't been reported, feel free to open a new issue there.
</div>


The Rustonomicon › The Rustonomicon › The Dark Arts of Unsafe Rust

THE KNOWLEDGE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF UNLEASHING INDESCRIBABLE HORRORS THAT SHATTER YOUR PSYCHE AND SET YOUR MIND ADRIFT IN THE UNKNOWABLY INFINITE COSMOS.
The Rustonomicon digs into all the awful details that you need to understand when writing Unsafe Rust programs.
Should you wish a long and happy career of writing Rust programs, you should turn back now and forget you ever saw this book.
It is not necessary.
However if you intend to write unsafe code — or just want to dig into the guts of the language — this book contains lots of useful information.
Unlike *The Rust Programming Language*, we will be assuming considerable prior knowledge.
In particular, you should be comfortable with basic systems programming and Rust.
If you don't feel comfortable with these topics, you should consider reading The Book first.
That said, we won't assume you have read it, and we will take care to occasionally give a refresher on the basics where appropriate.
You can skip straight to this book if you want; just know that we won't be explaining everything from the ground up.
This book exists primarily as a high-level companion to The Reference.
Where The Reference exists to detail the syntax and semantics of every part of the language, The Rustonomicon exists to describe how to use those pieces together, and the issues that you will have in doing so.
The Reference will tell you the syntax and semantics of references, destructors, and unwinding, but it won't tell you how combining them can lead to exception-safety issues, or how to deal with those issues.

The Rustonomicon
The Dark Arts of Unsafe Rust


The Rustonomicon › The Rustonomicon › The Dark Arts of Unsafe Rust

It should be noted that we haven't synced The Rustnomicon and The Reference well, so they may have duplicate content.
In general, if the two documents disagree, The Reference should be assumed to be correct (it isn't yet considered normative, it's just better maintained).
Topics that are within the scope of this book include: the meaning of (un)safety, unsafe primitives provided by the language and standard library, techniques for creating safe abstractions with those unsafe primitives, subtyping and variance, exception-safety (panic/unwind-safety), working with uninitialized memory, type punning, concurrency, interoperating with other languages (FFI), optimization tricks, how constructs lower to compiler/OS/hardware primitives, how to **not** make the memory model people angry, how you're **going** to make the memory model people angry, and more.
The Rustonomicon is not a place to exhaustively describe the semantics and guarantees of every single API in the standard library, nor is it a place to exhaustively describe every feature of Rust.
Unless otherwise noted, Rust code in this book uses the Rust 2024 edition.


The Rustonomicon › Meet Safe and Unsafe

safe and unsafe
It would be great to not have to worry about low-level implementation details.
Who could possibly care how much space the empty tuple occupies? Sadly, it
sometimes matters and we need to worry about it. The most common reason
developers start to care about implementation details is performance, but more
importantly, these details can become a matter of correctness when interfacing
directly with hardware, operating systems, or other languages.
When implementation details start to matter in a safe programming language,
programmers usually have three options:
* fiddle with the code to encourage the compiler/runtime to perform an optimization
* adopt a more unidiomatic or cumbersome design to get the desired implementation
* rewrite the implementation in a language that lets you deal with those details
For that last option, the language programmers tend to use is *C*. This is often
necessary to interface with systems that only declare a C interface.
Unfortunately, C is incredibly unsafe to use (sometimes for good reason),
and this unsafety is magnified when trying to interoperate with another
language. Care must be taken to ensure C and the other language agree on
what's happening, and that they don't step on each other's toes.
So what does this have to do with Rust?
Well, unlike C, Rust is a safe programming language.
But, like C, Rust is an unsafe programming language.
More accurately, Rust *contains* both a safe and unsafe programming language.
Rust can be thought of as a combination of two programming languages: *Safe
Rust* and *Unsafe Rust*. Conveniently, these names mean exactly what they say:
Safe Rust is Safe. Unsafe Rust is, well, not. In fact, Unsafe Rust lets us
do some *really* unsafe things. Things the Rust authors will implore you not to
do, but we'll do anyway.


The Rustonomicon › Meet Safe and Unsafe

Safe Rust is the *true* Rust programming language. If all you do is write Safe
Rust, you will never have to worry about type-safety or memory-safety. You will
never endure a dangling pointer, a use-after-free, or any other kind of
Undefined Behavior (a.k.a. UB).
The standard library also gives you enough utilities out of the box that you'll
be able to write high-performance applications and libraries in pure idiomatic
Safe Rust.
But maybe you want to talk to another language. Maybe you're writing a
low-level abstraction not exposed by the standard library. Maybe you're
*writing* the standard library (which is written entirely in Rust). Maybe you
need to do something the type-system doesn't understand and just *frob some dang
bits*. Maybe you need Unsafe Rust.
Unsafe Rust is exactly like Safe Rust with all the same rules and semantics.
It just lets you do some *extra* things that are Definitely Not Safe
(which we will define in the next section).
The value of this separation is that we gain the benefits of using an unsafe
language like C — low level control over implementation details — without most
of the problems that come with trying to integrate it with a completely
different safe language.
There are still some problems — most notably, we must become aware of properties
that the type system assumes and audit them in any code that interacts with
Unsafe Rust. That's the purpose of this book: to teach you about these assumptions
and how to manage them.


The Rustonomicon › How Safe and Unsafe Interact

What's the relationship between Safe Rust and Unsafe Rust? How do they
interact?
The separation between Safe Rust and Unsafe Rust is controlled with the
`unsafe` keyword, which acts as an interface from one to the other. This is
why we can say Safe Rust is a safe language: all the unsafe parts are kept
exclusively behind the `unsafe` boundary. If you wish, you can even toss
`#![forbid(unsafe_code)]` into your code base to statically guarantee that
you're only writing Safe Rust.
The `unsafe` keyword has two uses: to declare the existence of contracts the
compiler can't check, and to declare that a programmer has checked that these
contracts have been upheld.
You can use `unsafe` to indicate the existence of unchecked contracts on
_functions_ and _trait declarations_. On functions, `unsafe` means that
users of the function must check that function's documentation to ensure
they are using it in a way that maintains the contracts the function
requires. On trait declarations, `unsafe` means that implementors of the
trait must check the trait documentation to ensure their implementation
maintains the contracts the trait requires.
You can use `unsafe` on a block to declare that all unsafe actions performed
within are verified to uphold the contracts of those operations. For instance,
the index passed to `slice::get_unchecked` is in-bounds.
You can use `unsafe` on a trait implementation to declare that the implementation
upholds the trait's contract. For instance, that a type implementing [`Send`] is
really safe to move to another thread.
The standard library has a number of unsafe functions, including:


The Rustonomicon › How Safe and Unsafe Interact

* `slice::get_unchecked`, which performs unchecked indexing,
  allowing memory safety to be freely violated.
* `mem::transmute` reinterprets some value as having a given type,
  bypassing type safety in arbitrary ways (see [conversions] for details).
* Every raw pointer to a sized type has an `offset` method that
  invokes Undefined Behavior if the passed offset is not "in bounds".
* All FFI (Foreign Function Interface) functions are `unsafe` to call because the
  other language can do arbitrary operations that the Rust compiler can't check.
As of Rust 1.29.2, the standard library defines the following unsafe traits
(there are others, but they are not stabilized yet and some of them may never
be):
* [`Send`] is a marker trait (a trait with no API) that promises implementors
  are safe to send (move) to another thread.
* [`Sync`] is a marker trait that promises threads can safely share implementors
  through a shared reference.
* [`GlobalAlloc`] allows customizing the memory allocator of the whole program.
Much of the Rust standard library also uses Unsafe Rust internally. These
implementations have generally been rigorously manually checked, so the Safe Rust
interfaces built on top of these implementations can be assumed to be safe.
The need for all of this separation boils down to a single fundamental property
of Safe Rust, the *soundness property*:
**No matter what, Safe Rust clients can't cause Undefined Behavior.**
The design of the safe/unsafe split means that there is an asymmetric trust
relationship between Safe and Unsafe Rust. Safe Rust inherently has to
trust that any Unsafe Rust it touches has been written correctly.
On the other hand, Unsafe Rust cannot trust Safe Rust without care. It can
trust Safe Rust it is a client of, but it cannot trust Safe Rust chosen or
supplied by its clients.


The Rustonomicon › How Safe and Unsafe Interact

As an example, Rust has the [`PartialOrd`] and [`Ord`] traits to differentiate
between types which can "just" be compared, and those that provide a "total"
ordering (which basically means that comparison behaves reasonably).
[`BTreeMap`] doesn't really make sense for partially-ordered types, and so it
requires that its keys implement `Ord`. However, `BTreeMap` has Unsafe Rust code
inside of its implementation. Because it would be unacceptable for a sloppy `Ord`
implementation (which is Safe to write) to cause Undefined Behavior, the Unsafe
code in BTreeMap must be written to be robust against `Ord` implementations which
aren't actually total — even though that's the whole point of requiring `Ord`.
The Unsafe Rust code just can't trust the Safe Rust code to be written correctly.
That said, `BTreeMap` will still behave completely erratically if you feed in
values that don't have a total ordering. It just won't ever cause Undefined
Behavior.
One may wonder, if `BTreeMap` cannot trust `Ord` because it's Safe, why can it
trust *any* Safe code? For instance `BTreeMap` relies on integers and slices to
be implemented correctly. Those are safe too, right?
The difference is one of scope. When `BTreeMap` relies on integers and slices,
it's relying on one very specific implementation. This is a measured risk that
can be weighed against the benefit. In this case there's basically zero risk;
if integers and slices are broken, *everyone* is broken. Also, they're maintained
by the same people who maintain `BTreeMap`, so it's easy to keep tabs on them.


The Rustonomicon › How Safe and Unsafe Interact

The same can be true across crate boundaries. Say crate `foo` depends on crate
`bar`, then Unsafe Rust in crate `foo` may trust Safe Rust in crate `bar`. This
is because crate `foo` chose to depend on crate `bar`, and by doing so trusted
crate `bar` to be implemented correctly.
On the other hand, `BTreeMap`'s key type is generic. Trusting its `Ord`
implementation means trusting the `Ord` implementation of arbitrary clients.
Here the risk is high: someone somewhere is going to make a mistake and mess up
their `Ord` implementation, or even just straight up lie about providing a total
ordering because "it seems to work". When that happens, `BTreeMap` needs to be
prepared.
The same logic applies to trusting a closure that's passed to you to behave
correctly.
This problem of unbounded generic trust is the problem that `unsafe` traits
exist to resolve. The `BTreeMap` type could theoretically require that keys
implement a new trait called `UnsafeOrd`, rather than `Ord`, that might look
like this:
```rust
use std::cmp::Ordering;

unsafe trait UnsafeOrd {
    fn cmp(&self, other: &Self) -> Ordering;
}
```
Then, a type would use `unsafe` to implement `UnsafeOrd`, indicating that
they've ensured their implementation maintains whatever contracts the
trait expects. In this situation, the Unsafe Rust in the internals of
`BTreeMap` would be justified in trusting that the key type's `UnsafeOrd`
implementation is correct. If it isn't, it's the fault of the unsafe trait
implementation, which is consistent with Rust's safety guarantees.


The Rustonomicon › How Safe and Unsafe Interact

The decision of whether to mark a trait `unsafe` is an API design choice. A
safe trait is easier to implement, but any unsafe code that relies on it must
defend against incorrect behavior. Marking a trait `unsafe` shifts this
responsibility to the implementor. Rust has traditionally avoided marking
traits `unsafe` because it makes Unsafe Rust pervasive, which isn't desirable.
`Send` and `Sync` are marked unsafe because thread safety is a *fundamental
property* that unsafe code can't possibly hope to defend against in the way it
could defend against a buggy `Ord` implementation. Similarly, `GlobalAlloc`
is keeping accounts of all the memory in the program and other things like
`Box` or `Vec` that build on top of it. If it does something weird (giving the same
chunk of memory to another request when it is still in use), there's no chance
to detect that and do anything about it.
The decision of whether to mark your own traits `unsafe` depends on the same
sort of consideration. If `unsafe` code can't reasonably expect to defend
against a broken implementation of the trait, then marking the trait `unsafe` is
a reasonable choice.
As an aside, while `Send` and `Sync` are `unsafe` traits, they are *also*
automatically implemented for types when such derivations are provably safe
to do. `Send` is automatically derived for all types composed only of values
whose types also implement `Send`. `Sync` is automatically derived for all
types composed only of values whose types also implement `Sync`. This minimizes
the pervasive unsafety of making these two traits `unsafe`. And not many people
are going to *implement* memory allocators (or use them directly, for that
matter).


The Rustonomicon › How Safe and Unsafe Interact

This is the balance between Safe and Unsafe Rust. The separation is designed to
make using Safe Rust as ergonomic as possible, but requires extra effort and
care when writing Unsafe Rust. The rest of this book is largely a discussion
of the sort of care that must be taken, and what contracts Unsafe Rust must uphold.


The Rustonomicon › What Unsafe Rust Can Do

The only things that are different in Unsafe Rust are that you can:
* Dereference raw pointers
* Call `unsafe` functions (including C functions, compiler intrinsics, and the raw allocator)
* Implement `unsafe` traits
* Access or modify mutable statics
* Access fields of `union`s
That's it. The reason these operations are relegated to Unsafe is that misusing
any of these things will cause the ever dreaded Undefined Behavior. Invoking
Undefined Behavior gives the compiler full rights to do arbitrarily bad things
to your program. You definitely *should not* invoke Undefined Behavior.
Unlike C, Undefined Behavior is pretty limited in scope in Rust. All the core
language cares about is preventing the following things:


The Rustonomicon › What Unsafe Rust Can Do

* Dereferencing (using the `*` operator on) dangling or unaligned pointers (see below)
* Breaking the pointer aliasing rules
* Calling a function with the wrong call ABI or unwinding from a function with the wrong unwind ABI.
* Causing a data race
* Executing code compiled with target features that the current thread of execution does
  not support
* Producing invalid values (either alone or as a field of a compound type such
  as `enum`/`struct`/array/tuple):
  * a `bool` that isn't 0 or 1
  * an `enum` with an invalid discriminant
  * a null `fn` pointer
  * a `char` outside the ranges [0x0, 0xD7FF] and [0xE000, 0x10FFFF]
  * a `!` (all values are invalid for this type)
  * an integer (`i*`/`u*`), floating point value (`f*`), or raw pointer read from
    uninitialized memory, or uninitialized memory in a `str`.
  * a reference/`Box` that is dangling, unaligned, or points to an invalid value.
  * a wide reference, `Box`, or raw pointer that has invalid metadata:
    * `dyn Trait` metadata is invalid if it is not a pointer to a vtable for
      `Trait` that matches the actual dynamic trait the pointer or reference points to
    * slice metadata is invalid if the length is not a valid `usize`
      (i.e., it must not be read from uninitialized memory)
  * a type with custom invalid values that is one of those values, such as a
    [`NonNull`] that is null. (Requesting custom invalid values is an unstable
    feature, but some stable libstd types, like `NonNull`, make use of it.)


The Rustonomicon › What Unsafe Rust Can Do

For a more detailed explanation about "Undefined Behavior", you may refer to
the reference.
"Producing" a value happens any time a value is assigned, passed to a
function/primitive operation or returned from a function/primitive operation.
A reference/pointer is "dangling" if it is null or not all of the bytes it
points to are part of the same allocation (so in particular they all have to be
part of *some* allocation). The span of bytes it points to is determined by the
pointer value and the size of the pointee type. As a consequence, if the span is
empty, "dangling" is the same as "null". Note that slices and strings point
to their entire range, so it's important that the length metadata is never too
large (in particular, allocations and therefore slices and strings cannot be
bigger than `isize::MAX` bytes). If for some reason this is too cumbersome,
consider using raw pointers.
That's it. That's all the causes of Undefined Behavior baked into Rust. Of
course, unsafe functions and traits are free to declare arbitrary other
constraints that a program must maintain to avoid Undefined Behavior. For
instance, the allocator APIs declare that deallocating unallocated memory is
Undefined Behavior.
However, violations of these constraints generally will just transitively lead to one of
the above problems. Some additional constraints may also derive from compiler
intrinsics that make special assumptions about how code can be optimized. For instance,
Vec and Box make use of intrinsics that require their pointers to be non-null at all times.
Rust is otherwise quite permissive with respect to other dubious operations.
Rust considers it "safe" to:
* Deadlock
* Have a race condition
* Leak memory
* Overflow integers (with the built-in operators such as `+` etc.)
* Abort the program
* Delete the production database


The Rustonomicon › What Unsafe Rust Can Do

For more detailed information, you may refer to the reference.
However any program that actually manages to do such a thing is *probably*
incorrect. Rust provides lots of tools to make these things rare, but
these problems are considered impractical to categorically prevent.


The Rustonomicon › Working with Unsafe

Rust generally only gives us the tools to talk about Unsafe Rust in a scoped and
binary manner. Unfortunately, reality is significantly more complicated than
that. For instance, consider the following toy function:
```rust
fn index(idx: usize, arr: &[u8]) -> Option<u8> {
    if idx < arr.len() {
        unsafe {
            Some(*arr.get_unchecked(idx))
        }
    } else {
        None
    }
}
```
This function is safe and correct. We check that the index is in bounds, and if
it is, index into the array in an unchecked manner. We say that such a correct
unsafely implemented function is *sound*, meaning that safe code cannot cause
Undefined Behavior through it (which, remember, is the single fundamental
property of Safe Rust).
But even in such a trivial function, the scope of the unsafe block is
questionable. Consider changing the `<` to a `<=`:
```rust
fn index(idx: usize, arr: &[u8]) -> Option<u8> {
    if idx <= arr.len() {
        unsafe {
            Some(*arr.get_unchecked(idx))
        }
    } else {
        None
    }
}
```
This program is now *unsound*, Safe Rust can cause Undefined Behavior, and yet
*we only modified safe code*. This is the fundamental problem of safety: it's
non-local. The soundness of our unsafe operations necessarily depends on the
state established by otherwise "safe" operations.
Safety is modular in the sense that opting into unsafety doesn't require you
to consider arbitrary other kinds of badness. For instance, doing an unchecked
index into a slice doesn't mean you suddenly need to worry about the slice being
null or containing uninitialized memory. Nothing fundamentally changes. However
safety *isn't* modular in the sense that programs are inherently stateful and
your unsafe operations may depend on arbitrary other state.


The Rustonomicon › Working with Unsafe

This non-locality gets much worse when we incorporate actual persistent state.
Consider a simple implementation of `Vec`:
```rust
use std::ptr;

// Note: This definition is naive. See the chapter on implementing Vec.
pub struct Vec<T> {
    ptr: *mut T,
    len: usize,
    cap: usize,
}

// Note this implementation does not correctly handle zero-sized types.
// See the chapter on implementing Vec.
impl<T> Vec<T> {
    pub fn push(&mut self, elem: T) {
        if self.len == self.cap {
            // not important for this example
            self.reallocate();
        }
        unsafe {
            ptr::write(self.ptr.add(self.len), elem);
            self.len += 1;
        }
    }
    # fn reallocate(&mut self) { }
}

```
This code is simple enough to reasonably audit and informally verify. Now consider
adding the following method:
```rust,ignore
fn make_room(&mut self) {
    // grow the capacity
    self.cap += 1;
}
```
This code is 100% Safe Rust but it is also completely unsound. Changing the
capacity violates the invariants of Vec (that `cap` reflects the allocated space
in the Vec). This is not something the rest of Vec can guard against. It *has*
to trust the capacity field because there's no way to verify it.
Because it relies on invariants of a struct field, this `unsafe` code
does more than pollute a whole function: it pollutes a whole *module*.
Generally, the only bullet-proof way to limit the scope of unsafe code is at the
module boundary with privacy.


The Rustonomicon › Working with Unsafe

However this works *perfectly*. The existence of `make_room` is *not* a
problem for the soundness of Vec because we didn't mark it as public. Only the
module that defines this function can call it. Also, `make_room` directly
accesses the private fields of Vec, so it can only be written in the same module
as Vec.
It is therefore possible for us to write a completely safe abstraction that
relies on complex invariants. This is *critical* to the relationship between
Safe Rust and Unsafe Rust.
We have already seen that Unsafe code must trust *some* Safe code, but shouldn't
trust *generic* Safe code. Privacy is important to unsafe code for similar reasons:
it prevents us from having to trust all the safe code in the universe from messing
with our trusted state.
Safety lives!


The Rustonomicon › Data Representation in Rust

Low-level programming cares a lot about data layout. It's a big deal. It also
pervasively influences the rest of the language, so we're going to start by
digging into how data is represented in Rust.
This chapter is ideally in agreement with, and rendered redundant by,
the Type Layout section of the Reference. When this
book was first written, the reference was in complete disrepair, and the
Rustonomicon was attempting to serve as a partial replacement for the reference.
This is no longer the case, so this whole chapter can ideally be deleted.
We'll keep this chapter around for a bit longer, but ideally you should be
contributing any new facts or improvements to the Reference instead.


The Rustonomicon › repr(Rust)

First and foremost, all types have an alignment specified in bytes. The
alignment of a type specifies what addresses are valid to store the value at. A
value with alignment `n` must only be stored at an address that is a multiple of
`n`. So alignment 2 means you must be stored at an even address, and 1 means
that you can be stored anywhere. Alignment is at least 1, and always a power
of 2.
Primitives are usually aligned to their size, although this is
platform-specific behavior. For example, on x86 `u64` and `f64` are often
aligned to 4 bytes (32 bits).
A type's size must always be a multiple of its alignment (Zero being a valid size
for any alignment). This ensures that an array of that type may always be indexed
by offsetting by a multiple of its size. Note that the size and alignment of a
type may not be known statically in the case of dynamically sized types.
Rust gives you the following ways to lay out composite data:
* structs (named product types)
* tuples (anonymous product types)
* arrays (homogeneous product types)
* enums (named sum types -- tagged unions)
* unions (untagged unions)
An enum is said to be *field-less* if none of its variants have associated data.
By default, composite structures have an alignment equal to the maximum
of their fields' alignments. Rust will consequently insert padding where
necessary to ensure that all fields are properly aligned and that the overall
type's size is a multiple of its alignment. For instance:
```rust
struct A {
    a: u8,
    b: u32,
    c: u16,
}
```
will be 32-bit aligned on a target that aligns these primitives to their
respective sizes. The whole struct will therefore have a size that is a multiple
of 32-bits. It may become:


The Rustonomicon › repr(Rust)

```rust
struct A {
    a: u8,
    _pad1: [u8; 3], // to align `b`
    b: u32,
    c: u16,
    _pad2: [u8; 2], // to make overall size multiple of 4
}
```
or maybe:
```rust
struct A {
    b: u32,
    c: u16,
    a: u8,
    _pad: u8,
}
```
There is *no indirection* for these types; all data is stored within the struct,
as you would expect in C. However with the exception of arrays (which are
densely packed and in-order), the layout of data is not specified by default.
Given the two following struct definitions:
```rust
struct A {
    a: i32,
    b: u64,
}

struct B {
    a: i32,
    b: u64,
}
```
Rust *does* guarantee that two instances of A have their data laid out in
exactly the same way. However Rust *does not* currently guarantee that an
instance of A has the same field ordering or padding as an instance of B.
With A and B as written, this point would seem to be pedantic, but several other
features of Rust make it desirable for the language to play with data layout in
complex ways.
For instance, consider this struct:
```rust
struct Foo<T, U> {
    count: u16,
    data1: T,
    data2: U,
}
```
Now consider the monomorphizations of `Foo<u32, u16>` and `Foo<u16, u32>`. If
Rust lays out the fields in the order specified, we expect it to pad the
values in the struct to satisfy their alignment requirements. So if Rust
didn't reorder fields, we would expect it to produce the following:


The Rustonomicon › repr(Rust)

```rust,ignore
struct Foo<u16, u32> {
    count: u16,
    data1: u16,
    data2: u32,
}

struct Foo<u32, u16> {
    count: u16,
    _pad1: u16,
    data1: u32,
    data2: u16,
    _pad2: u16,
}
```
The latter case quite simply wastes space. An optimal use of space
requires different monomorphizations to have *different field orderings*.
Enums make this consideration even more complicated. Naively, an enum such as:
```rust
enum Foo {
    A(u32),
    B(u64),
    C(u8),
}
```
might be laid out as:
```rust
struct FooRepr {
    data: u64, // this is either a u64, u32, or u8 based on `tag`
    tag: u8,   // 0 = A, 1 = B, 2 = C
}
```
And indeed this is approximately how it would be laid out (modulo the
size and position of `tag`).
However there are several cases where such a representation is inefficient. The
classic case of this is Rust's "null pointer optimization": an enum consisting
of a single outer unit variant (e.g. `None`) and a (potentially nested) non-
nullable pointer variant (e.g. `Some(&T)`) makes the tag unnecessary. A null
pointer can safely be interpreted as the unit (`None`) variant. The net
result is that, for example, `size_of::<Option<&T>>() == size_of::<&T>()`.


The Rustonomicon › repr(Rust)

There are many types in Rust that are, or contain, non-nullable pointers such as
`Box<T>`, `Vec<T>`, `String`, `&T`, and `&mut T`. Similarly, one can imagine
nested enums pooling their tags into a single discriminant, as they are by
definition known to have a limited range of valid values. In principle enums could
use fairly elaborate algorithms to store bits throughout nested types with
forbidden values. As such it is *especially* desirable that
we leave enum layout unspecified today.


The Rustonomicon › Exotically Sized Types

Most of the time, we expect types to have a statically known and positive size.
This isn't always the case in Rust.


The Rustonomicon › Exotically Sized Types › Dynamically Sized Types (DSTs)

Rust supports Dynamically Sized Types (DSTs): types without a statically
known size or alignment. On the surface, this is a bit nonsensical: Rust *must*
know the size and alignment of something in order to correctly work with it! In
this regard, DSTs are not normal types. Since they lack a statically known
size, these types can only exist behind a pointer. Any pointer to a
DST consequently becomes a *wide* pointer consisting of the pointer and the
information that "completes" them (more on this below).
There are two major DSTs exposed by the language:
* trait objects: `dyn MyTrait`
* slices: [`[T]`][slice], [`str`], and others
A trait object represents some type that implements the traits it specifies.
The exact original type is *erased* in favor of runtime reflection
with a vtable containing all the information necessary to use the type.
The information that completes a trait object pointer is the vtable pointer.
The runtime size of the pointee can be dynamically requested from the vtable.
A slice is simply a view into some contiguous storage -- typically an array or
`Vec`. The information that completes a slice pointer is just the number of elements
it points to. The runtime size of the pointee is just the statically known size
of an element multiplied by the number of elements.
Structs can actually store a single DST directly as their last field, but this
makes them a DST as well:
```rust
// Can't be stored on the stack directly
struct MySuperSlice {
    info: u32,
    data: [u8],
}
```
Unfortunately, such a type is largely useless without a way to construct it. Currently the
only properly supported way to create a custom DST is by making your type generic
and performing an *unsizing coercion*:

Exotically Sized Types
Dynamically Sized Types (DSTs)


The Rustonomicon › Exotically Sized Types › Dynamically Sized Types (DSTs)

```rust
struct MySuperSliceable<T: ?Sized> {
    info: u32,
    data: T,
}

fn main() {
    let sized: MySuperSliceable<[u8; 8]> = MySuperSliceable {
        info: 17,
        data: [0; 8],
    };

    let dynamic: &MySuperSliceable<[u8]> = &sized;

    // prints: "17 [0, 0, 0, 0, 0, 0, 0, 0]"
    println!("{} {:?}", dynamic.info, &dynamic.data);
}
```
(Yes, custom DSTs are a largely half-baked feature for now.)


The Rustonomicon › Exotically Sized Types › Zero Sized Types (ZSTs)

Rust also allows types to be specified that occupy no space:
```rust
struct Nothing; // No fields = no size

// All fields have no size = no size
struct LotsOfNothing {
    foo: Nothing,
    qux: (),      // empty tuple has no size
    baz: [u8; 0], // empty array has no size
}
```
On their own, Zero Sized Types (ZSTs) are, for obvious reasons, pretty useless.
However as with many curious layout choices in Rust, their potential is realized
in a generic context: Rust largely understands that any operation that produces
or stores a ZST can be reduced to a no-op. First off, storing it doesn't even
make sense -- it doesn't occupy any space. Also there's only one value of that
type, so anything that loads it can just produce it from the aether -- which is
also a no-op since it doesn't occupy any space.
One of the most extreme examples of this is Sets and Maps. Given a
`Map<Key, Value>`, it is common to implement a `Set<Key>` as just a thin wrapper
around `Map<Key, UselessJunk>`. In many languages, this would necessitate
allocating space for UselessJunk and doing work to store and load UselessJunk
only to discard it. Proving this unnecessary would be a difficult analysis for
the compiler.
However in Rust, we can just say that  `Set<Key> = Map<Key, ()>`. Now Rust
statically knows that every load and store is useless, and no allocation has any
size. The result is that the monomorphized code is basically a custom
implementation of a HashSet with none of the overhead that HashMap would have to
support values.

Exotically Sized Types
Zero Sized Types (ZSTs)


The Rustonomicon › Exotically Sized Types › Zero Sized Types (ZSTs)

Safe code need not worry about ZSTs, but *unsafe* code must be careful about the
consequence of types with no size. In particular, pointer offsets are no-ops,
and allocators typically require a non-zero size.
Note that references to ZSTs (including empty slices), just like all other
references, must be non-null and suitably aligned. However, loading or storing
through a null pointer to a ZST is not undefined behavior, unlike
pointers to other types.


The Rustonomicon › Exotically Sized Types › Empty Types

Rust also enables types to be declared that *cannot even be instantiated*. These
types can only be talked about at the type level, and never at the value level.
Empty types can be declared by specifying an enum with no variants:
```rust
enum Void {} // No variants = EMPTY
```
Empty types are even more marginal than ZSTs. The primary motivating example for
an empty type is type-level unreachability. For instance, suppose an API needs to
return a Result in general, but a specific case actually is infallible. It's
actually possible to communicate this at the type level by returning a
`Result<T, Void>`. Consumers of the API can confidently unwrap such a Result
knowing that it's *statically impossible* for this value to be an `Err`, as
this would require providing a value of type `Void`.
In principle, Rust can do some interesting analyses and optimizations based
on this fact. For instance, `Result<T, Void>` is represented as just `T`,
because the `Err` case doesn't actually exist (strictly speaking, this is only
an optimization that is not guaranteed, so for example transmuting one into the
other is still Undefined Behavior).
The following also compiles:
```rust
enum Void {}

let res: Result<u32, Void> = Ok(0);

// Err doesn't exist anymore, so Ok is actually irrefutable.
let Ok(num) = res;
```
One final subtle detail about empty types is that raw pointers to them are
actually valid to construct, but dereferencing them is Undefined Behavior
because that wouldn't make sense.


The Rustonomicon › Exotically Sized Types › Empty Types

We recommend against modelling C's `void*` type with `*const Void`.
A lot of people started doing that but quickly ran into trouble because
Rust doesn't really have any safety guards against trying to instantiate
empty types with unsafe code, and if you do it, it's Undefined Behavior.
This was especially problematic because developers had a habit of converting
raw pointers to references and `&Void` is *also* Undefined Behavior to
construct.
`*const ()` (or equivalent) works reasonably well for `void*`, and can be made
into a reference without any safety problems. It still doesn't prevent you from
trying to read or write values, but at least it compiles to a no-op instead
of Undefined Behavior.


The Rustonomicon › Exotically Sized Types › Extern Types

There is an accepted RFC to add proper types with an unknown size,
called *extern types*, which would let Rust developers model things like C's `void*`
and other "declared but never defined" types more accurately. However as of
Rust 2018, the feature is stuck in limbo over how `size_of_val::<MyExternType>()`
should behave.


The Rustonomicon › Alternative representations

Rust allows you to specify alternative data layout strategies from the default.


The Rustonomicon › Alternative representations › repr(C)

This is the most important `repr`. It has fairly simple intent: do what C does.
The order, size, and alignment of fields is exactly what you would expect from C
or C++. The type is also passed across `extern "C"` function call boundaries the
same way C would pass the corresponding type. Any type you expect to pass through an FFI boundary should have
`repr(C)`, as C is the lingua-franca of the programming world. This is also
necessary to soundly do more elaborate tricks with data layout such as
reinterpreting values as a different type.
We strongly recommend using [rust-bindgen] and/or [cbindgen] to manage your FFI
boundaries for you. The Rust team works closely with those projects to ensure
that they work robustly and are compatible with current and future guarantees
about type layouts and `repr`s.
The interaction of `repr(C)` with Rust's more exotic data layout features must be
kept in mind. Due to its dual purpose as "for FFI" and "for layout control",
`repr(C)` can be applied to types that will be nonsensical or problematic if
passed through the FFI boundary.
* ZSTs are still zero-sized, even though this is not a standard behavior in
C, and is explicitly contrary to the behavior of an empty type in C++, which
says they should still consume a byte of space.
* DST pointers (wide pointers) and tuples are not a concept
  in C, and as such are never FFI-safe.
* Enums with fields also aren't a concept in C or C++, but a valid bridging
  of the types is defined.


The Rustonomicon › Alternative representations › repr(C)

* If `T` is an FFI-safe non-nullable pointer
  type,
  `Option<T>` is guaranteed to have the same layout and ABI as `T` and is
  therefore also FFI-safe. As of this writing, this covers `&`, `&mut`,
  and function pointers, all of which can never be null.
* Tuple structs are like structs with regards to `repr(C)`, as the only
  difference from a struct is that the fields aren’t named.
* `repr(C)` is equivalent to one of `repr(u*)` (see the next section) for
fieldless enums. The chosen size and sign is the default enum size and sign for the target platform's C
application binary interface (ABI). Note that enum representation in C is implementation
defined, so this is really a "best guess". In particular, this may be incorrect
when the C code of interest is compiled with certain flags.
* Fieldless enums with `repr(C)` or `repr(u*)` still may not be set to an
integer value without a corresponding variant, even though this is
permitted behavior in C or C++. It is undefined behavior to (unsafely)
construct an instance of an enum that does not match one of its
variants. (This allows exhaustive matches to continue to be written and
compiled as normal.)


The Rustonomicon › Alternative representations › repr(transparent)

`#[repr(transparent)]` can only be used on a struct or single-variant enum that has a single non-zero-sized field (there may be additional zero-sized fields).
The effect is that the layout and ABI of the whole struct/enum is guaranteed to be the same as that one field.
NOTE: There's a `transparent_unions` nightly feature to apply `repr(transparent)` to unions,
but it hasn't been stabilized due to design concerns. See the tracking issue for more details.
The goal is to make it possible to transmute between the single field and the
struct/enum. An example of that is [`UnsafeCell`], which can be transmuted into
the type it wraps ([`UnsafeCell`] also uses the unstable no_niche,
so its ABI is not actually guaranteed to be the same when nested in other types).
Also, passing the struct/enum through FFI where the inner field type is expected on
the other side is guaranteed to work. In particular, this is necessary for
`struct Foo(f32)` or `enum Foo { Bar(f32) }` to always have the same ABI as `f32`.
This repr is only considered part of the public ABI of a type if either the single
field is `pub`, or if its layout is documented in prose. Otherwise, the layout should
not be relied upon by other crates.
More details are in the RFC 1758 and the RFC 2645.


The Rustonomicon › Alternative representations › repr(u), repr(i)

These specify the size and sign to make a fieldless enum. If the discriminant overflows
the integer it has to fit in, it will produce a compile-time error. You can
manually ask Rust to allow this by setting the overflowing element to explicitly
be 0. However Rust will not allow you to create an enum where two variants have
the same discriminant.
The term "fieldless enum" only means that the enum doesn't have data in any
of its variants. A fieldless enum without a `repr` is
still a Rust native type, and does not have a stable layout or representation.
Adding a `repr(u*)`/`repr(i*)` causes it to be treated exactly like the specified
integer type for layout purposes (except that the compiler will still exploit its
knowledge of "invalid" values at this type to optimize enum layout, such as when
this enum is wrapped in `Option`). Note that the function call ABI for these
types is still in general unspecified, except that across `extern "C"` calls they
are ABI-compatible with C enums of the same sign and size.
If the enum has fields, the effect is similar to the effect of `repr(C)`
in that there is a defined layout of the type. This makes it possible to
pass the enum to C code, or access the type's raw representation and directly
manipulate its tag and fields. See the RFC for details.
These `repr`s have no effect on a struct.
Adding an explicit `repr(u*)`, `repr(i*)`, or `repr(C)` to an enum with fields suppresses the null-pointer optimization, like:

Alternative representations
repr(u), repr(i)


The Rustonomicon › Alternative representations › repr(u), repr(i)

```rust
enum MyOption<T> {
    Some(T),
    None,
}

#[repr(u8)]
enum MyReprOption<T> {
    Some(T),
    None,
}

assert_eq!(8, size_of::<MyOption<&u16>>());
assert_eq!(16, size_of::<MyReprOption<&u16>>());
```
This optimization still applies to fieldless enums with an explicit `repr(u*)`, `repr(i*)`, or `repr(C)`.


The Rustonomicon › Alternative representations › repr(packed), repr(packed(n))

`repr(packed(n))` (where `n` is a power of two) forces the type to have an
alignment of *at most* `n`. Most commonly used without an explicit `n`,
`repr(packed)` is equivalent to `repr(packed(1))` which forces Rust to strip
any padding, and only align the type to a byte. This may improve the memory
footprint, but will likely have other negative side-effects.
In particular, most architectures *strongly* prefer values to be naturally
aligned. This may mean that unaligned loads are penalized (x86), or even fault
(some ARM chips). For simple cases like directly loading or storing a packed
field, the compiler might be able to paper over alignment issues with shifts
and masks. However if you take a reference to a packed field, it's unlikely
that the compiler will be able to emit code to avoid an unaligned load.
As this can cause undefined behavior, the lint has been implemented
and it will become a hard error.
`repr(packed)/repr(packed(n))` is not to be used lightly. Unless you have
extreme requirements, this should not be used.
This repr is a modifier on `repr(C)` and `repr(Rust)`. For FFI compatibility
you most likely always want to be explicit: `repr(C, packed)`.

Alternative representations
repr(packed), repr(packed(n))


The Rustonomicon › Alternative representations › repr(align(n))

`repr(align(n))` (where `n` is a power of two) forces the type to have an
alignment of *at least* `n`.
This enables several tricks, like making sure neighboring elements of an array
never share the same cache line with each other (which may speed up certain
kinds of concurrent code).
This is a modifier on `repr(C)` and `repr(Rust)`. It is incompatible with
`repr(packed)`.


The Rustonomicon › Ownership and Lifetimes

Ownership is the breakout feature of Rust. It allows Rust to be completely
memory-safe and efficient, while avoiding garbage collection. Before getting
into the ownership system in detail, we will consider the motivation of this
design.
We will assume that you accept that garbage collection (GC) is not always an
optimal solution, and that it is desirable to manually manage memory in some
contexts. If you do not accept this, might I interest you in a different
language?
Regardless of your feelings on GC, it is pretty clearly a *massive* boon to
making code safe. You never have to worry about things going away *too soon*
(although whether you still wanted to be pointing at that thing is a different
issue...). This is a pervasive problem that C and C++ programs need to deal
with. Consider this simple mistake that all of us who have used a non-GC'd
language have made at one point:
```rust,compile_fail
fn as_str(data: &u32) -> &str {
    // compute the string
    let s = format!("{}", data);

    // OH NO! We returned a reference to something that
    // exists only in this function!
    // Dangling pointer! Use after free! Alas!
    // (this does not compile in Rust)
    &s
}
```
This is exactly what Rust's ownership system was built to solve.
Rust knows the scope in which the `&s` lives, and as such can prevent it from
escaping. However this is a simple case that even a C compiler could plausibly
catch. Things get more complicated as code gets bigger and pointers get fed through
various functions. Eventually, a C compiler will fall down and won't be able to
perform sufficient escape analysis to prove your code unsound. It will consequently
be forced to accept your program on the assumption that it is correct.
This will never happen to Rust. It's up to the programmer to prove to the
compiler that everything is sound.


The Rustonomicon › Ownership and Lifetimes

Of course, Rust's story around ownership is much more complicated than just
verifying that references don't escape the scope of their referent. That's
because ensuring pointers are always valid is much more complicated than this.
For instance in this code,
```rust,compile_fail
let mut data = vec![1, 2, 3];
// get an internal reference
let x = &data[0];

// OH NO! `push` causes the backing storage of `data` to be reallocated.
// Dangling pointer! Use after free! Alas!
// (this does not compile in Rust)
data.push(4);

println!("{}", x);
```
naive scope analysis would be insufficient to prevent this bug, because `data`
does in fact live as long as we needed. However it was *changed* while we had
a reference into it. This is why Rust requires any references to freeze the
referent and its owners.


The Rustonomicon › References

There are two kinds of references:
* Shared reference: `&`
* Mutable reference: `&mut`
Which obey the following rules:
* A reference cannot outlive its referent
* A mutable reference cannot be aliased
That's it. That's the whole model references follow.
Of course, we should probably define what *aliased* means.
```text
error[E0425]: cannot find value `aliased` in this scope
 --> <rust.rs>:2:20
  |
2 |     println!("{}", aliased);
  |                    ^^^^^^^ not found in this scope

error: aborting due to previous error
```
Unfortunately, Rust hasn't actually defined its aliasing model. 🙀
While we wait for the Rust devs to specify the semantics of their language,
let's use the next section to discuss what aliasing is in general, and why it
matters.


The Rustonomicon › Aliasing

First off, let's get some important caveats out of the way:
* We will be using the broadest possible definition of aliasing for the sake
of discussion. Rust's definition will probably be more restricted to factor
in mutations and liveness.
* We will be assuming a single-threaded, interrupt-free, execution. We will also
be ignoring things like memory-mapped hardware. Rust assumes these things
don't happen unless you tell it otherwise. For more details, see the
Concurrency Chapter.
With that said, here's our working definition: variables and pointers *alias*
if they refer to overlapping regions of memory.