You are on page 1of 99

Rust 1.2.

0
082e47636

The Rust Reference
1 Introduction
2 Notation
2.1 Unicode productions
2.2 String table productions
3 Lexical structure
3.1 Input format
3.2 Identi ers
3.3 Comments
3.4 Whitespace
3.5 Tokens
3.5.1 Literals
3.5.1.1 Examples
3.5.1.1.1 Characters and strings
3.5.1.1.2 Byte escapes
3.5.1.1.3 Unicode escapes
3.5.1.1.4 Numbers
3.5.1.1.5 Suf xes
3.5.1.2 Character and string literals
3.5.1.2.1 Character literals
3.5.1.2.2 String literals
3.5.1.2.3 Character escapes
3.5.1.2.4 Raw string literals
3.5.1.3 Byte and byte string literals
3.5.1.3.1 Byte literals
3.5.1.3.2 Byte string literals
3.5.1.3.3 Raw byte string literals
3.5.1.4 Number literals
3.5.1.4.1 Integer literals
3.5.1.4.2 Floating-point literals
3.5.1.5 Boolean literals
3.5.2 Symbols
3.6 Paths
4 Syntax extensions
4.1 Macros

4.1.1 Macro By Example
4.1.2 Parsing limitations
5 Crates and source les
6 Items and attributes
6.1 Items
6.1.1 Type Parameters
6.1.2 Modules
6.1.2.1 Extern crate declarations
6.1.2.2 Use declarations
6.1.3 Functions
6.1.3.1 Generic functions
6.1.3.2 Unsafety
6.1.3.2.1 Unsafe functions
6.1.3.2.2 Unsafe blocks
6.1.3.2.3 Behavior considered unde ned
6.1.3.2.4 Behavior not considered unsafe
6.1.3.3 Diverging functions
6.1.3.4 Extern functions
6.1.4 Type aliases
6.1.5 Structures
6.1.6 Enumerations
6.1.7 Constant items
6.1.8 Static items
6.1.8.1 Mutable statics
6.1.9 Traits
6.1.10 Implementations
6.1.11 External blocks
6.2 Visibility and Privacy
6.2.1 Re-exporting and Visibility
6.3 Attributes
6.3.1 Crate-only attributes
6.3.2 Module-only attributes
6.3.3 Function-only attributes
6.3.4 Static-only attributes
6.3.5 FFI attributes
6.3.6 Macro-related attributes
6.3.7 Miscellaneous attributes
6.3.8 Conditional compilation
6.3.9 Lint check attributes
6.3.10 Language items
6.3.11 Inline attributes
6.3.12 derive
6.3.13 Compiler Features

7 Statements and expressions
7.1 Statements
7.1.1 Declaration statements
7.1.1.1 Item declarations
7.1.1.2 Variable declarations
7.1.2 Expression statements
7.2 Expressions
7.2.0.1 Lvalues, rvalues and temporaries
7.2.0.1.1 Temporary lifetimes
7.2.0.2 Moved and copied types
7.2.1 Literal expressions
7.2.2 Path expressions
7.2.3 Tuple expressions
7.2.4 Structure expressions
7.2.5 Block expressions
7.2.6 Method-call expressions
7.2.7 Field expressions
7.2.8 Array expressions
7.2.9 Index expressions
7.2.10 Range expressions
7.2.11 Unary operator expressions
7.2.12 Binary operator expressions
7.2.12.1 Arithmetic operators
7.2.12.2 Bitwise operators
7.2.12.3 Lazy boolean operators
7.2.12.4 Comparison operators
7.2.12.5 Type cast expressions
7.2.12.6 Assignment expressions
7.2.12.7 Compound assignment expressions
7.2.12.8 Operator precedence
7.2.13 Grouped expressions
7.2.14 Call expressions
7.2.15 Lambda expressions
7.2.16 In nite loops
7.2.17 Break expressions
7.2.18 Continue expressions
7.2.19 While loops
7.2.20 For expressions
7.2.21 If expressions
7.2.22 Match expressions
7.2.23 If let expressions
7.2.24 While let loops
7.2.25 Return expressions

3 Type coercions 8.0.1 Types 8.1. .7 Recursive types 8.1.9 Function types 8. and Slice types 8.2 Machine-dependent integer types 8.1 Primitive types 8.8 Type system 8.3 Variables 11 Linkage 12 Appendix: Rationales and design tradeoffs 13 Appendix: In uences 1 Introduction This document is the primary reference for the Rust programming language.1 Memory allocation and lifetime 10.3 Tuple types 8.1.4 The Dereftrait 10 Memory model 10.10 Closure types 8.3.2 Coercion types 9 Special traits 9.11 Trait objects 8.13 Self types 8.3 The Droptrait 9.1.1.1.1.1.8 Pointer types 8.2 Subtyping 8.2 Memory ownership 10.1.1.9.0.1.1 Machine types 8. It provides three kinds of material: Chapters that informally describe each language construct and their use.1.1.0.1.1 The Copytrait 9.1.1.1.6 Enumerated types 8.2 Textual types 8.4 Array.1.12 Type parameters 8.2 The Sizedtrait 9.5 Structure types 8.1 Coercion sites 8.3.1 Function types for speci c items 8.

Chapters that informally describe the memory model, concurrency model,
runtime services, linkage model and debugging facilities.
Appendix chapters providing rationale and references to languages that
influenced the design.
This document does not serve as an introduction to the language. Background
familiarity with the language is assumed. A separate book (book/) is available to help
acquire such background familiarity.
This document also does not serve as a reference to the standard (std/) library
included in the language distribution. Those libraries are documented separately by
extracting documentation attributes from their source code. Many of the features
that one might expect to be language features are library features in Rust, so what
you're looking for may be there, not here.
You may also be interested in the grammar (grammar.html).

