1.5. Keywords
Keywords are tokens that look like identifiers but are reserved by the language. When a keyword appears in identifier position, the compiler produces a keyword token rather than an identifier.
This document defines only the list of keywords the language reserves directly. The exact meaning of each keyword is introduced in later parts of the specification; this document states only their form and classification.
1.5.1. Reserved keyword list
There are two classes of keywords. The principle is the following single rule.
Important
A word that starts a statement or expression and could be confused with "identifier + what follows" is a reserved keyword; a word whose position of appearance is fixed is a contextual keyword (1.5.4).
A reserved keyword is tokenized as a keyword wherever it appears and cannot be used as an identifier. The only exception is the name positions of 1.5.5.
let fn if else match while loop for
return break continue try throw
async await yield unsafe using
struct enum trait impl pub mod use
as is ref
true false none self Self
Note
try? and try! are not separate keywords but token sequences of the keyword try and the punctuation ? / ! (Punctuation and operator tokens).
self (lowercase) refers to the instance identifier (the method receiver), and Self (uppercase) refers to the name of the type that the current impl targets. using is the keyword introducing an RAII-style resource management block (using expression).
1.5.2. Meaning is defined later
The meanings of the tokens above are defined across the specification: variables, visibility and modules in Chapter 5; types and containers in Chapter 2; control flow in Chapter 3; functions, closures and coroutines in Chapter 4; meta and magic in Chapter 6.
This Chapter 1 covers only the classification rule that, at the lexical stage, these tokens are separated as keywords rather than identifiers.
1.5.3. Registered keywords (extension mechanism)
Beyond the reserved list above, there is a mechanism by which the standard libraries can register additional keywords. It is part of the meta-system. The registration mechanism and exact processing rules are defined in #[keyword(...)] magic.
Within the scope of this document, only the following is promised. Reserved keywords are not identifiers, except in the name positions of 1.5.5, and are separated as keywords. A registered keyword takes effect only within the compilation unit that contains its registration. If the two sets collide, the registration is rejected; reserved keywords cannot be overridden.
1.5.4. Contextual keywords
The following words are keywords only in designated positions and are ordinary identifiers elsewhere.
| Word | Position where it is a keyword | Definition |
|---|---|---|
type | At item start, when followed by an identifier and then = or < (type alias) | 2.6 |
any | Type position (any, any Tr) | 2.2 |
in | The in of for pat in | 3.13.3 |
where | After a function signature, an impl header, or a struct / enum / union / type alias header | 2.10.4 |
throws, rethrows | After the parameter ) of a function signature | 4.14 |
catch, finally | After an expression or block (postfix clause) | 3.14 |
const, static, extern, mut | At item start (including extern "C", static mut) | 5.2, 5.3, 5.9 |
union | At item start, when immediately followed by an identifier | 2.5 |
pkg, sub | Immediately after pub( | 5.6 |
pkg, sup, rok | As the first token of a path, when immediately followed by :: | 5.7 |
let type = 1; // identifier
type Pair = (i32, i32); // type alias (item start + identifier + =)
let in = 3; for x in xs { } // identifier / the in of for
fn catch(e: str) { } // identifier - not after an expression
Declaring a type named any is a compile error (struct any { }), because it could not be distinguished from any in type position.
Visibility qualifiers: pkg / sub
pkg and sub are used as qualifiers inside the parentheses of pub(pkg) and pub(sub), and are ordinary identifiers elsewhere.
pub(sub) fn helper() { ... } // inside pub( ): visibility qualifier
trait Sub { fn sub(self, rhs: Self) -> Self; } // in ordinary position: identifier
Path roots: pkg / sup / rok
These three words are always path roots when they are the first token of a path and are immediately followed by :: (5.7 Paths). Elsewhere they are ordinary identifiers.
pkg::xxx- from the current package rootsup::xxx- from the parent modulerok::xxx- the standard library virtual namespace (rok::core,rok::bare,rok::std, 0.5 Standard library tiers)
Because pkg::name is always interpreted as a root, using any of the three words as the name of a module or type (struct, enum, union, trait, type alias, mod) is a compile error. They may be used as names of variables, functions, fields and methods.
let rok = 42; // variable name OK
fn sup() { } // function name OK
self.rok // field / member name OK
mod rok { ... } // ERROR - cannot be a module name
struct pkg { } // ERROR - cannot be a type name
rok::core::iter::Iterator // path root
1.5.5. Keywords in name positions
In the following positions, all keywords, including reserved keywords, are used as identifiers, because the surrounding tokens make it clear that a name is meant.
- Immediately after
.(member access, method call):x.type,stream.match(p) struct/enumfield name declarations:struct Token { type: Kind; }- Field names in
structliterals andstructpatterns:Ev { match: 1 },Ev { match: m } => ... - Names of named arguments:
f(type: 1). A named argument names a parameter, and a parameter name cannot be a reserved keyword, so only contextual keywords appear here in practice.
self is an exception and cannot be an identifier even in these positions. Raw identifiers (Rust's r#fn) are still not provided (1.4.4).
struct Token { type: Kind; for: str; } // field name - OK
let k = tok.type; // after . - OK
make(type: Kind::Ident); // named argument (contextual keyword) - OK
struct S { self: i32; } // ERROR - self is the exception