2 Notation
2.1 Unicode productions
A few productions in Rust's grammar permit Unicode code points outside the ASCII
range. We define these productions in terms of character properties specified in the
Unicode standard, rather than in terms of ASCII-range code points. The grammar
has a Special Unicode Productions (grammar.html#special-unicode-productions)
section that lists these productions.

2.2 String table productions
Some rules in the grammar — notably unary operators (#unary-operatorexpressions), binary operators (#binary-operator-expressions), and keywords
(grammar.html#keywords) — are given in a simplified form: as a listing of a table of
unquoted, printable whitespace-separated strings. These cases form a subset of the
rules regarding the token (#tokens) rule, and are assumed to be the result of a
lexical-analysis phase feeding the parser, driven by a DFA, operating over the
disjunction of all such string table entries.

When such a string enclosed in double-quotes ( ") occurs inside the grammar, it is an
implicit reference to a single member of such a string table production. See tokens
(#tokens) for more information.

3 Lexical structure
3.1 Input format
Rust input is interpreted as a sequence of Unicode code points encoded in UTF-8.
Most Rust grammar rules are defined in terms of printable ASCII-range code points,
but a small number are defined in terms of Unicode properties or explicit code point
lists. 1 (#fn1)

3.2 Identi ers
An identifier is any nonempty Unicode2 (#fn2) string of the following form:
The first character has property XID_start
The remaining characters have property XID_continue
that does not occur in the set of keywords (grammar.html#keywords).
Note: XID_startand XID_continueas character properties cover the character
ranges used to form the more familiar C and Java language-family identifiers.

3.3 Comments
Comments in Rust code follow the general C++ style of line ( //) and block ( /* ...
*/) comment forms. Nested block comments are supported.
Line comments beginning with exactly three slashes ( ///), and block comments
beginning with exactly one repeated asterisk in the block-open sequence ( /**), are
interpreted as a special syntax for docattributes (#attributes). That is, they are
equivalent to writing #[doc="..."]around the body of the comment, i.e., ///
Footurns into #[doc="Foo"].

Line comments beginning with //!and block comments beginning with /*!are
doc comments that apply to the parent of the comment, rather than the item that
follows. That is, they are equivalent to writing #![doc="..."]around the body of
the comment. //!comments are usually used to document modules that occupy a
source file.
Non-doc comments are interpreted as a form of whitespace.

3.4 Whitespace
Whitespace is any non-empty string containing only the following characters:
U+0020(space, ' ')
U+0009(tab, '\t')
U+000A(LF, '\n')
U+000D(CR, '\r')
Rust is a "free-form" language, meaning that all forms of whitespace serve only to
separate tokens in the grammar, and have no semantic significance.
A Rust program has identical meaning if each whitespace element is replaced with
any other legal whitespace element, such as a single space character.

3.5 Tokens
Tokens are primitive productions in the grammar defined by regular (non-recursive)
languages. "Simple" tokens are given in string table production (#string-tableproductions) form, and occur in the rest of the grammar as double-quoted strings.
Other tokens have exact rules given.

3.5.1 Literals
A literal is an expression consisting of a single token, rather than a sequence of
tokens, that immediately and directly denotes the value it evaluates to, rather than
referring to it by name or some other evaluation rule. A literal is a form of constant
expression, so is evaluated (primarily) at compile time.

2 Byte escapes Name \x7F 8-bit character code (exactly 2 digits) \n Newline \r Carriage return \t Tab \\ Backslash 3..1.1 Examples 3.1.5.5..4 Numbers Number literals * Example Exponentiation Suffixes Decimal integer 98_222 N/A Integer suffixes Hex integer 0xff N/A Integer suffixes .1.. All ASCII N/A 3.1.1.5.5. All Unicode N/A Byte b'H' N/A All ASCII \'& Byte Byte string b"hello" N/A All ASCII \"& Byte Raw byte string br#"hello"# 0.1.1.1 Characters and strings Example #sets Characters Escapes Character 'H' N/A All Unicode \'& Byte & Unicode String "hello" N/A All Unicode \"& Byte & Unicode Raw r#"hello"# 0.5.1.3.1..3 Unicode escapes Name \u{7FFF} 24-bit Unicode character code (up to 6 digits) 3.

1.1. the U+005Ccharacter. with the exception of U+0022itself. no translation). Thus aand bare equal: let a = "foobar". the newline.2 Character and string literals 3. i16. isize.0E+18f64 3.5.0E+77 Floating-point suffixes Optional *All number literals allow _as a visual separator: 1_234. usize f32.5 Suf xes Integer Floating-point u8. f64 3.b).e.2. 3. u16. which must be escaped by a preceding U+005Ccharacter ( \). which must be escaped by a preceding U+005Ccharacter ( \). but as a special exception.5. u32. . i32.1. i8. u64. Line-break characters are allowed in string literals.5. assert_eq!(a.2 String literals A string literal is a sequence of any Unicode characters enclosed within two U+0022 (double-quote) characters. with the exception of U+0027itself.Hex integer 0xff N/A Integer suffixes Octal integer 0o77 N/A Integer suffixes Binary integer 0b1111_0000 N/A Integer suffixes Floating-point 123. and all whitespace at the beginning of the next line are ignored.5. Normally they represent themselves (i.1.2. when a U+005Ccharacter ( \) occurs immediately before the newline.1 Character literals A character literal is a single Unicode character enclosed within two U+0027(singlequote) characters. i64. let b = "foo\ bar".1.

3.2. It denotes the Unicode code point equal to the provided hex value.3. The raw string body can contain any sequence of Unicode characters and is terminated only by another U+0022(double-quote) character. They start with the character U+0072 ( r). U+000D(CR) or U+0009(HT) respectively. An escape starts with a U+005C( \) and continues with one of the following forms: An 8-bit code point escape starts with U+0078( x) and is followed by exactly two hex digits. A 24-bit code point escape starts with U+0075( u) and is followed by up to six hex digits surrounded by braces U+007B( {) and U+007D( }).5.1.2. The backslash escape is the character U+005C( \) which must be escaped in order to denote itself. or U+0074( t). All Unicode characters contained in the raw string body represent themselves.5. followed by zero or more of the character U+0023( #) and a U+0022(doublequote) character. denoting the Unicode values U+000A(LF).1. Examples for string literals: . U+0072( r). followed by the same number of U+0023( #) characters that preceded the opening U+0022(double-quote) character.3 Character escapes Some additional escapes are available in either character or non-raw string literals. A whitespace escape is one of the characters U+006E( n). the characters U+0022(double-quote) (except when followed by at least as many U+0023( #) characters as were used to start the raw string literal) or U+005C( \) do not have any special meaning.4 Raw string literals Raw string literals do not process any escapes. It denotes the Unicode code point equal to the provided hex value.

r##"foo #"# bar"##. It is equivalent to a u8unsigned 8-bit integer number literal.3 Byte and byte string literals 3. A whitespace escape is one of the characters U+006E( n). "R". and followed by the character U+0027. r"\x52". a byte string literal can be a raw byte string literal. It denotes the byte equal to the provided hex value. r"R".5. If the character U+0027is present within the literal. "\\x52".5.1 Byte literals A byte literal is a single ASCII character (in the U+0000to U+007Frange) or a single escape preceded by the characters U+0062( b) and U+0027(single-quote). // foo #"# bar "\x52". defined below. and followed by the character U+0022. // foo // "foo" "foo #\"# bar". Some additional escapes are available in either byte or non-raw byte string literals.3.1. preceded by the characters U+0062( b) and U+0022(double-quote). it must be escaped by a preceding U+005C( \) character.5. n]borrowed fixed-sized array of unsigned 8-bit integers. The backslash escape is the character U+005C( \) which must be escaped in . it must be escaped by a preceding U+005C( \) character. Alternatively."foo". r#""foo""#. r"foo". "\"foo\"". or U+0074( t). 3.3. An escape starts with a U+005C( \) and continues with one of the following forms: A byte escape escape starts with U+0078( x) and is followed by exactly two hex digits.1. // R // \x52 3. If the character U+0022is present within the literal. 0x0D(ASCII CR) or 0x09(ASCII HT) respectively.1. denoting the bytes values 0x0A(ASCII LF).2 Byte string literals A non-raw byte string literal is a sequence of ASCII characters and escapes. U+0072( r). A byte string literal of length nis equivalent to a &'static [u8.

1.3. br"R". b"\\x52". The raw string body can contain any sequence of ASCII characters and is terminated only by another U+0022(double-quote) character.1. and a U+0022(double-quote) character. 3.4. Examples for byte string literals: b"foo".5. br"\x52". . br##"foo #"# bar"##. They start with the character U+0062( b). followed by the same number of U+0023( #) characters that preceded the opening U+0022(double-quote) character. 3.5.5. // foo #"# bar b"\x52". followed by U+0072( r). All characters contained in the raw string body represent their ASCII encoding.1. The grammar for recognizing the two kinds of literals is mixed. // R // \x52 3. br#""foo""#.4 Number literals A number literal is either an integer literal or a floating-point literal. b"R". followed by zero or more of the character U+0023( #).3 Raw byte string literals Raw byte string literals do not process any escapes. the characters U+0022(double-quote) (except when followed by at least as many U+0023( #) characters as were used to start the raw string literal) or U+005C( \) do not have any special meaning.1 Integer literals An integer literal has one of four forms: A decimal literal starts with a decimal digit and continues with any mixture of decimal digits and underscores. b"\"foo\"". A raw byte string literal can not contain any non-ASCII byte.order to denote its ASCII encoding 0x5C. br"foo". // foo // "foo" b"foo #\"# bar".

). An octal literal starts with the character sequence U+0030 U+006F( 0o) and continues as any mixture of octal digits and underscores. 0o70_i16. it is considered a static type error. A binary literal starts with the character sequence U+0030 U+0062( 0b) and continues as any mixture of binary digits and underscores.5. without any spaces) by an integer suffix. u16. which forcibly sets the type of the literal. 0usize.2 Floating-point literals A floating-point literal has one of two forms: A decimal literal followed by a period character U+002E( . the unsuffixed integer literal has that type. If an integer type can be uniquely determined from the surrounding program context. Examples of integer literals of various forms: 123i32.A hex literal starts with the character sequence U+0030 U+0078( 0x) and continues as any mixture of hex digits and underscores. Like any literal. A single decimal literal followed by an exponent. i16. an integer literal may be followed (immediately. or usize. i32. The integer suffix must be the name of one of the integral types: u8. if the program context overconstrains the type. u64. . 0xff_u8. The type of an unsuffixed integer literal is determined by type inference. isize.4. i8. u32. with an optional exponent. If the program context underconstrains the type. // type i32 // type u32 // type u32 // type u8 // type i16 // type i32 // type usize 3. 0b1111_1111_1001_0000_i32.1. 123_u32. This is optionally followed by another decimal literal. it defaults to the signed 32-bit integer i32. i64. 123u32.

Like integer literals.f64would attempt to call a method named f64on 2. // type f64 This last example is different because it is not possible to use the suffix syntax with a floating point literal ending in a period. Examples of floating-point literals of various forms: 123. it defaults to double-precision f64.5 Boolean literals The two values of the boolean type are written trueand false. There are two valid floating-point suffixes. it is considered a static type error.5. // type f64 let x: f64 = 2.1f64. // type f64 0. 3. If the program context underconstrains the type. the unsuffixed floating-point literal has that type.).2 Symbols Symbols are a general class of printable token (#tokens) that play structural roles in a variety of grammar productions. or keywords (grammar. so long as the pre-suffix part does not end with U+002E( . . They are catalogued here for completeness as the set of remaining miscellaneous printable tokens that do not otherwise appear as unary operators (#unary-operator-expressions).1. If a floating-point type can be uniquely determined from the surrounding program context. f32and f64(the 32-bit and 64bit floating point types). binary operators (#binary-operatorexpressions). a floating-point literal may be followed by a suffix. // type f32 12E+99_f64. 3. The suffix forcibly sets the type of the literal. 2.5. // type f64 0. The representation semantics of floating-point numbers are described in "Machine Types" (#machine-types)..1f32. if the program context overconstrains the type.0f64. The type of an unsuffixed floating-point literal is determined by type inference. which explicitly determine the type of the literal.html#keywords).

Two examples of simple paths consisting of only identifier components: x. Each identifier in the path must resolve to an item. . but they may also include angle-bracket-enclosed lists of type arguments. x::y::z. Two examples of paths with type arguments: type T = HashMap<i32. the final namespace qualifier is omitted.3. // Type arguments used in a type expression let x = id::<i32>(10). In expression (#expressions) context. but the path naming an item is only meaningful within a given crate. Every item has a canonical path within its crate.6 Paths A path is a sequence of one or more path components logically separated by a namespace qualifier ( ::). the type argument list is given a er a ::namespace qualifier in order to disambiguate it from a relational expression involving the less-than symbol ( <). it refers to an item. There is no global namespace across crates. Path components are usually identifiers (#identifiers). // Type arguments used in a call expression Paths can be denoted with various leading qualifiers to change the meaning of how it is resolved: Paths starting with ::are considered to be global paths where the components of the path start being resolved from the crate root. If a path has multiple components. it may refer to either an item (#items) or a variable (#variables) in a local control scope. an item's canonical path merely identifies it within the crate. In type expression context.String>. If a path consists of only one component.

mod a { pub fn foo() {} } mod b { pub fn foo() { super::a::foo(). Instead. Each further identifier must resolve to an item. // call a's foo function } } Paths starting with the keyword selfbegin resolution relative to the current module.mod a { pub fn foo() {} } mod b { pub fn foo() { ::a::foo().. // call a's foo function } } Paths starting with the keyword superbegin resolution relative to the parent module. Each further identifier must resolve to an item. and invoked through a consistent syntax: some_extension!(. } 4 Syntax extensions A number of minor features of Rust are not central enough to have their own syntax. fn foo() {} fn bar() { self::foo(). Users of rustccan define new syntax extensions in two ways: . and yet are not implementable as functions..). they are given names.

The parentheses are not matched or . pat. Macros (book/macros. *means zero or more repetitions. including delimiters. (A sep_tokenis any token other than *and +. and so only the name of a matched nonterminal comes a er the dollar sign.html) define new syntax in a higher-level. and tries each macro rule in turn. or patterns. expr. +means at least one repetition. macros can expand to expressions.html). Valid designators are item. statements. $name :designator matches the nonterminal in the Rust syntax named by designator. Note that the interface for compiler plugins is considered highly unstable. A non_special_tokenis any token other than a delimiter or $.html) can include arbitrary Rust code that manipulates syntax trees at compile time. tt(either side of the =>in macro rules). optionally followed by a separator token. In the matcher. followed by *or +.1 Macros macro_rulesallows users to define syntax extension in a declarative way. In the transcriber. the designator is already known. The Kleene star operator consists of $and parentheses. items. ident. Matching and transcription are closely related to each other. 4. 4.1 Macro By Example The macro expander matches and transcribes every token that does not begin with a $literally. but they are otherwise not special. block. ty (type). In both the matcher and transcriber.Compiler plugins (book/compiler-plugins. Currently. the Kleene star-like operator indicates repetition.) The macro expander looks up macro invocations by name. For parsing reasons. path. delimiters must be balanced. It transcribes the first successful match.1. declarative way. and we will describe them together. We call such extensions "macros by example" or simply "macros" — to be distinguished from the "procedural macros" defined in compiler plugins (book/compiler-plugins. stmt.

d).2 Parsing limitations The parser used by the macro system is reasonably powerful. $( $j:ident ). a $(.e). but not (a. ( $( $i:ident ). When Macro By Example encounters a repetition. See RFC 550 for more information. so the former input transcribes to (a. The job of the transcriber is to sort that structure out.c . d. d.b.e).and . This implies that a macro definition like $i:expr [ . 5 Crates and source les .* ) => ( $( ($i. (b. or immediately a er. and all of them must be discharged by the time a name is transcribed.. 4. A macro definition like $i:expr. The repetition walks through the choices at that layer in lockstep. Therefore. This requirement most o en affects name-designator pairs when they occur at the beginning of.would be legal.f).1. because [could be part of an expression.are legal separators.* )is acceptable (if trivial). Nested repetitions are allowed.transcribed.c . At the "current layer".$j) ).. 2. but the parsing of Rust syntax is restricted in two ways: 1. The rules for transcription of these repetitions are called "Macro By Example". The parser must have eliminated all ambiguity by the time it reaches a $name : designator. it examines all of the $name s that occur in its body.or $i:expr. however. Essentially. because . they all must repeat the same number of times. a name is bound to all of the names it matches.b. ]is not legal. (c. requiring a distinctive token in front can solve the problem. Macro definitions are required to include suitable separators a er parsing expressions and other bits of the Rust grammar. On the matcher side.* ) => ( $i )is an invalid macro.e. one "layer" of repetition is discharged at a time.f). so ( $( $i:ident ).* )is valid if given the argument (a.* .* ) => ( $( $i:ident ). but ( $( $i:ident ).)*. in a structure that mimics the structure of the repetition encountered on a successful match.

Although Rust. A Rust source file describes a module. Each source file contains a sequence of zero or more itemdefinitions. as well as versioning. the name and location of which — in the module tree of the current crate — are defined from outside the source file: either by an explicit mod_itemin a referencing source file. but not every module needs its own source file: module definitions (#modules) can be nested within one file. this section assumes a compiler. The compilation model centers on artifacts called crates. The top level of this tree is a module that is anonymous (from the point of view of paths within the module) and any item within a crate has a canonical module path (#paths) denoting its location within the crate's module tree. Rust's semantics obey a phase distinction between compile-time and run-time. Every source file is a module. The processing of that source file may result in other source files being loaded as modules. . The Rust compiler is always invoked with a single source file as input. For these reasons. or by the name of the crate itself.4 (#fn4) A crate is a unit of compilation and linking. Each compilation processes a single crate in source form.rs. and if successful. produces a single crate in binary form: either an executable or some sort of library. A crate contains a tree of nested module (#modules) scopes. the only existing implementation is a compiler — from now on referred to as the Rust compiler — and the language has always been designed to be compiled. The anonymous crate module can have additional attributes that apply to the crate as a whole. and may optionally begin with any number of attributes (#items-and-attributes) that apply to the containing module. and always produces a single output crate. can be implemented by an interpreter as well as a compiler. like any other language. Source files have the extension . distribution and runtime loading. Those semantics that have a dynamic interpretation govern the behavior of the program at run-time. most of which influence the behavior of the compiler.3 (#fn3) Those semantic rules that have a static interpretation govern the success or failure of compilation.

If a main function is present. not just the anonymous crate module. Items are entirely determined at compile-time. There are several kinds of item: extern cratedeclarations usedeclarations modules functions type definitions structures enumerations . #![crate_name = "projx"] // Specify the type of output artifact. all further items within the crate have paths (#paths) within the module tree of the crate. // This can be done in any module. #![warn(non_camel_case_types)] A crate that contains a mainfunction can be compiled to an executable. #![crate_type = "lib"] // Turn on a warning. its return type must be unit(#tuple-types) and it must take no arguments. generally remain fixed during execution. 6. 6 Items and attributes Crates contain items (#items).// Specify the crate name.1 Items An item is a component of a crate. each of which may have some number of attributes (#attributes) attached to it. and may reside in read-only memory. Every crate has a single "outermost" anonymous module. Items are organized within a crate by a nested set of modules (#modules).

2 Modules A module is a container for zero or more items (#items). only type-parametric items.. a er the name of the item and before its definition. not part of the type of the item. That is.1. 6. A module item introduces a new.constant items static items traits implementations Some items form an implicit scope for the declaration of sub-items. In practice. The meaning of these scoped items is the same as if the item was declared outside the scope — it is still a static item — except that the item's path name within the module namespace is qualified by the name of the enclosing item. and prefixed with the keyword mod. A referencing path (#paths) must (in principle) provide type arguments as a list of comma-separated types enclosed within angle brackets. An example of a module: . There are no general type-parametric types. or is private to the enclosing item (in the case of functions). The type parameters of an item are considered "part of the name". In other words. surrounded in braces. named..1.1 Type Parameters All items except modules. The grammar specifies the exact locations in which sub-item declarations may appear. 6. declarations of items can (in many cases) be mixed with the statements. constants and statics may be parameterized by type. the type-inference system can usually infer such argument types from context. Type parameters are given as a comma-separated list of identifiers enclosed in angle brackets ( <. named module into the tree of modules making up a crate. control blocks. though higher-ranked types do exist for lifetimes. and similar artifacts that otherwise compose the item body. within a function or module. A module item is a module. in order to refer to the type-parameterized item. Rust has no notion of type abstraction: there are no higher-ranked (or "forall") types abstracted over other types.>). Modules can nest arbitrarily.

*/ } fn tan(f: f64) -> f64 { /* . */ } fn cos(f: f64) -> f64 { /* .rs` #[path = "tls.mod math { type Complex = (f64. it is loaded from a subdirectory path that mirrors the module hierarchy. trait. a type definition.. mod local_data. plus the . #[path = "thread_files"] mod thread { // Load the `local_data` module from `thread_files/tls. A module without a body is loaded from an external file.rsextension. // Load the `vec` module from `vec. struct. } . by default with the same name as the module. */ } } Modules and types share the same namespace. or type parameter can't shadow the name of a module in scope.. When a nested submodule is loaded from an external file. enumeration.rs`...rs` // or `thread/local_data/mod. Declaring a named type with the same name as a module in scope is forbidden: that is. } The directories and files used for loading external file modules can be influenced with the pathattribute. fn sin(f: f64) -> f64 { /* . mod thread { // Load the `local_data` module from `thread/local_data.rs` mod vec.. or vice versa.. f64).rs"] mod local_data.

The external crate is resolved to a specific sonameat compile time.6. extern cratedeclarations (#externcrate-declarations) declare linkage dependencies. If no crateidis provided.1. using the syntax use p::q::r . The external crate is then bound into the declaring scope as the identprovided in the extern_crate_decl. extern crate std as ruststd. The sonameis resolved at compile time by scanning the compiler's library path and matching the optional crateidprovided against the crateidattributes that were declared on the external crate when it was compiled. // linking to 'std' under another name 6. Use declarations support a number of convenient shortcuts: Rebinding the target name as a new local name. // equivalent to: extern crate std as std.2. a default nameattribute is assumed. Three examples of extern cratedeclarations: extern crate pcre. extern crate std. Note: Unlike in many languages. Rather.2. usedeclarations in Rust do not declare linkage dependency with external crates. Usually a usedeclaration is used to shorten the path required to refer to a module item. These declarations may appear at the top of modules (#modules) and blocks (grammar.1 Extern crate declarations An extern cratedeclaration specifies a dependency on an external crate.html#block-expressions). equal to the identgiven in the extern_crate_decl.2 Use declarations A use declaration creates one or more local name bindings synonymous with some other path (#paths).1. and a runtime linkage requirement to that sonameis passed to the linker for loading at runtime.

An example of usedeclarations: use std::option::Option::{Some. such as use a::b:: {self. Such a usedeclaration serves to re-export a name. fn foo<T>(_: T){} fn bar(map1: HashMap<String. Simultaneously binding a list of paths differing only in their final element.0f64). d}. None]). If a sequence of such redirections form a cycle or cannot be resolved unambiguously. inside a different module. a usedeclaration can be public. usize>){} fn main() { // Equivalent to 'foo(vec![std::option::Option::Some(1. let map1 = HashMap::new(). Binding all paths matching a given prefix. using the asterisk wildcard syntax use a::b::*. // std::option::Option::None]). usize>. HashMap}. usedeclarations are private to the containing module. map2: hash_map::HashMap<String. let map2 = hash_map::HashMap::new(). using the glob-like brace syntax use a::b::{c.d. // Both `hash_map` and `HashMap` are in scope. None}. Simultaneously binding a list of paths differing only in their final element and their immediate parent module. by default. An example of re-exporting: . A public usedeclaration can therefore redirect some public name to a different target definition: even a definition with a private canonical path. using the selfkeyword.e. c. if qualified by the pubkeyword.as x. bar(map1. } Like items.0f64). Also like items. they represent a compile-time error.f}. use std::collections::hash_map::{self.' foo(vec![Some(1. map2).

All rules regarding accessing declared modules in usedeclarations apply to both module declarations and extern cratedeclarations. This also means that top-level module declarations should be at the crate root if direct usage of the declared modules within useitems is desired. the module quuxre-exports two public names defined in foo. So.mod quux { pub use quux::foo::{bar. baz}. baz}. pub mod foo { pub fn bar() { } pub fn baz() { } } } In this example. the userefers to quux::foo::{bar. Also note that the paths contained in useitems are relative to the crate root. in the previous example. baz}. and not simply to foo::{bar. It is also possible to use selfand superat the beginning of a useitem to refer to the current and direct parent modules respectively. An example of what will and will not work for useitems: .

// good: foo is at crate root pub mod bar { pub fn foobar() { } } pub mod baz { use super::bar::foobar. Functions are declared with the keyword fn. // good: self refers to module 'foo' use foo::bar::foobar. in which case the value has the corresponding function type (#function-types). that expression is interpreted as an implicit returnexpression applied to the final-expression. // good: foo is at the root of the crate mod foo { mod example { pub mod iter {} } use foo::example::iter. // bad: core is not at the crate root use self::baz::foobaz.3 Functions A function item defines a sequence of statements (#statements) and an optional final expression (#expressions). Every control path in a function logically ends with a returnexpression or a diverging expression. . and can be used otherwise exactly as a function item (with a minor additional cost of calling the function indirectly). along with a name and a set of parameters. Functions declare a set of input variables (#variables) as parameters. and the output type (#types) of the value the function will return to its caller on completion. // good: super refers to module 'foo' pub fn foobaz() { } } } fn main() {} 6.use foo::baz::foobaz. If the outermost block of a function has a value-producing expression in its final-expression position. A function may also be copied into a first-class value.1. through which the caller passes arguments into the function. // good: foo is at crate root // use example::iter.

fn first((value. For example.3. B>(x: A. y: B) { Inside the function signature and body. function arguments are irrefutable patterns.1 Generic functions A generic function allows one or more parameterized types to appear in its signature. y: i32) -> i32 { return x + y. i32)) -> i32 { value } 6. // foo is generic over A and B fn foo<A. so any pattern that is valid in a let binding is also valid as an argument. Trait (#traits) bounds can be specified for type parameters to allow methods with that trait to be called on values of that type. comma-separated list following the function name. } As with letbindings. in an angle-bracket-enclosed.1. Each type parameter must be explicitly declared. the name of the type parameter can be used as a type name. This is specified using the wheresyntax: fn foo<T>(x: T) where T: Debug { When a generic function is referenced.An example of a function: fn add(x: i32. its type is instantiated based on the context of the reference. _): (i32. calling the foofunction here: .

3. 2]).2. to permit calling unsafefunctions or dereferencing raw pointers within a safe function. mem::size_of::<u32>() == 4. 6.3. The type parameters can also be explicitly supplied in a trailing path (#paths) component a er the function name. 6. fn foo<T>(x: &[T]) where T: Debug { // details elided } foo(&[1.1. 6. will instantiate type parameter Twith i32. Such a function must be prefixed with the keyword unsafeand can only be called from an unsafeblock or another unsafefunction. This might be necessary if there is not sufficient context to determine the type parameters.1.1. For example. . The following language level features cannot be used in the safe subset of Rust: Dereferencing a raw pointer. Calling an unsafe function (including an intrinsic or foreign function).2 Unsafety Unsafe operations are those that potentially violate the memory-safety guarantees of Rust's static semantics.2.3. Reading or writing a mutable static variable.use std::fmt::Debug.1 Unsafe functions Unsafe functions are functions that are not safe in all contexts and/or for all possible inputs.2 Unsafe blocks A block of code can be prefixed with the unsafekeyword.

in the surrounding context. they can encapsulate that sequence (taken as a whole) within an unsafeblock.2. 6. The compiler will consider uses of such code safe.When a programmer has sufficient conviction that a sequence of potentially unsafe operations is actually safe. For example. Invoking undefined behavior via compiler intrinsics: Indexing outside of the bounds of an object with std::ptr::offset ( offsetintrinsic). except if the &Tcontains an UnsafeCell<U>. so in some cases there is a performance cost to using safe code. . Mutating non-mutable data (that is. Rust's type system is a conservative approximation of the dynamic safety requirements.3. unless that data is contained within an UnsafeCell<U>. Unsafe blocks are used to wrap foreign libraries. Data races Dereferencing a null/dangling raw pointer Reads of undef (uninitialized) memory Breaking the pointer aliasing rules with raw pointers (a subset of the rules used by C) &mutand &follow LLVM’s scoped noalias model.1. For example. By using unsafeblocks to represent the reverse links as raw pointers. data reached through a shared reference or data owned by a letbinding). make direct use of hardware or implement features not directly present in the language. including within unsafeblocks and unsafefunctions. Rust provides the language features necessary to implement memory-safe concurrency in the language but the implementation of threads and message passing is in the standard library.3 Behavior considered unde ned The following is a list of behavior which is forbidden in all Rust code. Unsafe code must not violate these aliasing guarantees. a doubly-linked list is not a tree structure and can only be represented with reference-counted pointers in safe code. with the exception of one byte past the end which is permitted. Type checking provides the guarantee that these issues are never caused by safe code. it can be implemented with only boxes.

3 Diverging functions A special kind of function can be declared with a !character where the output type would normally be. 6.2. Unwinding must be caught and handled at FFI boundaries. but in optimized builds overflow instead results in wrapped values. but that may be undesired. Deadlocks Reading data from private fields ( std::repr) Leaks of memory and other resources Exiting without calling destructors Sending signals Accessing/modifying the file system Integer overflow Overflow is considered "unexpected" behavior and is always user-error.Using std::ptr::copy_nonoverlapping_memory ( memcpy32/ memcpy64intrinsics) on overlapping buffers Invalid values in primitive types.3. unless the wrappingprimitives are used. See RFC 560 for the rationale and more details.3. 6.1. Rust's failure system is not compatible with exception handling in other languages. For example: .1. even in private fields/locals: Dangling/null references or boxes A value other than false(0) or true(1) in a bool A discriminant in an enumnot included in the type definition A value in a charwhich is a surrogate or above char::MAX Non-UTF-8 byte sequences in a str Unwinding into Rust from foreign code or unwinding from Rust into foreign code. the compiler will insert debug checks that panic on overflow.4 Behavior not considered unsafe This is a list of behavior not considered unsafe in Rust terms. In non-optimized builds.

} } This will not compile without the !annotation on my_err.3. It might be necessary to declare a diverging function because as mentioned previously.1. the following code would not typecheck: fn f(i: i32) -> i32 { if i == 42 { return 42. So.4 Extern functions Extern functions are part of Rust's foreign function interface. should control ever enter my_err. since the elsebranch of the conditional in fdoes not return an i32. providing the opposite functionality to external blocks (#external-blocks). extern functions with bodies defined in Rust code can . } We call such functions "diverging" because they never return a value to the caller. the typechecker checks that every control path in a function ends with a return(#return-expressions) or diverging expression. } else { my_err("Bad number!"). Thus the return type on fonly needs to reflect the ifbranch of the conditional. since control will never resume in any context that relies on those judgments.fn my_err(s: &str) -> ! { println!("{}". The !annotation does not denote a type. Adding the !annotation to my_errinforms the typechecker that. 6. Whereas external blocks allow Rust code to call foreign code. Every control path in a diverging function must end with a panic!()or a call to another diverging function on every control path. as required by the signature of f. panic!(). if my_errwere declared without the !annotation. s). no further type judgments about fneed to hold.

An example of a structitem and its use: . the following defines the type Pointas a synonym for the type (u8. For example. except that they have the externmodifier.be called by foreign code. specific type. 6.1. They are defined in the same way as any other Rust function. This is the same type as the functions declared in an extern block.5 Structures A structure is a nominal structure type (#structure-types) defined with the keyword struct. the ABI defaults to "C" extern fn new_i32() -> i32 { 0 } // Declares an extern fn with "stdcall" ABI extern "stdcall" fn new_i32_stdcall() -> i32 { 0 } Unlike normal functions.4 Type aliases A type alias defines a new name for an existing type (#types). the type of pairs of unsigned 8 bit integers: type Point = (u8. or be compatible with several different type constraints. but may implement several different traits. Extern functions may be called directly from Rust code as Rust uses large. u8). contiguous stack segments like C. 68). Every value has a single. let fptr: extern "C" fn() -> i32 = new_i32.1. extern fns have type extern "ABI" fn(). u8). Type aliases are declared with the keyword type. // Declares an extern fn. let p: Point = (41. 6.

11). An example of an enumitem and its use: enum Animal { Dog.1.struct Point {x: i32. let c = [Cookie. let px: i32 = p. 6. . For example: struct Cookie. For example: struct Point(i32. also defined with the keyword struct. Cookie. y: 11}. i32). Cookie]. Enumerations are declared with the keyword enum. that can be used to create or pattern-match values of the corresponding enumerated type.x. let p = Point(10. A tuple structure is a nominal tuple type (#tuple-types). _) => x }. Cookie. The precise memory layout of a structure is not specified. Such types will have a single value.6 Enumerations An enumeration is a simultaneous definition of a nominal enumerated type (#enumerated-types) as well as a set of constructors. y: i32} let p = Point {x: 10. a = Animal::Cat. defined by leaving off the list of fields entirely. One can specify a particular layout using the reprattribute (#ffi-attributes). Cat } let mut a: Animal = Animal::Dog. let px: i32 = match p { Point(x. A unit-like struct is a structure without any fields.

Enumeration constructors can have either named or unnamed fields: enum Animal { Dog (String. . f64).1. whereas Dogis simply called an enum variant. weight: 2.to_string(). References to the same constant are not necessarily guaranteed to refer to the same memory address.2). Cat { name: String. If it were Bar(i32). in order. } If a discriminant isn't assigned.7 }. In this example. a = Animal::Cat { name: "Spotty". meaning that they are copied directly into the relevant context when used. You can assign them explicitly: enum Foo { Bar = 123.to_string(). // x is now 123u32 This only works as long as none of the variants have data attached. they start at zero. Catis a struct-like enum variant. weight: f64 } } let mut a: Animal = Animal::Dog("Cocoa". this is disallowed.7 Constant items A constant item is a named constant value which is not associated with a specific memory location in the program. 37. Constants are essentially inlined wherever they are used. Enums have a discriminant. You can cast an enum to get this value: let x = Foo::Bar as u32. and add one for each variant. 6.

The types of static values must ascribe to Syncto allow threadsafe access. 6. 2] = [BIT1. The type may be bool. a number. Constants must be explicitly typed. so the address referred to may not be stable. const BITS: [u32. 2]. and otherwise permit most forms of data. mystring: STRING }. Static items may be placed in read-only memory if they do not contain any interior mutability. mystring: &'a str } const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings { mybits: BITS. Static items have the static lifetime. enum variants.1. Statics may contain interior mutability through the UnsafeCelllanguage item. Statics may not refer to other statics by value. Constants cannot refer to statics. fixed-size arrays. A static is never "inlined" at the usage site. const STRING: &'static str = "bitstring". The derived types are references with the staticlifetime. The compiler is. and structs. but there are a number of restrictions on statics: Statics may not contain any destructors. const BIT2: u32 = 1 << 1. . BIT2].Constant values must not have destructors. however. struct BitsNStrings<'a> { mybits: [u32. in which case the address will have the staticlifetime. except that it represents a precise memory location in the program. const BIT1: u32 = 1 << 0. and all references to it refer to the same memory location. tuples.8 Static items A static item is similar to a constant. or a type derived from those primitive types. char. only by reference. Constants may refer to the address of other constants. All access to a static is safe. still at liberty to translate the constant many times. which outlives all other lifetimes in a Rust program.

They can be used with C libraries and can also be bound from C libraries (in an externblock).1.1 Mutable statics If a static item is declared with the mutkeyword. or single-address and mutability properties are required. // this function is "safe" but the meaning of the return value may not be what // callers expect. This interface consists of associated items. so it's still marked as `unsafe` unsafe fn bump_levels_unsafe2() -> u32 { return atomic_add(&mut LEVELS.1. } Mutable statics have the same restrictions as normal statics. 6. Care should be taken to ensure that modifications to a mutable static are safe with respect to other threads running in the same process.Constants should in general be preferred over statics. and this is obviously a very large source of race conditions or other bugs. For this reason. } // Assuming that we have an atomic_add function which returns the old value. return ret. however. except that the type of the value is not required to ascribe to Sync.9 Traits A trait describes an abstract interface that types can implement.8. 1). Mutable statics are still very useful. // This violates the idea of no shared state. LEVELS += 1. static mut LEVELS: u32 = 0. which come in three varieties: . and this doesn't internally // protect against races. so this function is `unsafe` unsafe fn bump_levels_unsafe1() -> u32 { let ret = LEVELS. One of Rust's goals is to make concurrency bugs hard to run into. unless large amounts of data are being stored. then it is allowed to be modified by the program. an unsafeblock is required when either reading or writing a mutable static variable. 6.

Traits may also contain additional type parameters..bounding_box()syntax (#method-callexpressions). These are required to be acyclic. using value. fn baz(&self) { println!("We called baz.notation (e. These type parameters (including Self) may be constrained by other traits and so forth as usual. fn bounding_box(&self) -> BoundingBox.g. x. Traits can include default implementations of methods. } This defines a trait with two methods.foo())."). All traits define an implicit type parameter Selfthat refers to "the type that is implementing this interface". Surface).functions constants types Associated functions whose first parameter is named selfare called methods and may be invoked using . Consider the following trait: trait Shape { fn draw(&self. } } . as in: trait Foo { fn bar(&self). Traits are implemented for specific types through separate implementations (#implementations). All values that have implementations (#implementations) of this trait in scope can have their drawand bounding_box methods called. Supertraits are somewhat different from other constraints in that they affect what methods are available in the vtable when the trait is used as a trait object (#traitobjects). Trait bounds on Selfare considered "supertraits".

but it must specify the type E. F) where F: Fn(T). } } Generic functions may use traits as bounds on their type parameters. trait Seq<T> { fn len(&self) -> u32. Self::E). Type parameters can be specified for a trait to make it generic. so types that implement Foo need only implement bar. n: u32) -> T. It is also possible for implementing types to override a method that has a default implementation. } In order for a type to implement this trait. Consider the following example of a Containertrait. the methods of the trait can be called on values that . fn iter<F>(&self.push(x). } It is also possible to define associated types for a trait. Within the generic function.Here the bazmethod has a default implementation. Here's an implementation of Containerfor the standard library type Vec: impl<T> Container for Vec<T> { type E = T. x: T) { self. fn empty() -> Self. it must not only provide implementations for every method. fn empty() -> Vec<T> { Vec::new() } fn insert(&mut self. This will have two effects: Only types that have the trait may instantiate the parameter. fn elt_at(&self. Notice how the type is available for use in the method signatures: trait Container { type E. using the same syntax used in generic functions (#generic-functions). These appear a er the trait name. fn insert(&mut self.

have the parameter's type.
For example:
fn draw_twice<T: Shape>(surface: Surface, sh: T) {
sh.draw(surface);
sh.draw(surface);
}

Traits also define an trait object (#trait-objects) with the same name as the trait.
Values of this type are created by coercing from a pointer of some specific type to a
pointer of trait type. For example, &Tcould be coerced to &Shapeif T: Shape
holds (and similarly for Box<T>). This coercion can either be implicit or explicit
(#type-cast-expressions). Here is an example of an explicit coercion:
trait Shape { }
impl Shape for i32 { }
let mycircle = 0i32;
let myshape: Box<Shape> = Box::new(mycircle) as Box<Shape>;

The resulting value is a box containing the value that was cast, along with
information that identifies the methods of the implementation that was used. Values
with a trait type can have methods called (#method-call-expressions) on them, for
any method in the trait, and can be used to instantiate type parameters that are
bounded by the trait.
Trait methods may be static, which means that they lack a selfargument. This
means that they can only be called with function call syntax ( f(x)) and not method
call syntax ( obj.f()). The way to refer to the name of a static method is to qualify it
with the trait name, treating the trait name like a module. For example:
trait Num {
fn from_i32(n: i32) -> Self;
}
impl Num for f64 {
fn from_i32(n: i32) -> f64 { n as f64 }
}
let x: f64 = Num::from_i32(42);

Traits may inherit from other traits. For example, in
trait Shape { fn area(&self) -> f64; }
trait Circle : Shape { fn radius(&self) -> f64; }

the syntax Circle : Shapemeans that types that implement Circlemust also
have an implementation for Shape. Multiple supertraits are separated by +, trait
Circle : Shape + PartialEq { }. In an implementation of Circlefor a
given type T, methods can refer to Shapemethods, since the typechecker checks
that any type with an implementation of Circlealso has an implementation of
Shape.
In type-parameterized functions, methods of the supertrait may be called on values
of subtrait-bound type parameters. Referring to the previous example of trait
Circle : Shape:
fn radius_times_area<T: Circle>(c: T) -> f64 {
// `c` is both a Circle and a Shape
c.radius() * c.area()
}

Likewise, supertrait methods may also be called on trait objects.
let mycircle = Box::new(mycircle) as Box<Circle>;
let nonsense = mycircle.radius() * mycircle.area();

6.1.10 Implementations
An implementation is an item that implements a trait (#traits) for a specific type.
Implementations are defined with the keyword impl.

struct Circle {
radius: f64,
center: Point,
}
impl Copy for Circle {}
impl Clone for Circle {
fn clone(&self) -> Circle { *self }
}
impl Shape for Circle {
fn draw(&self, s: Surface) { do_draw_circle(s, *self); }
fn bounding_box(&self) -> BoundingBox {
let r = self.radius;
BoundingBox{x: self.center.x - r, y: self.center.y - r,
width: 2.0 * r, height: 2.0 * r}
}
}

It is possible to define an implementation without referring to a trait. The methods
in such an implementation can only be used as direct calls on the values of the type
that the implementation targets. In such an implementation, the trait type and for
a er implare omitted. Such implementations are limited to nominal types (enums,
structs), and the implementation must appear in the same crate as the selftype:
struct Point {x: i32, y: i32}
impl Point {
fn log(&self) {
println!("Point is at ({}, {})", self.x, self.y);
}
}
let my_point = Point {x: 10, y:11};
my_point.log();

When a trait is specified in an impl, all methods declared as part of the trait must
be implemented, with matching types and type parameter counts.

*/ } impl Seq<bool> for u32 { /* Treat the integer as a sequence of bits */ } 6. as shown here: // Interface to the Windows API extern "stdcall" { } The linkattribute allows the name of the library to be specified. just like functions defined in Rust. The Rust compiler automatically translates between the Rust ABI and the foreign ABI.11 External blocks External blocks form the basis for Rust's foreign function interface. #[link(name = "crypto")] extern { } .1. Functions within external blocks may be called by Rust code. non-Rust libraries. with the exception that they may not have a body and are instead terminated by a semicolon. By default external blocks assume that the library they are calling uses the standard C "cdecl" ABI. Implementation parameters are written a er the implkeyword. impl<T> Seq<T> for Vec<T> { /* . Functions within external blocks are declared in the same way as other Rust functions.An implementation can take type parameters. Other ABIs may be specified using an abistring. Declarations in an external block describe symbols in external.. which can be different from the type parameters taken by the trait it implements. When specified the compiler will attempt to link against the native library of the specified name. A number of attributes (#attributes) control the behavior of external blocks..

. PubliclyAccessibleState2. it can be thought of as being accessible to the outside world. Each level in the hierarchy can be thought of as some item. For example: // Declare a private struct struct Foo. To control whether interfaces can be used across modules. everything in Rust is private..Anare the declared types of its arguments and Ris the declared return type. The items are one of those mentioned above. with one exception. This is where privacy warnings are generated. An) -> R.The type of a function declared in an extern block is extern "abi" fn(A1.. where A1." By default.. and what they are attempting to convey is the answer to the question "Can this item be used at this location?" Rust's name resolution operates on a global hierarchy of namespaces. Declaring or defining a new module can be thought of as inserting a new tree into the hierarchy at the location of the definition. Rust checks each use of an item to see whether it should be allowed or not. Enum variants in a pub enum are also public by default. } With the notion of an item being either public or private. but also include external crates.2 Visibility and Privacy These two terms are o en used interchangeably. 6.. or otherwise "you used a private item of another module and weren't allowed to. // Declare a public struct with a private field pub struct Bar { field: i32 } // Declare a public enum with two public variants pub enum State { PubliclyAccessibleState. When an item is declared as pub.. Rust allows item accesses in two cases: .

path expressions and import statements are considered to access an item in the sense that the import/expression is only valid if the destination is in the current visibility scope. Accessing a module. This module could access any items of the parent module through the second case. would mean looking inside of it (to import more items). As a consequence of the first case. These two cases are surprisingly powerful for creating module hierarchies exposing public APIs while hiding internal implementation details. When writing unit tests for a module. for example. Because the entire crate is a descendant of the root. accessing a function would mean that it is invoked. If an item is public. here's a few use cases and what they would entail: A library developer needs to expose functionality to crates which link against their library. To accomplish this. but it doesn't want to expose the helper module as a public API. the root of the crate's hierarchy would have a private module which then internally has a "public api". If an item is private. it mentions that a private item "can be accessed" by the current module and its descendants. then it can be used externally through any of its public ancestors. Here's an example of a program which exemplifies the three cases outlined above: . Additionally. but the exact meaning of accessing an item depends on what the item is.1. To help explain. then the entire local crate can access this private module through the second case. Any private item in the chain will disallow external accesses. it's o en a common idiom to have an immediate child of the module to-be-tested named mod test. A crate needs a global available "helper module" to itself. In the second case. meaning that internal implementation details could also be seamlessly tested from the child module. 2. this means that anything which is usable externally must be pubfrom the root down to the destination item. On the other hand. it may be accessed by the current module and its descendants.

pub fn my_method() { // Any item in the local crate may invoke the helper module's public // interface through a combination of the two rules above. all paths must be valid accesses given the two rules above. however. } } } For a rust program to pass the privacy checking pass. This includes all use statements. super::my_implementation().// This module is private. so only this // current module and its descendants may access it. pub fn public_api() {} // Similarly to 'public_api'. it's allowed // to access private items inside of `submodule` without a privacy // violation. It is not // publicly visible outside of the `crate_helper_module`. pub mod submodule { use crate_helper_module. meaning that no external crate can access this // module. } // This function is hidden to any module which is not a descendant of // `submodule` fn my_implementation() {} #[cfg(test)] mod test { #[test] fn test_my_implementation() { // Because this module is a descendant of `submodule`. mod crate_helper_module { // This function can be used by anything in the current crate pub fn crate_helper() {} // This function *cannot* be used by anything else in the crate. Because it is private at the root of this current crate. expressions. . fn implementation_detail() {} } // This function is "public to the root" meaning that it's available to external // crates linking against this one. crate_helper_module::crate_helper(). any // module in the crate may access any publicly visible item in this module. this module is public so external crates may look // inside of it.

6. An attribute is a general. while the path api::fwould be allowed.1 Re-exporting and Visibility Rust allows publicly re-exporting items through a pub usedirective.types. mod implementation { pub mod api { pub fn f() {} } } This means that any external crate referencing implementation::api::fwould receive a privacy violation. convention. this allows the item to be used in the current module through the rules above. Attributes in Rust are modeled on Attributes in ECMA-335. it can be thought of as allowing the "privacy chain" being short-circuited through the reexport instead of passing through the namespace hierarchy as it normally would. Attributes may appear as any of: A single identifier. For example.3 Attributes Any item declaration may have an attribute applied to it. and language and compiler version. providing a key/value pair An identifier followed by a parenthesized list of sub-attribute arguments . It essentially allows public access into the re-exported item. this program is valid: pub use self::implementation::api. When re-exporting a private item. etc. 6.2. free-form metadatum that is interpreted according to name. with the syntax coming from ECMA-334 (C#). the attribute name An identifier followed by the equals sign '=' and a literal. Because this is a public directive.

An example of attributes: // General metadata applied to the enclosing module or crate.Attributes with a bang ("!") a er the hash ("#") apply to the item that the attribute is declared within..disable optimizing certain code patterns to invocations of library functions that are assumed to exist no_main. no_start. */ } // A conditionally-compiled module #[cfg(target_os="linux")] mod bar { /* ..see linkage.see compiler features. the compiler will distinguish between languagereserved and user-available attributes. Until then. #![crate_type = "lib"] // A function marked as a unit test #[test] fn test_foo() { /* . which specifies the "start" .1 Crate-only attributes crate_name. */ } // A lint attribute used to suppress a warning/error #[allow(non_camel_case_types)] type int8_t = i8.3.specify the crate's crate name. feature.disable emitting the mainsymbol. Note: At some point in the future. there is effectively no difference between an attribute handled by a loadable syntax extension and the compiler. Useful when some other object being linked to defines main.. Attributes that do not have a bang a er the hash apply to the item that follows the attribute. no_builtins. 6. crate_type.disable linking to the nativecrate..

6.e.rs */ }.specifies the file to load the module from. this signals that the value of this static may change depending on the current thread.mark this function as the registration point for compiler plugins.rs"] mod bar. #[path="foo.disable injecting use std::prelude::*in this module.3.language item. rather than the function in the crate root named main. See the "start" language item for more details.3 Function-only attributes main. The pluginfeature gate is required to use this attribute. 6. plugin— load a list of named crates as compiler plugins.indicates that this test function should panic. to only be compiled in case of --test. args .g. #! [plugin(foo.indicates that this function is a test function.on a static mut. bar)].indicates that this function should be passed to the entry point.4 Static-only attributes thread_local. #! [plugin(foo(..3.is equivalent to mod bar { /* contents of foo. path. The path is taken relative to the directory that the current module is in.2 Module-only attributes no_implicit_prelude. plugin_registrar. are provided to the plugin's registrar function.. overriding the "start" language item. cold. Optional arguments for each plugin. inverting the success condition. i. so optimize it (and calls to it) differently.))]. e. such as loadable syntax extensions. no_std.The function is unlikely to be executed. The exact consequences of this are implementation-defined...disable linking to the stdcrate. . start. 6.3. test.indicates that this function should be used as the entry point. should_panic.

on a static. and framework. which specifies that it should be the default enumsize of the C ABI for that platform. static. Takes one argument. which is the primitive type this enum should be represented for.3. and packedwill remove any padding between fields (note that this is very fragile and may break platforms which require aligned access). Takes a list of options. and this may be incorrect when the C code is compiled with certain flags. This is feature gated and the exact behavior is implementation-defined (due to variety of linker invocation syntax). Two examples: #[link(name = "readline")]and # [link(name = "CoreFoundation". On enums: repr.6. which may be combined. The currently accepted ones are Cand packed. or C.on C-like enums.specify arguments to the linker. linkage. this sets the underlying type used for representation. On structs: repr. linksupports an optional kindkey with three possible values: dylib.indicate that a native library should be linked to for the declarations in this block to be linked correctly. kind = "framework")].3.5 FFI attributes On an externblock.6 Macro-related attributes . 6. link. this specifies the linkage type. the following attributes are interpreted: link_name. See external blocks for more about external blocks. On declarations inside an externblock.the name of the symbol that this function or static should be imported as. rather than just the library name and type. Cwill use a C ABI compatible struct layout. Note that enum representation in C is undefined. the following attributes are interpreted: link_args.specifies the representation to use for this struct.

packed. remove the flag that prevents destructors from being run twice.on any item. if any. unsafe_no_drop_flag. this determines the name of the exported symbol.on certain tuple structs. doc. not inside mod.html#scoping-and-macroimport/export) for more information on macro scope. the simdfeature gate is necessary to use this attribute. Set the symbol for this item to its identifier.on structs or enums. no_mangle. which lower to the target's SIMD instructions. a er this module has been included. this specifies the section of the object file that this item's contents will be placed into. bar)]restricts the import to just those macros named. simd. macro_export.export a macro for cross-crate usage. An optional list of names #[macro_use(foo. macro_useon an extern crate— load macros from this crate. link_section. which ensures proper function of the $cratemacro variable (book/macros. The extern cratemust appear at the crate root. do not apply the standard name mangling.Doc comments such as /// fooare equivalent to #[doc = "foo"]. don't link it into the output.html#the-variable-$crate). eliminate any padding that would be used to align fields.on statics and functions.3. See the macros section of the book (book/macros. derive the arithmetic operators. 6.macro_useon a mod— macros defined in this module will be visible in the module's parent. . Destructors might be run multiple times on the same object with this attribute.7 Miscellaneous attributes export_name. no_linkon an extern crate— even if we load this crate for macros.on structs. macro_reexporton an extern crate— re-export the named macros. To use this.on statics and functions. the unsafe_no_drop_flagfeature gate must be enabled.

depending on build target.. only compiler-defined configuration options can have the latter form. the on_unimplementedfeature gate must be enabled. } // This function is only included when compiling for a unixish OS with a 32-bit // architecture #[cfg(all(unix. target_pointer_width = "32"))] fn on_32bit_unix() { // . To use this. such as targeted operating system.. There are two kinds of configuration options. {Self}will be replaced with the type that is supposed to implement the trait but doesn't.rustc_on_unimplemented. } // This function is only included when foo is not defined #[cfg(not(foo))] fn needs_not_foo() { // . // The function is only included in the build when compiling for OSX #[cfg(target_os = "macos")] fn macos_only() { // . Currently. one that is either defined or not ( # [cfg(foo)]). 6.. } // This function is only included when either foo or bar is defined #[cfg(any(foo.3.. You may use format arguments like {T}. {A}to correspond to the types at the point of use corresponding to the type parameters of the trait of the same name. and the other that contains a string that can be checked against ( # [cfg(bar = "baz")]).Write a custom note to be shown along with the error when the trait is found to be unimplemented on a type....8 Conditional compilation Sometimes one wants to have different compiler outputs from the same code. } . bar))] fn needs_foo_or_bar() { // .. or to enable release builds.

9 Lint check attributes A lint check names a potentially undesirable coding pattern. For example. like unixor windows.. "linux".3.. Endianness of the target CPU. such as unreachable code or omitted documentation.". target_family = ". unix. and likewise set to "64"for 64-bit pointers. "macos"..". This can be used to enable extra debugging code in development but not in production. it controls the behavior of the standard library's debug_assert!macro.)]attribute. any. Operating system family of the target.. Operating system of the target. The value of this configuration option is defined as a configuration itself. windows. "freebsd".. target_endian = ".". "android". Target pointer width in bits. . Enabled by default when compiling without optimizations. target_pointer_width = ". examples include "windows". "x86_64" "mips". "dragonfly".". and nothing otherwise. either "little"or "big". alland notcan be used to assemble arbitrarily complex configurations through nesting. for the static entity to which the attribute applies. such as "x86". 6. target_os = "... This is set to "32"for targets with 32-bit pointers. "bitrig"or "openbsd". You can also set another attribute based on a cfgvariable with cfg_attr: #[cfg_attr(a. e. The following configurations must be defined by the implementation: debug_assertions. or "aarch64". target_arch = ". See target_family.. "unix" or "windows". "powerpc".. g. Target CPU architecture... "ios".This illustrates some conditional compilation can be achieved using the # [cfg(. b)] Will be the same as #[b]if ais set by cfg.". See target_family. "arm"..

For any lint check C: allow(C)overrides the check for Cso that violations will go unreported. deny(C)signals an error a er encountering a violation of C. mod m1 { // Missing documentation is ignored here #[allow(missing_docs)] pub fn undocumented_one() -> i32 { 1 } // Missing documentation signals a warning here #[warn(missing_docs)] pub fn undocumented_too() -> i32 { 2 } // Missing documentation signals an error here #[deny(missing_docs)] pub fn undocumented_end() -> i32 { 3 } } This example shows how one can use allowand warnto toggle a particular check on and off: .html#lintplugins) can provide additional lint checks. along with their default settings. warn(C)warns about violations of Cbut continues compilation. but also forbids changing the lint level a erwards. Compiler plugins (book/compiler-plugins. forbid(C)is the same as deny(C). The lint checks supported by the compiler can be found via rustc -W help.

The definitions of these operations have to be easy for the compiler to find. #[warn(missing_docs)] pub fn undocumented_two() -> i32 { 2 } } // Missing documentation signals a warning here pub fn undocumented_too() -> i32 { 3 } } This example shows how one can use forbidto disallow uses of allowfor that lint check: #[forbid(missing_docs)] mod m3 { // Attempting to toggle warning signals an error here #[allow(missing_docs)] /// Returns 2. b: &str) -> bool { // details elided } . The langattribute makes it possible to declare these operations.3. the strmodule in the Rust standard library defines the string equality function: #[lang = "str_eq"] pub fn eq_slice(a: &str. rather than being implemented directly in C or assembly language. For example. // despite the allow above. pub fn undocumented_too() -> i32 { 2 } } 6.#[warn(missing_docs)] mod m2{ #[allow(missing_docs)] mod nested { // Missing documentation is ignored here pub fn undocumented_one() -> i32 { 1 } // Missing documentation signals a warning here.10 Language items Some primitive Rust operations are defined in Rust code.

Clone)] struct Foo<T> { a: i32. the following will create an implfor the PartialEqand Clonetraits for Foo.12 derive The deriveattribute allows certain traits to be automatically implemented for data structures. 6. For example.3. #[inline]and #[inline(always)]always cause the function to be serialized into the crate metadata to allow cross-crate inlining. The compiler automatically inlines functions based on internal heuristics. There are three different types of inline attributes: #[inline]hints the compiler to perform an inline expansion. #[inline(always)]asks the compiler to always perform an inline expansion.3. The set of language items is currently considered unstable. A complete list of the built-in language items will be added in the future. the type parameter Twill be given the PartialEqor Clone constraints for the appropriate impl: #[derive(PartialEq. b: T } . rather than generating code to call the function or access the static where it is defined.11 Inline attributes The inline attribute suggests that the compiler should place a copy of the function or static in the caller. 6.The name str_eqhas a special meaning to the Rust compiler. so it should be used with care. and the presence of this definition means that it will use this definition when generating calls to the string equality function. Incorrectly inlining functions can actually make the program slower. #[inline(never)]asks the compiler to never perform an inline expansion.

The currently implemented features of the reference compiler are: advanced_slice_patterns.b == other.a && self.3.a == other.See the match expressions (#match-expressions) section for discussion. other: &Foo<T>) -> bool { self.b } fn ne(&self.a || self. actually.OK. and feature3should all be enabled. feature2. Without this directive. slice_patterns. but they're not necessarily ready for every-day use. For this reason. Rust recognizes a special crate-level attribute of the form: #![feature(feature1. other: &Foo<T>) -> bool { self. the exact semantics of slice patterns are subject to change. so some types are still unstable.b != other.a != other. These features are o en of "prototype quality" or "almost production ready". . not at a module-level.The generated implfor PartialEqis equivalent to impl<T: PartialEq> PartialEq for Foo<T> { fn eq(&self. slice patterns are just scary and completely unstable.13 Compiler Features Certain aspects of Rust may be implemented in the compiler.b } } 6. feature2. This is only recognized at a crate-level. and using the features will result in a compiler error. but may not be stable enough to be considered a fullfledged language feature. feature3)] This directive informs the compiler that the feature list: feature1. all features are considered off.

but the exact syntax for this feature along with its semantics are likely to change. which is in many ways insufficient for concatenating identifiers.Allows the usage of attributes unknown to the compiler so that new attributes can be added in a backwards compatible manner (RFC 572). concat_idents. custom_attribute.Allows the use of #[derive(Foo. and may be removed entirely for something more wholesome. custom_derive.asm.This attribute is used to specify custom flags to the linker. which can be user-defined syntax extensions.Allows use of the "rust-intrinsics" ABI. intrinsics. .Allows boxpatterns.Allows constants to be defined in impland trait blocks.Allows use of the concat_identsmacro. This is o en useful.Allows use of boxexpressions. link_args. but usage is strongly discouraged.The asm!macro provides a means for inline assembly. Like intrinsics.Allows use of the #[lang]attribute. box_syntax. lang_items. lang items are inherently unstable and no promise about them is made. box_patterns. and if the system linker is not used then specifying custom flags doesn't have much meaning. the exact semantics of which is subject to change. The compiler's usage of the system linker is not guaranteed to continue in the future.*"]. Compiler intrinsics are inherently unstable and no promise about them is made.Bar)]as sugar for # [derive_Foo] #[derive_Bar]. link_llvm_intrinsics– Allows linking to LLVM intrinsics via # [link_name="llvm. the exact semantics of which is subject to change. so that they can be associated with a type or trait in a similar manner to methods and associated types. associated_consts. so this macro usage must be opted into.

Usage of compiler plugins (book/compiler-plugins. such as libcore and libcollections.html). This typically requires use of the unstable APIs behind the libstd "facade". quote.The compiler supports the use of non-ascii identifiers.Allows use of the log_syntaxmacro attribute. . which disables the implicit extern crate std.Allows the definition of default and negative trait implementations. but the implementation is a little rough around the edges.Allows use of the linkageattribute. This capability is subject to change. which is not portable. plugin_registrar.html) for custom lints or syntax extensions.Allows the #![no_std]crate attribute. optin_builtin_traits. log_syntax. which allows trait definitions to add specialized notes to error messages when an implementation was expected but not found.linkage. which are implemented very poorly and will likely change significantly with a proper implementation. on_unimplemented. which changes the entry point into a Rust program. This feature was originally designed with the sole use case of the Rust standard library in mind.Allows the #[rustc_on_unimplemented]attribute. non_ascii_idents. These depend on compiler internals and are subject to change.Indicates that a crate provides compiler plugins (book/compiler-plugins. It may also cause problems when using syntax extensions. which is a nasty hack that will certainly be removed. Experimental. macro_reexport.Allows use of the quote_*!family of macros. so this can be seen as an experimental feature for now until the specification of identifiers is fully fleshed out. plugin.Allows use of the #[main]attribute. no_std. and is subject to change. including #[derive].Allows macros to be re-exported from one crate a er being imported from another. main.

struct_variant. used in the implementation of rustc.Structural enum variants (those with named fields).Allows using struct inheritance. not meant for mortals. Stability markers are also attributes: #[stable]. Don't use this. and usage of it is discouraged. which is barely implemented and will probably be removed. It is currently unknown whether this style of enum variant is as fully supported as the tuple-forms. #[unstable].The usage of the #[thread_local]attribute is experimental and should be seen as unstable. staged_api. simd. thread_local. This capability.Allows use of SIMD vectors in signatures for foreign functions. which is overly simple and not the SIMD interface we want to expose in the long term. simd_ffi. and # [deprecated]are the three levels. rustc_diagnostic_macros. and it's not certain that this style of variant should remain in the language. The SIMD interface is subject to change.Allows use of the #[simd]attribute. is subject to change. struct_inherit.A mysterious feature.Gates internal #[rustc_*]attributes which may be for internal use only or have meaning added to them in the future. especially the signature for the annotated function. This attribute is used to declare a staticas being unique per-thread leveraging LLVM's implementation which works in concert with the kernel loader and dynamic linker.Allows usage of stability markers and #![staged_api]in a crate. start. which is a nasty hack that will certainly be removed.rustc_attrs.Allows use of the #[start]attribute. which changes the entry point into a Rust program. trace_macros. .Allows use of the trace_macrosmacro. This is not necessarily available on all platforms. For now this style of variant is hidden behind a feature flag.

Allows use of the #[unsafe_no_drop_flag] attribute. e. which removes hidden flag added to a type that implements the Drop trait. This capability may be removed in the future. which is currently a work in progress feature with many known bugs. The design for the Dropflag is subject to change. Such items should not be allowed by the compiler to exist. An unknown feature is one which has never been recognized by the compiler. This means that most forms of valueproducing or effect-causing evaluation are directed by the uniform syntax category of expressions. allow_internal_unstable. However.unboxed_closures. visible_private_types.Allows use of items within a #![staged_api]crate which have not been marked with a stability marker. unsafe_no_drop_flag. unmarked_api. If a feature is promoted to a language feature. as the return type of a public function. then all existing programs will start to receive compilation warnings about #![feature]directives which enabled the new feature (because the directive is no longer necessary).Allows public APIs to expose otherwise private types.g.e. errors will be issued (if there isn't a parser error first). 7 Statements and expressions Rust is primarily an expression language. If an unknown feature is found in a directive. it results in a compiler error. The directive in this case is no longer necessary. if a feature is decided to be removed from the language. Each kind of expression can typically nest within each other kind of .Allows macro_rules!macros to be tagged with the #[allow_internal_unstable]attribute. making them behave like function calls in terms of encapsulation). so if you need this there probably is a compiler bug. designed to allow std macros to call #[unstable]/feature-gated functionality internally without imposing on callers (i. and it's likely that existing code will break if the feature isn't removed. and this feature may be removed in the future.Rust's new closure design.

7. the compiler will infer the type.1. trait.expression. The declared names may denote new variables or new items.1.1. and rules for evaluation of expressions involve specifying both the value produced by the expression and the order in which its sub-expressions are themselves evaluated. or signal an error if .1 Declaration statements A declaration statement is one that introduces one or more names into the enclosing statement block. 7. statements in Rust serve mostly to contain and explicitly sequence expression evaluation. When no type annotation is given. structure.1. implementation or module — locally within a statement block is simply a way of restricting its scope to a narrow region containing all of its uses. which is in turn a component of an outer expression (#expressions) or function (#functions). enumeration. static. Note: there is no implicit capture of the function's dynamic environment when declaring a function-local item. Declaring an item — a function.1 Statements A statement is a component of a block. and/or an initializer expression.1. type.2 Variable declarations A variable declaration introduces a new set of variable. 7. it is otherwise identical in meaning to declaring the item outside the statement block.1 Item declarations An item declaration statement has a syntactic form identical to an item (#items) declaration within a module. The pattern may be followed by a type annotation. given by a pattern. In contrast. 7. Rust has two kinds of statement: declaration statements (#declaration-statements) and expression statements (#expression-statements).

and blocks again can recursively nest inside each other to an arbitrary depth.0.insufficient type information is available for definite inference. dereferences ( *expr). 7.2. 7. Blocks are just another kind of expression. regardless of the type of e. expressions. indexing expressions (#index- . The type of an expression statement e.2 Expression statements An expression statement is one that evaluates an expression (#expressions) and ignores its result. The evaluation of an expression depends both on its own category and the context it occurs within.2 Expressions An expression may have two roles: it always produces a value. Any variables introduced by a variable declaration are visible from the point of declaration until the end of the enclosing block scope.1 Lvalues. As a rule. Likewise within each expression.is always (). or static variables). An lvalue is an expression that represents a memory location. sub-expressions may occur in lvalue context or rvalue context. and has effects during evaluation. These expressions are paths (#path-expressions) (which refer to local variables. function and method arguments. The meaning of each kind of expression dictates several things: Whether or not to evaluate the sub-expressions when evaluating the expression The order in which to evaluate the sub-expressions How to combine the sub-expressions' values to obtain the value of the expression In this way. so blocks.1. statements. an expression statement's purpose is to trigger the effects of evaluating its expression. An expression evaluates to a value. and it may have effects (otherwise known as "side effects"). 7. the structure of expressions dictates the structure of execution. rvalues and temporaries Expressions are divided into two main categories: lvalues and rvalues. Many expressions contain sub-expressions (operands).

foo(). if ref bindings are made. and therefore deserve a longer temporary lifetime. as is the single operand of a unary borrow (#unary-operator-expressions). but the temporary would be freed before the variable could be used). when evaluated in an rvalue context. Here are some examples: let x = foo(&temp()).expressions) ( expr[expr]). however.0. the tail expression of a block is considered part of the statement that encloses the block. In . say Foo. 7. Here we are assuming that foo()is an &selfmethod defined in some trait. The expression temp()is an rvalue. let x = temp(). it denotes a memory location.f). When an lvalue is evaluated in an lvalue context. the temporary is created with the lifetime of the enclosing block instead.2. This is the same as the previous example. All other expressions are rvalues. a temporary is created which will be freed a er the innermost enclosing statement (the letdeclaration. The discriminant or subject of a match expression (#match-expressions) may be an lvalue context. The le operand of an assignment (#assignment-expressions) or compoundassignment (#compound-assignment-expressions) expression is an lvalue context. and field references (#field-expressions) ( expr. When a temporary rvalue is being created that is assigned into a letdeclaration. it denotes the value held in that memory location.1 Temporary lifetimes When an rvalue is used in an lvalue context. except that the value of temp()is being borrowed via autoref on a method-call. a temporary un-named lvalue is created and used instead. as using the enclosing statement (the letdeclaration) would be a guaranteed error (since a pointer to the temporary would be stored into a variable. All other expression contexts are rvalue contexts. but is otherwise an rvalue context. As it is being borrowed. The lifetime of temporary values is typically the innermost enclosing statement. The compiler uses simple syntactic rules to decide which values are being assigned into a letbinding.1. in this case).

depending on its type.2 Path expressions A path (#paths) used as an expression context denotes either a local variable or an item. boolean value. character. 5. Here. all others are moved.2 Moved and copied types When a local variable (#variables) is used as an rvalue (#lvalues.1 Literal expressions A literal expression consists of one of the literal (#literals) forms described earlier. let x = &temp().-rvalues-and-temporaries).other words. the temporary is created using a ref binding. All values whose type implements Copyare copied. "hello". the temporary is assigned into a struct which is then assigned into a binding. or the unit value.2. '5'. 7. // unit type // string type // character type // integer type 7.2. and hence it is given the lifetime of the enclosing block. let x = SomeStruct { foo: &temp() }.-rvalues-andtemporaries) the variable will either be moved or copied.3 Tuple expressions . the same temporary is being assigned into x. 7.2.foo()is equivalent to Foo::foo(&temp()). but the result is the same: the lifetime is extended to the enclosing block. and hence the temporary's lifetime is considered to be the enclosing block.2. In this case. and hence it is given the lifetime of the enclosing block. It directly describes a number. the expression temp(). ().0. As in the previous case. the temporary is assigned into an array which is then assigned into a binding. let ref x = temp(). string. let x = [ &temp() ]. 7. Path expressions are lvalues (#lvalues. As in the previous case. rather than being passed as a parameter.

some_fn::<Cookie>(Cookie).0.Tuples are written by enclosing zero or more comma-separated expressions in parentheses. A structure expression consists of the path (#paths) of a structure item (#structures). // single-element tuple (0). followed by a brace-enclosed list of one or more comma-separated name-value pairs. 4usize. 4.2.0. . 20. true). followed by a parenthesized list of one or more comma-separated expressions (in other words.4 Structure expressions There are several forms of structure expressions. You can disambiguate a single-element tuple from a value in parentheses with a comma: (0. A field name can be any identifier. the path of a structure item followed by a tuple expression). // zero in parentheses 7.0. The following are examples of structure expressions: Point {x: 10. score: 100_000}. let u = game::User {name: "Joe". The location denoted by a structure field is mutable if and only if the enclosing structure is mutable.). A tuple structure expression consists of the path (#paths) of a structure item (#structures). ("a".5).0}. They are used to create tuple-typed (#tuple-types) values. y: 20.0). and is separated from its value expression by a colon. providing the field values of a new instance of the structure. age: 35. TuplePoint(10. A unit-like structure expression consists only of the path (#paths) of a structure item (#structures). The structure item must be a tuple structure item. (0.

x). A structure expression can terminate with the syntax . and then execute the expression (if given). The expression following .2. this will always be the same value.followed by an expression to denote a functional update. The entire expression denotes the result of constructing a new structure (with the same type as the base expression) with the given values for the fields that were explicitly specified and the values in the base expression for all other fields. }. Each block conceptually introduces a new namespace scope.(the base) must have the same structure type as the new structure type being formed.5 Block expressions A block expression is similar to a module in terms of the declarations that are possible. If it ends in an expression. 7. y: 2.2.."). Note that for a given unit-like structure type. If the block ends in a statement. its value is (): let x: () = { println!("Hello. z: 10. Point3d {y: 0. 7. base}. assert_eq!(5.6 Method-call expressions .").. .. z: 3}. its value and type are that of the expression: let x: i32 = { println!("Hello. A block will execute each statement sequentially. 5 }.A structure expression forms a new value of the named structure type. Use items can bring new names into scopes and declared items are in scope for only the block itself. let base = Point3d {x: 1.

b: 20}).-and-slice-types) expression is written by enclosing zero or more comma-separated expressions of uniform type in square brackets. it is automatically dereferenced as many times as necessary to make the field access possible.x. In the [expr '. it can be assigned (#assignment-expressions) to. A field access is an lvalue (#lvalues. When the type providing the field inherits mutability. mystruct.' expr]form.-rvalues-and-temporaries) referring to the value of that field. Method calls are resolved to methods on specific traits. 7. the expression a er the '.8 Array expressions An array (#array.2.7 Field expressions A field expression consists of an expression followed by a single dot and an identifier. when not immediately followed by a parenthesized expression-list (the latter is a method call expression (#method-call-expressions)). we prefer fewer autoderefs to more. an identifier.a.A method call consists of an expression followed by a single dot. such as a literal (#literals) or a static item (#static-items). or dynamically dispatching if the le -hand-side expression is an indirect trait object (#trait-objects). either statically dispatching to a method if the exact self-type of the le hand-side is known. (Struct {a: 10. and a parenthesized expression-list. foo().myfield. . if the type of the expression to the le of the dot is a pointer. In cases of ambiguity. A field expression denotes a field of a structure (#structure-types).'must be a constant expression that can be evaluated at compile time. 7.2. Also.

"b"])[n]. 3. let x = (["a". Indices are zero-based.2. // compiler error: const index-expr is out of bounds let n = 10. 2.2. 4]. 0u8]. 1. 3. ([1. 7. and may be of any integral type. // panics let arr = ["a".. In cases of ambiguity. arr[10].operator will construct an object of one of the std::ops::Rangevariants. ["a".9 Index expressions Array (#array. [0. 0u8.10 Range expressions The .-rvalues-and-temporaries) can be assigned to. let y = (["a".4. it is automatically dereferenced as many times as necessary to make the indexing possible. 3.. "d"].2. Otherwise a check will be performed at run-time that will put the thread in a panicked state if it fails. 2. . . // panics Also. When the array is mutable.[1. "b". "c". "b"])[10]. 4])[0]. we prefer fewer autoderefs to more. 128]. 7.. Vector access is boundschecked at compile-time for constant arrays being accessed with a constant index value.... if the type of the expression to the le of the brackets is a pointer. "b"]. 0u8.-and-slice-types)-typed expressions can be indexed by writing a squarebracket-enclosed expression (the index) a er them. the resulting lvalue (#lvalues. // array with 128 zeros [0u8. // std::ops::Range // std::ops::RangeFrom // std::ops::RangeTo // std::ops::RangeFull ..

the resulting lvalue can be assigned to. If the &or &mutoperators are applied to an rvalue. this implies that the lvalue may not be mutated. but it may be read or shared again.11 Unary operator expressions Rust defines the following unary operators.12 Binary operator expressions Binary operators expressions are given in terms of operator precedence (#operatorprecedence). 7. end: 10}. *: Dereference. let x = std::ops::Range {start: 0. On integer types. On nonpointer types. The lvalue is also placed into a borrowed state for the duration of the reference. When applied to an lvalue. let y = 0.10. For a mutable borrow ( &mut).y). or the deref_mutmethod of the std::ops::DerefMuttrait (if implemented by the type and required for an outer expression that will or could mutate the dereference). a temporary value is created. the lvalue may not be accessed in any way until the borrow expires. -: Negation.2. . assert_eq!(x. before the expression they apply to. !: Logical negation. May only be applied to numeric types. it calls the derefmethod of the std::ops::Dereftrait. On the boolean type. the lifetime of this temporary value is defined by syntactic rules. They are all written as prefix operators. For pointers to mutable locations.The following expressions are equivalent. 7. this inverts the individual bits in the two's complement representation of the value. When applied to a pointer it denotes the pointed-to location.. For a shared borrow ( &). these operators produce a reference (pointer) to the lvalue. &and &mut: Borrowing.2. and produces the result of dereferencing the &or &mutborrowed pointer returned from the overload method. this flips between trueand false.

This means that bitwise operators can be overridden for user-defined types.3 Lazy boolean operators The operators ||and &&may be applied to operands of boolean type. Calls the addmethod on the std::ops::Addtrait. +: Addition and array/string concatenation. Calls the bitormethod of the std::ops::BitOr trait. |and ^applied to boolean arguments are equivalent to logical &&.2. Calls the bitandmethod of the std::ops::BitAndtrait.12.2. Calls the shlmethod of the std::ops::Shltrait. Calls the divmethod on the std::ops::Divtrait.2. and the &&operator denotes logical 'and'. 7. *: Multiplication. -: Subtraction. Calls the remmethod on the std::ops::Remtrait. |: Bitwise inclusive OR.12. /: Quotient.2 Bitwise operators Like the arithmetic operators (#arithmetic-operators). Calls the mulmethod on the std::ops::Multrait. Calls the shrmethod of the std::ops::Shrtrait. defined in the std::opsmodule of the stdlibrary.7. The default meaning of the operators on standard types is given here. %: Remainder. <<: Le shi . Calls the submethod on the std::ops::Subtrait. This means that arithmetic operators can be overridden for user-defined types. Calls the bitxormethod of the std::ops::BitXor trait. ||and !=evaluated in non-lazy fashion. 7. The default meaning of the operators on standard types is given here. They differ from |and &in that the right-hand operand is only evaluated when the le -hand .12. ^: Bitwise exclusive OR.1 Arithmetic operators Binary arithmetic expressions are syntactic sugar for calls to built-in traits. >>: Right shi (arithmetic). The || operator denotes logical 'or'. bitwise operators are syntactic sugar for calls to methods of built-in traits. &: Bitwise AND. Bitwise &.

Calls the gtmethod on the std::cmp::PartialOrdtrait. and &&only when it evaluates to true. Calls the ltmethod on the std::cmp::PartialOrdtrait. That is.operand does not already determine the result of the expression.5 Type cast expressions A type cast expression is denoted with the binary operator as. and bitwise operators (#bitwise-operators). >=: Greater than or equal.2. let size: f64 = len(values) as f64. Calls the lemethod on the std::cmp::PartialOrd trait. Calls the eqmethod on the std::cmp::PartialEqtrait. ==: Equal to.12. The default meaning of the operators on standard types is given here. This means that comparison operators can be overridden for user-defined types.2. <=: Less than or equal. 7. <: Less than. 7.4 Comparison operators Comparison operators are. >: Greater than. ||only evaluates its right-hand operand when the le -hand operand evaluates to false. !=: Unequal to. sum / size } . Calls the gemethod on the std::cmp::PartialOrdtrait. Executing an asexpression casts the value on the le -hand side to the type on the right-hand side. syntactic sugar for calls to built-in traits. Calls the nemethod on the std::cmp::PartialEqtrait. like the arithmetic operators (#arithmetic-operators). An example of an asexpression: fn average(values: &[f64]) -> f64 { let sum: f64 = sum(values).12.

such as argument passing and assignment to a letbinding with an explicit type. -. *. For example. ^. /. 7.2. 7.12. Evaluating an assignment expression either copies or moves (#moved-and-copiedtypes) its right-hand operand to its le -hand operand. <<. Implicit conversions are limited to "harmless" conversions that do not lose information and which have minimal or no risk of surprising side-effects on the dynamic execution semantics.12. and >>operators may be composed with the = operator. Any such expression always has the unit(#tuple-types) type. |. The expression lval OP= valis equivalent to lval = lval OP val.8 Operator precedence The precedence of Rust binary operators is ordered as follows. going from strong to weak: .-rvalues-andtemporaries) expression.2. &.-rvalues-and-temporaries) expression followed by an equals sign ( =) and an rvalue (#lvalues. x = y. x = x + 1may be written as x += 1.6 Assignment expressions An assignment expression consists of an lvalue (#lvalues.7 Compound assignment expressions The +. %.Some of the conversions which can be done through the asoperator can also be done implicitly at various points in the program. 7.12.2.

let pi: Result<f32. Parentheses can be used to explicitly specify evaluation order within an expression. .parse(). 7. Operators at the same precedence level are evaluated le -to-right. _> = "3.2. providing zero or more input variables and an optional location to move the function's output into.14 Call expressions A call expression invokes a function. 7. An example of a parenthesized expression: let x: i32 = (2 + 3) * 4. 2i32). then the expression completes.as */% +<< >> & ^ | == != < > <= >= && || = .2. If the function eventually returns.14". Some examples of call expressions: let x: i32 = add(1i32.. Unary operators (#unary-operator-expressions) have the same precedence level and are stronger than any of the binary operators.13 Grouped expressions An expression enclosed in parentheses evaluates to the result of the enclosed expression.

These parameters' types need not be specified. the compiler may infer that a lambda expression should copy or move values (depending on their type) from the environment into the lambda expression's captured environment. The exact type of capture depends on the function type (#function-types) inferred for the lambda expression. Lambda expressions are most useful when passing functions as arguments to other functions.16 In nite loops .2. as an abbreviation for defining and capturing a separate function. in a single expression. which regular function definitions (#functions) do not. The identifiers in the ident_listare the parameters to the function. j)).7.15 Lambda expressions A lambda expression (sometimes called an "anonymous function expression") defines a function and denotes it as a value. 7.2. In the simplest and leastexpensive form (analogous to a || { }expression). i += 1. while i < 10 { f(i). we define a function ten_timesthat takes a higher-order function argument. the lambda expression captures its environment by reference. A lambda expression is a pipe-symbol-delimited ( |) list of identifiers followed by an expression. lambda expressions capture their environment. In this example. } } ten_times(|j| println!("hello. effectively borrowing pointers to all outer variables mentioned inside the function. as the compiler infers them from context. Significantly. {}". Alternately. and call it with a lambda expression as an argument: fn ten_times<F>(f: F) where F: Fn(i32) { let mut i = 0i32. A lambda expression denotes a function that maps a list of parameters ( ident_list) onto the expression that follows the ident_list.

which need not be the innermost label enclosing the breakexpression. It is only permitted in the body of a loop. In the case of a forloop. If a label is present. If the label is absent. as in 'foo: loop{ }. but must enclose it. then executing a continueexpression immediately terminates the current iteration of the innermost loop enclosing it. the loop body block executes and control returns to the loop conditional expression. then continue 'fooreturns control to the head of the loop with label 'foo. but must enclose it. 7. If the loop conditional expression evaluates to true. If the label is present. A loopexpression may optionally have a label.18 Continue expressions A continueexpression has an optional label. A continueexpression is only permitted in the body of a loop. which need not be the innermost label enclosing the breakexpression. If the label is present. then break 'footerminates the loop with label 'foo.A loopexpression denotes an infinite loop. the head is the conditional expression controlling the loop. then executing a breakexpression immediately terminates the innermost loop enclosing it. the head is the call-expression controlling the loop.2. 7. then labeled breakand continueexpressions nested within this loop may exit out of this loop or return control to its head.2. returning control to the loop head.17 Break expressions A breakexpression has an optional label.2. The label is written as a lifetime preceding the loop expression. the whileexpression completes. 7. If the loop conditional expression evaluates to false. If the label is absent. .19 While loops A whileloop begins by evaluating the boolean loop conditional expression. In the case of a whileloop. See Break expressions (#break-expressions) and Continue expressions (#continue-expressions).

. } Like loopexpressions. See infinite loops (#infinite-loops). and continue expressions (#continue-expressions) for more information. forloops can be controlled with breakor continue. i = i + 1.2. and continue expressions (#continue-expressions) for more information.An example: let mut i = 0.20 For expressions A forexpression is a syntactic construct for looping over elements provided by an implementation of std::iter::IntoIterator. break expressions (#break-expressions). and may optionally have a label. for e in v { bar(e).256 { bar(i). An example of a for loop over the contents of an array: let v: &[Foo] = &[a. } An example of a for loop over a series of integers: for i in 0. whileloops can be controlled with breakor continue. 7. } Like loopexpressions. c]. break expressions (#break-expressions).. while i < 10 { println!("hello"). See infinite loops (#infinite-loops). and may optionally have a label. b.

A matchexpression has a head expression. it is first evaluated into a temporary location. and an optional trailing elseblock. In a pattern whose head expression has an enumtype. If a condition expression evaluates to false.2.-rvalues-and-temporaries). If a condition expression evaluates to true. followed by a consequent block.22 Match expressions A matchexpression branches on a pattern. destructured arrays or enum constructors. structures and tuples. the consequent block is executed and any subsequent else ifor elseblock is skipped. 7. The type of the patterns must equal the type of the head expression. If the head expression is an rvalue.stands for all the fields of a particular variant. any variables bound by the pattern are assigned to local variables in the arm's block. If all ifand else ifconditions evaluate to falsethen any elseblock is executed. it is preferable to match on lvalues. When the head expression is an lvalue.7. a placeholder ( _) stands for a single data field. the consequent block is skipped and any subsequent else ifcondition is evaluated. the match does not allocate a temporary location (however. The condition expressions must have type bool. Patterns consist of some combination of literals. any number of else ifconditions and blocks. variable binding specifications. The first arm with a matching pattern is chosen as the branch target of the match.). The exact form of matching that occurs depends on the pattern.. The form of an if expression is a condition expression. a by-value binding may copy or move from the lvalue). whereas a wildcard . When possible. and placeholders ( _).. wildcards ( .2. and control enters the block. A matchbehaves differently depending on whether or not the head expression is an lvalue or an rvalue (#lvalues. as the lifetime of these matches .21 If expressions An ifexpression is a conditional branch in program control. which is the value to compare to the patterns. and the resulting value is sequentially compared to the patterns in the arms until a match is found.

2 => println!("two").. or to a mutable reference using ref mut. z). 4 => println!("four"). } Patterns that bind variables default to binding to a copy or move of the matched value (depending on the matched value's type). assert_eq!(y. _ => println!("anything"). match x { e @ 1 . For example: let x = 1. . Subpatterns can also be bound to variables by the use of the syntax variable @ subpattern. &mutand boxsymbols. e). _ => "some" }.inherits the lifetime of the lvalue. match x { 1 => println!("one"). _ => println!("something else"). 5 => println!("five"). _ => "some" }. rather than being restricted to the inside of the match. let z = match x { &0 => "zero". An example of a matchexpression: let x = 1. as appropriate.. This can be changed to bind to a reference by using the refkeyword. For example. 5 => println!("got a range element {}". } Patterns can also dereference pointers by using the &. these two matches on x: &i32are equivalent: let y = match *x { 0 => "zero". 3 => println!("three").

For example: let message = match x { 0 | 1 => "not many". Pattern guards appear a er the pattern and consist of a bool-typed expression following the ifkeyword. Some(x) => process_other(x). A convention you can use to avoid conflicts is simply to name variants with upper-case letters. or bind a new variable. A range of values may be specified with . and local variables with lower-case letters. Range patterns only work on scalar types (like integers and characters. _ => "lots" }. a matchpattern would not be able to bind Nilas a new name. which have sub-components). like Nilin the previous example. let message = match maybe_digit { Some(x) if x < 10 => process_digit(x).2.23 If let expressions . A range pattern may not be a subrange of another range pattern inside the same match. could either refer to an enum variant that's in scope. wherever Listis in scope. Finally. For example. match patterns can accept pattern guards to further refine the criteria for matching a case. None => panic!() }... A pattern guard may refer to the variables bound within the pattern they follow. 9 => "a few". 2 ..A pattern that's just an identifier. The compiler interprets a variable pattern xas a binding only if there is no variant named xin scope. The compiler resolves this ambiguity by forbidding variable bindings that occur in matchpatterns from shadowing names of variants that are in scope.. Multiple match patterns may be joined with the |operator. not like arrays and structs. 7..

b) = dish { println!("Bacon is served with {}". Evaluating a return expression moves its argument into the designated output location for the current function call. b). } // this body will execute if let ("Ham".2. the corresponding block will execute. Otherwise.An if letexpression is semantically identical to an ifexpression but in place of a condition expression it expects a refutable let statement. If the value of the expression on the right hand side of the let statement matches the pattern. 7. If the value of the expression on the right hand side of the let statement matches the pattern. destroys the current function activation frame.24 While let loops A while letloop is semantically identical to a whileloop but in place of a condition expression it expects a refutable let statement. An example of a returnexpression: . } 7. b). // this body will be skipped because the pattern is refuted if let ("Bacon". the loop body block executes and control returns to the pattern matching statement. the while expression completes. b) = dish { println!("Ham is served with {}". "Eggs"). otherwise flow proceeds to the first elseblock that follows. and transfers control to the caller frame.25 Return expressions Return expressions are denoted with the keyword return.2. let dish = ("Ham".

[-(231). 27 .1]. } 8 Type system 8. The machine-dependent integer types. 231 .1].1 Primitive types The primitive types are the following: The boolean type boolwith values trueand false. u16.1 Machine types The machine types are the following: The unsigned word types u8. The signed two's complement word types i8. 264 .1. 8. i32and i64. 28 .fn max(a: i32. u32and u64. with values drawn from the integer intervals [-(27).1. [0.1] and [0.1]. 216 .1]. The type of a value defines the interpretation of the memory holding it. The machine types (integer and floating-point). in nontrivial ways that are not possible to emulate in user-defined types.1] respectively. b: i32) -> i32 { if a > b { return a.1] respectively. } return b. 215 . 263 . 232 . User-defined types have limited capabilities. i16. Built-in types and type-constructors are tightly integrated into the language.1].1 Types Every variable. . with values drawn from the integer intervals [0. [-(263).1. item and value in a Rust program has a type. [-(215). 8. [0.

1.org/glossary/#unicode_scalar_value) (i.1. It has no nominal name and is instead structurally typed. A [char]array is effectively an UCS-4 / UTF-32 string. This ensures that isizecan be used to calculate differences between pointers into an object or array and can address every byte within an object along with one byte past the end. but can only be instantiated through a pointer type. It can represent every memory address in the process.e.unicode. a code point that is not a surrogate). A value of type charis a Unicode scalar value (http://www. Since stris of unknown size.1. . Tuple types and values are denoted by listing the types or values of their elements. such as &str. 8. respectively. A value of type stris a Unicode string.The IEEE 754-2008 binary32and binary64floating-point types: f32and f64. respectively.2 Machine-dependent integer types The usizetype is an unsigned integer type with the same number of bits as the platform's pointer type. represented as a 32-bit unsigned word in the 0x0000 to 0xD7FF or 0xE000 to 0x10FFFF range. 8.3 Tuple types A tuple type is a heterogeneous product of other types. represented as an array of 8-bit unsigned bytes holding a sequence of UTF-8 code points. Because tuple elements don't have a name. The isizetype is a signed integer type with the same number of bits as the platform's pointer type. they can only be accessed by patternmatching or by using Ndirectly as a field to access the Nth element. called the elements of the tuple. comma-separated list. it is not a first-class type. 8. in a parenthesized.1.2 Textual types The types charand strhold textual data. The theoretical upper bound on object and array size is the maximum isizevalue.

and slices are always initialized. 3]. "hello"). A slice is a 'view' into an array. The vec! macro is also part of the standard library.An example of a tuple type and its use: type Pair<'a> = (i32. assert!(b != "world"). 8. and can be allocated on either the stack or the heap.]. the tuple type with no elements ( ()) is o en called ‘unit’ or ‘the unit type’.1. All in-bounds elements of arrays. a 'slice'. An array has a fixed size. 3]. let p: Pair<'static> = (10. an 'array'. An example of each kind: let vec: Vec<i32> = vec![1. It doesn't own the data it points to. 2. 2. N]. b) = p. called the fields of the type. &[T]. 3] = [1..1. 8. the vec!macro allows you to create a Vec<T>easily.4 Array. let (a. let arr: [i32.0 == 10).5 (#fn5) .5 Structure types A structtype is a heterogeneous product of other types. &'a str). assert!(p. For historical reasons and convenience. rather than the language. and access to an array or slice is always bounds-checked. As you can see. it borrows it. and Slice types Rust has two different types for a list of items: [T. let s: &[i32] = &vec[.

Any enumvalue consumes as much memory as the largest variant constructor for its corresponding enumtype. but it can be fixed with the #[repr(.1.)] attribute. The fields of a structmay be qualified by visibility modifiers (#visibility-andprivacy).1. The one value constructed by the associated structure expression (#structure-expressions) is the only value that inhabits such a type. the resulting structvalue will always have the same memory layout.7 Recursive types . except that it has no fields. 8. A tuple struct type is just like a structure type. fields may be given in any order in a corresponding struct expression. A unit-like struct type is like a structure type. 8..New instances of a structcan be constructed with a struct expression (#structureexpressions). New instances of an enumcan be constructed by calling one of the variant constructors. 6 (#fn6) An enumitem (#enumerations) declares both the type and a number of variant constructors. except that the fields are anonymous.. The memory layout of a structis undefined by default to allow for compiler optimizations like field reordering. heterogeneous disjoint union type. Enum types cannot be denoted structurally as types. to allow access to data in a structure outside a module. In either case. denoted by the name of an enumitem (#enumerations).6 Enumerated types An enumerated type is a nominal. in a call expression (#call-expressions). but must be denoted by named reference to an enumitem (#enumerations). each of which is independently named and takes an optional tuple of arguments.

but a reference of a temporary value will keep it alive during the scope of the reference itself. or other structural types such as arrays or tuples).Nominal types — enumerations (#enumerated-types) and structures (#structuretypes) — may be recursive. Cons(T. stored into data structures. A recursive enumitem must have at least one non-recursive constructor (in order to give the recursion a basis case). Box<List<T>>) } let a: List<i32> = List::Cons(7. each enumconstructor or structfield may refer. in other words the recursive fields of the type must be pointer types. Box::new(List::Cons(13. Such recursion has restrictions: Recursive types must include a nominal type in the recursion (not mere type definitions. Copying a reference is a "shallow" operation: it involves only copying the pointer itself. but not module visibility boundaries. directly or indirectly. An example of a recursive type and its use: enum List<T> { Nil.8 Pointer types All pointers in Rust are explicit first-class values. 8. . and returned from functions.1. That is. or crate boundaries (in order to simplify the module system and type checker). to the enclosing enumor structtype itself. There are two varieties of pointer in Rust: References ( &) : These point to memory owned by some other value. Box::new(List::Nil)))). or &'a typewhen you need to specify an explicit lifetime. Releasing a reference has no effect on the value it points to. They can be copied. The size of a recursive type must be finite. A reference type is written &type. Recursive type definitions can cross module boundaries.

} let mut x = add(5. for example. Dereferencing a raw pointer or converting it to any other pointer type is an unsafeoperation (#unsafe-functions). i32) -> i32. A function type consists of a possibly-empty set of function-type modifiers (such as unsafeor extern). x = bo(5. type Binop = fn(i32.9 Function types The function type constructor fnforms new function types. despite the fact that they have the same signature: . for example *const i32means a raw pointer to a 32-bit integer.7). Copying or dropping a raw pointer has no effect on the lifecycle of any other value.7).1. let bo: Binop = add. 8.Raw pointers ( *) : Raw pointers are pointers without safety or liveness guarantees. 8.1 Function types for speci c items Internally to the compiler. a sequence of input types and an output type. In the following snippet. the internal types of the functions fooand barare different.1. Raw pointers are written as *const Tor *mut T. they exist to support interoperability with foreign code. y: i32) -> i32 { return x + y. and writing performancecritical or low-level functions. The standard library contains additional 'smart pointer' types beyond references and raw pointers. Raw pointers are generally discouraged in Rust code. there are also function types that are specific to a particular function item. An example of a fntype: fn add(x: i32.9.

e. Fnimplies FnMutand FnOnce.fn foo() { } fn bar() { } The types of fooand barcan both be implicitly coerced to the fn pointer type fn(). its type implements one or more of the closure traits: FnOnce: The closure can be called once. . though the compiler will emit a type like fn() {foo}in error messages to indicate "the unique fn type for the function foo". a type like &SomeTraitor Box<SomeTrait>is called a trait object. Each instance of a trait object includes: a pointer to an instance of a type Tthat implements SomeTrait a virtual method table. A closure called as Fncan neither move out from nor mutate values from its environment. a pointer to T's implementation (i.1. Fn: The closure can be called multiple times through a shared reference. 8. FnMut: The closure can be called multiple times as mutable. for each method of SomeTraitthat Timplements. A closure called as FnMutcan mutate values from its environment.11 Trait objects In Rust. 8. a function pointer). anonymous type that cannot be written out. which contains.1. Depending on the requirements of the closure. A closure called as FnOncecan move out values from its environment. o en just called a vtable. FnMutimplies FnOnce. There is currently no syntax for unique fn types.10 Closure types A lambda expression (#lambda-expressions) produces a closure value with a unique.

where Timplements trait R. } impl Printable for i32 { fn stringify(&self) -> String { self.1. and the cast expression in main. the trait must be object-safe.to_string() } } fn print(a: Box<Printable>) { println!("{}".md).The purpose of trait objects is to permit "late binding" of methods.12 Type parameters Within the body of an item that has type parameter declarations. } In this example. Note that for a trait object to be instantiated. and the pointer value of E. This result is represented as a pair of pointers: the vtable pointer for the Timplementation of R. An example of a trait object: trait Printable { fn stringify(&self) -> String. 8. casting Eto the corresponding pointer type &Ror Box<R>results in a value of the trait object R. Object safety rules are defined in RFC 255 (https://github. } fn main() { print(Box::new(10) as Box<Printable>). a. A call to a method on a trait object is only resolved to a vtable entry at compile time.stringify()).com/rustlang/rfcs/blob/master/text/0255-object-safety. The actual implementation for each vtable entry can vary on an object-by-object basis. the names of its type parameters are types: . the trait Printableoccurs as a trait object in both the type signature of print. Given a pointer-typed expression Eof type &Tor Box<T>.

then the only subtyping would be due to type equality. referring to to_vec's Atype parameter. first). Subtyping in Rust is very restricted and occurs only due to variance with respect to lifetimes and between types with higher ranked lifetimes. } impl Printable for String { fn make_string(&self) -> String { (*self). in: trait Printable { fn make_string(&self) -> String.clone(). Selfrefers to the value of type Stringthat is the receiver for a call to the method make_string. it refers to an implicit type parameter representing the "implementing" type. a vector with element type A. and resthas type Vec<A>. rest.2 Subtyping Subtyping is implicit and can occur at any stage in type checking or inference.13 Self types The special type Selfhas a meaning within traits and impls. For example. } let first: A = xs[0]. it is an alias for the implementing type. In a trait definition.1. .. In this case.]).is_empty() { return vec![].insert(0. If we were to erase lifetimes from types. In an impl. let mut rest: Vec<A> = to_vec(&xs[1. firsthas type A. 8. 8. in the impl.fn to_vec<A: Clone>(xs: &[A]) -> Vec<A> { if xs. rest } Here.clone() } } The notation &selfis a shorthand for self: &Self.

For example.md). &'static stris a subtype of &'a str. instantiations of struct or variant fields.3 Type coercions Coercions are defined in RFC401 (https://github. staticand conststatements (similar to letstatements). arguments for function calls. we can assign sto t: fn bar<'a>() { let s: &'static str = "hi". 8... Possible coercion sites are: letstatements where an explicit type is given. let foobe defined as fn foo(x: U) { . 8. A coercion is implicit and has no syntax. } Since 'static"lives longer" than 'a. these are typically places where the desired type is explicit or can be dervied by propagation from explicit types (without type inference).. Nevertheless. .1 Coercion sites A coercion can only occur at certain coercion sites in a program. eis coerced to have type U.. In let _: U = e.3. Then eis coerced to have type U.Consider the following example: string literals always have 'staticlifetime. The value being coerced is the actual parameter and it is coerced to the type of the formal parameter. let t: &'a str = s.com/rustlang/rfcs/blob/master/text/0401-coercions. Then eis coerced to have type U. }and call it as foo(e). Assume we have a struct Foo { x: U }and instantiate it as Foo { x: e }.

then the last expression in the block (if it is not semicolon-terminated) is a coercion site to U. T_1to T_3where T_1coerces to T_2and T_2coerces to T_3(transitive case).. This includes blocks which are part of control flow statements. where the array has type [U. U_1. n]. then the subexpression is a coercion site to U. tuples. Note that this is not fully supported yet &mut Tto &T. If a block has type U. The repeated sub-expression is a coercion site for coercion to type U. where a tuple is a coercion site to type (U_0. Propagation recurses from these new coercion sites. Each sub-expression is a coercion site to the respective type. array literals with repeating syntax.. then the relevant sub-expressions in that expression are also coercion sites.g. parenthesised sub-expressions ( (e)). U_n). e.3.function results (either the final line of a block if it is not semicolon terminated or any expression in a returnstatement). If the expression has type U.2 Coercion types Coercion is allowed between the following types: Tto Uif Tis a subtype of U(reflexive case). the zeroth subexpression is a coercion site to type U_0. . In fn foo() -> U { e }. where the array has type [U. such as if/ else. eis coerced to to have type U. blocks. n]. . If the expression in one of these coercion sites is a coercion-propagating expression.. Propagating expressions and their relevant sub-expressions are: array literals. if the block has a known type. Each sub-expression in the array literal is a coercion site for coercion to type U. 8.

&Tto *const T.*mut Tto *const T.coerce_inner( T) = Uwhere Tis a concrete type which implements the trait U. . where TyCtor( T) is one of &T &mut T *const T *mut T Box<T> and where . &mut Tto *mut T. For example: use std::ops::Deref. } &mut Tto &mut Uif Timplements DerefMut<Target = U>.n]) = [T]. //&mut CharContainer is coerced to &char. . foo(x). &Tto &Uif Timplements Deref<Target = U>. TyCtor( T) to TyCtor(coerce_inner( T)).coerce_inner( [T. struct CharContainer { value: char } impl Deref for CharContainer { type Target = char..value } } fn foo(arg: &char) {} fn main() { let x = &mut CharContainer { value: 'y' }. fn deref<'a>(&'a self) -> &'a char { &self.

In the future.4 The Dereftrait The Deref<Target = U>trait allows a type to implicitly implement all the methods of the type U.md) for more details.1 The Copytrait The Copytrait changes the semantics of a type implementing it. . coerce_inner will be recursively extended to tuples and structs. If no such method is found. 10 Memory model .2 The Sizedtrait The Sizedtrait indicates that the size of this type is known at compile-time. In addition. 9. 9.3 The Droptrait The Droptrait provides a destructor. When attempting to resolve a method call.deref()is called and the compiler continues to search for the method implementation in the returned type U. 9 Special traits Several traits define special evaluation behavior. Values whose type implements Copyare copied rather than moved upon assignment. to be run whenever a value of this type is to be destroyed. 9. the compiler will search the top-level type for the implementation of the called method. See RFC401 (https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions. coercions from sub-traits to super-traits will be added. 9.

Immutable portions of the heap may be safely shared between threads. Items are neither dynamically allocated nor freed. Local variables are immutable unless declared otherwise like: let mut x = . The heap is a general term that describes boxes.0..0. A local variable (or stack-local allocation) holds a value directly. or stored in the heap.2 Memory ownership When a stack frame is exited. its local allocations are all released. 10. The lifetime of an allocation in the heap depends on the lifetime of the box values pointing to it. 10. mutable portions may not be safely shared. 10. either a named function parameter..3 Variables A variable is a component of a stack frame. Since box values may themselves be passed in and out of frames. an anonymous temporary (#lvalues.A Rust program's memory consists of a static set of items and a heap. .. allocated within the stack's memory. heap allocations may outlive the frame they are allocated within.1 Memory allocation and lifetime The items of a program are those functions. and its references to boxes are dropped. Allocations in the stack consist of variables. modules and types that have their value calculated at compile-time and stored uniquely in the memory image of the rust process.-rvalues-and-temporaries). exist in the standard library. or a named local variable.0. The value is a part of the stack frame. but several mechanisms for effectively-safe sharing of mutable values. built on unsafe code but enforcing a safe locking discipline. and allocations in the heap consist of boxes.

. y|and fn f(mut x: Box<i32>. all crate_typeattributes will be ignored in favor of only building the artifacts specified by command line. Subsequent statements within a function may or may not initialize the local variables.A runnable executable will be produced. this is enforced by the compiler. in an uninitialized state. on frame-entry. If one or more command line flag is specified.Function parameters are immutable unless declared with mut. This section will explore the various methods to link Rust crates together. producing a distributable binary. In one session of compilation. #[crate_type = "bin"]. This requires that there is a mainfunction in the crate which will be run when the program begins executing. --crate-type=bin. the compiler can generate multiple artifacts through the usage of either command line flags or the crate_typeattribute. and more information about native libraries can be found in the ffi section of the book (book/ffi.html). This will link in all Rust and native dependencies. } Local variables are not initialized when allocated. fn modify(mut self: Box<Self>) -> Box<Self>. 11 Linkage The Rust compiler supports various methods to link crates together both statically and dynamically. Local variables can be used only a er they have been initialized. y: Box<i32>)declare one mutable variable xand one immutable variable y). the entire frame worth of local variables are allocated at once. Methods that take either selfor Box<Self>can optionally place them in a mutable variable by prefixing them with mut(similar to regular arguments): trait Changer { fn change(mut self) -> Self. The mutkeyword applies only to the following parameter (so |mut x.

--crate-type=dylib.A dynamic Rust library will be produced. This format is recommended for use in situations such as linking Rust code into an existing nonRust application because it will not have dynamic dependencies on other Rust code. If only . *. #[crate_type = "staticlib"]. then the compiler will produce each form of output at once without having to recompile. and the libtype can be seen as an alias for one of them (but the actual one is compiler-defined).dllfiles on windows. this only applies for outputs specified by the same method. This is different from other library outputs in that the Rust compiler will never attempt to link to staticliboutputs. This is different from the liboutput type in that this forces dynamic library generation. The static library is actually a *.A static system library will be produced. The output library will always be usable by rustc. The remaining output types are all different flavors of libraries. are interpreted by the Rust compiler in future linkage.aarchive on linux and osx and a *. but the actual type of library may change from time-to-time. However. The purpose of this output type is to create a static library containing all of the local crate's code along with all upstream dependencies.A Rust library will be produced. #[crate_type = "lib"]. This essentially means that rustcwill look for metadata in rlibfiles like it looks for metadata in dynamic libraries. unlike staticlibfiles.sofiles on linux. --crate-type=staticlib. This is used as an intermediate artifact and can be thought of as a "static Rust library". This form of output is used to produce statically linked executables as well as staticliboutputs. Note that these outputs are stackable in the sense that if multiple are specified. #[crate_type = "dylib"].--crate-type=lib. --crate-type=rlib. This is an ambiguous concept as to what exactly is produced because a library can manifest itself in several forms.dylibfiles on osx. The resulting dynamic library can be used as a dependency for other libraries and/or executables. #[crate_type = "rlib"]. The purpose of this generic lib option is to generate the "compiler recommended" style of library. These rlibfiles.libfile on windows. and *. This output type will create *.A "Rust library" file will be produced.

If a dynamic library or an executable that is being dynamically linked is being produced. are the rlibformat and the dynamic library format. If an rlibfile is being produced. It is simply required that all upstream dependencies be available for reading metadata from. . The reason for this is that rlibfiles do not contain any of their upstream dependencies. The only forms looked for by the compiler. then they will all be built. 4. and in this case warnings will be printed about all unlinked native dynamic dependencies. then dependencies are first attempted to be found in the rlibformat. If some dependencies are not available in an rlib format. With these two options for a dependent library.crate_typeattributes are specified. then dynamic linking is attempted (see below). however. but if one or more -crate-typecommand line flag is specified.rlib! 3. then the compiler could find B in various different forms throughout the system. then there are no restrictions on what format the upstream dependencies are available in. the compiler follows these rules when determining what format of dependencies will be used: 1. With this in mind. all upstream dependencies are required to be available in rlibformats. the compiler must at some point make a choice between these two formats. then only those outputs will be built. If an executable is being produced and the -C prefer-dynamicflag is not specified. if crate A depends on crate B. Note that it is impossible to link in native dynamic dependencies to a static library. 2. then the compiler will attempt to reconcile the available dependencies in either the rlib or dylib format to create a final product. If a static library is being produced. It wouldn't be very efficient for all rlibfiles to contain a copy of libstd. With all these different kinds of outputs. This requirement stems from the reason that a dynamic library cannot be converted into a static format.

When dynamically linking. memory model ML Kit. semicolon statement separation C++: references. The compiler allows mixing the rlib and dylib formats. OCaml: algebraic datatypes. RAII. type inference. pattern matching. the compiler will attempt to maximize dynamic dependencies while still allowing some dependencies to be linked in via an rlib. 13 Appendix: In uences Rust is not a particularly original language. the compiler will emit a warning if it is unable to determine which formats to link each library with. For most situations. Alef. move semantics. having all libraries available as a dylib is recommended if dynamically linking. if dynamic libraries B and C were each statically linked to library A. 12 Appendix: Rationales and design tradeoffs TODO. For other situations. --crate-type=binor --crate-type=libshould be sufficient for all compilation needs. lightweight . In general. Cyclone: region based memory management Haskell (GHC): typeclasses. type families Newsqueak. thread failure. then a crate could not link to B and C together because there would be two copies of A. The compiler currently implements no method of hinting what format a library should be linked with. smart pointers.A major goal of the compiler is to ensure that a library never appears more than once in any artifact. with design elements coming from a wide range of sources. For example. concurrency Erlang: message passing. monomorphisation. and the other options are just available if more fine-grained control is desired over the output format of a Rust crate. but this restriction must be satisfied. linked thread failure. Limbo: channels. Some of these are listed below (including elements that have since been removed): SML.

A crate is somewhat analogous to an assembly in the ECMA-335 CLI model. at your option. the record types of the ML family. Licensed under the Apache License. Static checks like syntactic analysis. or the structure types of the Lisp family. ↩ (#fnref4) 5. structtypes are analogous to structtypes in C. This is expected to improve soon. and lints should happen before the program is executed regardless of when it is executed. type checking. or a pick ADT in Limbo. Hermes: typestate Unicode Annex #31: identifier and pattern syntax 1. Version 2. modified. a unit in the Owens and Flatt module system. This file may not be copied. This distinction would also exist in an interpreter. Non-ASCII characters in identifiers are currently feature gated. a library in the SML/NJ Compilation Manager. Substitute definitions for the special Unicode productions are provided to the grammar verifier. when verifying the grammar in this document.0 or the MIT license. The enumtype is analogous to a dataconstructor declaration in ML.concurrency Swi : optional bindings Scheme: hygienic macros C#: attributes Ruby: block syntax NIL. ↩ (#fnref5) 6. or a configuration in Mesa. ↩ (#fnref1) 2. ↩ (#fnref2) 3. ↩ (#fnref6) Copyright © 2011-2015 The Rust Project Developers. restricted to ASCII range. or distributed except according to those terms. . ↩ (#fnref3) 4.