4 ## Appendix A: Keywords
6 The following list contains keywords that are reserved for current or future
7 use by the Rust language. As such, they cannot be used as identifiers, such as
8 names of functions, variables, parameters, struct fields, modules, crates,
9 constants, macros, static values, attributes, types, traits, or lifetimes.
11 ### Keywords Currently in Use
13 * `as` - perform primitive casting, disambiguate the specific trait containing
14 an item, or rename items in `use` and `extern crate` statements
15 * `break` - exit a loop immediately
16 * `const` - define constant items or constant raw pointers
17 * `continue` - continue to the next loop iteration
18 * `crate` - link an external crate or a macro variable representing the crate in
19 which the macro is defined
20 * `else` - fallback for `if` and `if let` control flow constructs
21 * `enum` - define an enumeration
22 * `extern` - link an external crate, function, or variable
23 * `false` - Boolean false literal
24 * `fn` - define a function or the function pointer type
25 * `for` - loop over items from an iterator, implement a trait, or specify a
26 higher-ranked lifetime
27 * `if` - branch based on the result of a conditional expression
28 * `impl` - implement inherent or trait functionality
29 * `in` - part of `for` loop syntax
30 * `let` - bind a variable
31 * `loop` - loop unconditionally
32 * `match` - match a value to patterns
33 * `mod` - define a module
34 * `move` - make a closure take ownership of all its captures
35 * `mut` - denote mutability in references, raw pointers, or pattern bindings
36 * `pub` - denote public visibility in struct fields, `impl` blocks, or modules
37 * `ref` - bind by reference
38 * `return` - return from function
39 * `Self` - a type alias for the type implementing a trait
40 * `self` - method subject or current module
41 * `static` - global variable or lifetime lasting the entire program execution
42 * `struct` - define a structure
43 * `super` - parent module of the current module
44 * `trait` - define a trait
45 * `true` - Boolean true literal
46 * `type` - define a type alias or associated type
47 * `unsafe` - denote unsafe code, functions, traits, or implementations
48 * `use` - import symbols into scope
49 * `where` - denote clauses that constrain a type
50 * `while` - loop conditionally based on the result of an expression
52 ### Keywords Reserved for Future Use
54 The following keywords do not have any functionality but are reserved by Rust
55 for potential future use.
75 ## Appendix B: Operators and Symbols
77 This appendix contains a glossary of Rust’s syntax, including operators and
78 other symbols that appear by themselves or in the context of paths, generics,
79 trait bounds, macros, attributes, comments, tuples, and brackets.
83 The following list contains the operators in Rust, an example of how the
84 operator would appear in context, a short explanation, and whether that
85 operator is overloadable. If an operator is overloadable, the relevant trait to
86 use to overload that operator is listed.
89 * `!` (`ident!(...)`, `ident!{...}`, `ident![...]`): denotes macro
91 * `!` (`!expr`): bitwise or logical complement. Overloadable (`Not`).
92 * `!=` (`var != expr`): nonequality comparison. Overloadable (`PartialEq`).
93 * `%` (`expr % expr`): arithmetic remainder. Overloadable (`Rem`).
94 * `%=` (`var %= expr`): arithmetic remainder and assignment. Overloadable
96 * `&` (`&expr`, `&mut expr`): borrow.
97 * `&` (`&type`, `&mut type`, `&'a type`, `&'a mut type`): borrowed pointer type.
98 * `&` (`expr & expr`): bitwise AND. Overloadable (`BitAnd`).
99 * `&=` (`var &= expr`): bitwise AND and assignment. Overloadable
101 * `&&` (`expr && expr`): logical AND.
102 * `*` (`expr * expr`): arithmetic multiplication. Overloadable (`Mul`).
103 * `*` (`*expr`): dereference.
104 * `*` (`*const type`, `*mut type`): raw pointer.
105 * `*=` (`var *= expr`): arithmetic multiplication and assignment. Overloadable
107 * `+` (`trait + trait`, `'a + trait`): compound type constraint.
108 * `+` (`expr + expr`): arithmetic addition. Overloadable (`Add`).
109 * `+=` (`var += expr`): arithmetic addition and assignment. Overloadable
111 * `,`: argument and element separator.
112 * `-` (`- expr`): arithmetic negation. Overloadable (`Neg`).
113 * `-` (`expr - expr`): arithmetic subtraction. Overloadable (`Sub`).
114 * `-=` (`var -= expr`): arithmetic subtraction and assignment. Overloadable
116 * `->` (`fn(...) -> type`, `|...| -> type`): function and closure
118 * `.` (`expr.ident`): member access.
119 * `..` (`..`, `expr..`, `..expr`, `expr..expr`): right-exclusive range literal.
120 * `..` (`..expr`): struct literal update syntax.
121 * `..` (`variant(x, ..)`, `struct_type { x, .. }`): “and the rest” pattern
123 * `...` (`expr...expr`) *in a pattern*: inclusive range pattern.
124 * `/` (`expr / expr`): arithmetic division. Overloadable (`Div`).
125 * `/=` (`var /= expr`): arithmetic division and assignment. Overloadable
127 * `:` (`pat: type`, `ident: type`): constraints.
128 * `:` (`ident: expr`): struct field initializer.
129 * `:` (`'a: loop {...}`): loop label.
130 * `;`: statement and item terminator.
131 * `;` (`[...; len]`): part of fixed-size array syntax
132 * `<<` (`expr << expr`): left-shift. Overloadable (`Shl`).
133 * `<<=` (`var <<= expr`): left-shift and assignment. Overloadable (`ShlAssign`).
134 * `<` (`expr < expr`): less-than comparison. Overloadable (`PartialOrd`).
135 * `<=` (`expr <= expr`): less-than or equal-to comparison. Overloadable
137 * `=` (`var = expr`, `ident = type`): assignment/equivalence.
138 * `==` (`expr == expr`): equality comparison. Overloadable (`PartialEq`).
139 * `=>` (`pat => expr`): part of match arm syntax.
140 * `>` (`expr > expr`): greater-than comparison. Overloadable (`PartialOrd`).
141 * `>=` (`expr >= expr`): greater-than or equal-to comparison. Overloadable
143 * `>>` (`expr >> expr`): right-shift. Overloadable (`Shr`).
144 * `>>=` (`var >>= expr`): right-shift and assignment. Overloadable
146 * `@` (`ident @ pat`): pattern binding.
147 * `^` (`expr ^ expr`): bitwise exclusive OR. Overloadable (`BitXor`).
148 * `^=` (`var ^= expr`): bitwise exclusive OR and assignment. Overloadable
150 * `|` (`pat | pat`): pattern alternatives.
151 * `|` (`|…| expr`): closures.
152 * `|` (`expr | expr`): bitwise OR. Overloadable (`BitOr`).
153 * `|=` (`var |= expr`): bitwise OR and assignment. Overloadable (`BitOrAssign`).
154 * `||` (`expr || expr`): logical OR.
155 * `_`: “ignored” pattern binding. Also used to make integer literals readable.
156 * `?` (`expr?`): error propagation.
158 ### Non-operator Symbols
160 The following list contains all non-letters that don’t function as operators;
161 that is, they don’t behave like a function or method call.
163 #### Stand-Alone Syntax
165 * `'ident`: named lifetime or loop label.
166 * `...u8`, `...i32`, `...f64`, `...usize`, *etc.*: numeric literal of
168 * `"..."`: string literal.
169 * `r"..."`, `r#"..."#`, `r##"..."##`, *etc.*: raw string literal,
170 escape characters are not processed.
171 * `b"..."`: byte string literal, constructs a `[u8]` instead of a string.
172 * `br"..."`, `br#"..."#`, `br##"..."##`, *etc.*: raw byte string
173 literal, combination of raw and byte string literal.
174 * `'...'`: character literal.
175 * `b'...'`: ASCII byte literal.
176 * `|...| expr`: closure.
177 * `!`: always empty bottom type for diverging functions.
179 #### Path-Related Syntax
181 * `ident::ident`: namespace path.
182 * `::path`: path relative to the crate root (*i.e.*, an explicitly absolute
184 * `self::path`: path relative to the current module (*i.e.*, an explicitly
186 * `super::path`: path relative to the parent of the current module.
187 * `type::ident`, `<type as trait>::ident`: associated constants, functions, and
189 * `<type>::...`: associated item for a type that cannot be directly named
190 (*e.g.*, `<&T>::...`, `<[T]>::...`, *etc.*).
191 * `trait::method(...)`: disambiguating a method call by naming the trait
193 * `type::method(...)`: disambiguating a method call by naming the type for
195 * `<type as trait>::method(...)`: disambiguating a method call by naming
196 the trait *and* type.
200 * `path<...>` (*e.g.*, `Vec<u8>`): specifies parameters to generic type *in
202 * `path::<...>`, `method::<...>` (*e.g.*, `"42".parse::<i32>()`):
203 specifies parameters to generic type, function, or method *in an expression*.
204 Often referred to as *turbofish*.
205 * `fn ident<...> ...`: define generic function.
206 * `struct ident<...> ...`: define generic structure.
207 * `enum ident<...> ...`: define generic enumeration.
208 * `impl<...> ...`: define generic implementation.
209 * `for<...> type`: higher-ranked lifetime bounds.
210 * `type<ident=type>` (*e.g.*, `Iterator<Item=T>`): a generic type where one or
211 more associated types have specific assignments.
213 #### Trait Bound Constraints
215 * `T: U`: generic parameter `T` constrained to types that implement `U`.
216 * `T: 'a`: generic type `T` must outlive lifetime `'a`. When we say that a type
217 “outlives” the lifetime, we mean it cannot transitively contain any references
218 with lifetimes shorter than `'a`.
219 * `T : 'static`: the generic type `T` contains no borrowed references other
221 * `'b: 'a`: generic lifetime `'b` must outlive lifetime `'a`.
222 * `T: ?Sized`: allow generic type parameter to be a dynamically sized type.
223 * `'a + trait`, `trait + trait`: compound type constraint.
225 #### Macros and Attributes
227 * `#[meta]`: outer attribute.
228 * `#![meta]`: inner attribute.
229 * `$ident`: macro substitution.
230 * `$ident:kind`: macro capture.
231 * `$(…)…`: macro repetition.
235 * `//`: line comment.
236 * `//!`: inner line doc comment.
237 * `///`: outer line doc comment.
238 * `/*...*/`: block comment.
239 * `/*!...*/`: inner block doc comment.
240 * `/**...*/`: outer block doc comment.
244 * `()`: empty tuple (*aka* unit), both literal and type.
245 * `(expr)`: parenthesized expression.
246 * `(expr,)`: single-element tuple expression.
247 * `(type,)`: single-element tuple type.
248 * `(expr, ...)`: tuple expression.
249 * `(type, ...)`: tuple type.
250 * `expr(expr, ...)`: function call expression. Also used to initialize
251 tuple `struct`s and tuple `enum` variants.
252 * `ident!(...)`, `ident!{...}`, `ident![...]`: macro invocation.
253 * `expr.0`, `expr.1`, *etc.*: tuple indexing.
257 * `{...}`: block expression.
258 * `Type {...}`: `struct` literal.
262 * `[...]`: array literal.
263 * `[expr; len]`: array literal containing `len` copies of `expr`.
264 * `[type; len]`: array type containing `len` instances of `type`.
265 * `expr[expr]`: collection indexing. Overloadable (`Index`, `IndexMut`).
266 * `expr[..]`, `expr[a..]`, `expr[..b]`, `expr[a..b]`: collection indexing
267 pretending to be collection slicing, using `Range`, `RangeFrom`, `RangeTo`, or
268 `RangeFull` as the “index.”
270 ## Appendix C: Derivable Traits
272 In various places in the book, we’ve discussed the `derive` attribute that you
273 can apply to a struct or enum definition.
275 The `derive` attribute generates code that will implement a trait with its own
276 default implementation on the type you’ve annotated with the `derive` syntax.
277 In this appendix, we provide a reference of all the traits in the standard
278 library that you can use with `derive`. Each section covers:
280 * What operators and methods deriving this trait will enable
281 * What the implementation of the trait provided by `derive` does
282 * What implementing the trait signifies about the type
283 * The conditions in which you’re allowed or not allowed to implement the trait
284 * Examples of operations that require the trait
286 If you want different behavior than that provided by the `derive` attribute,
287 consult the standard library documentation for each trait for details on how to
288 manually implement them.
290 The rest of the traits defined in the standard library can’t be implemented on
291 your types using `derive`. These traits don’t have sensible default behavior,
292 so it’s up to you to implement them in the way that makes sense for what you’re
293 trying to accomplish.
295 An example of a trait that can’t be derived is `Display`, which handles
296 formatting for end users. You should always consider the appropriate way to
297 display a type to an end user: for example, what parts of the type should an
298 end user be allowed to see? What parts would they find relevant? What format of
299 the data would be most relevant to them? The Rust compiler doesn’t have this
300 insight, so it can’t provide appropriate default behavior for you.
302 The list of derivable traits provided in this appendix is not comprehensive:
303 libraries can implement `derive` for their own traits, making the list of
304 traits you can use `derive` with truly open-ended. Implementing `derive`
305 involves using a procedural macro, which is covered in Appendix D, “Macros.”
307 ### `Debug` for Programmer Output
309 The `Debug` trait enables debug formatting in format strings, which you
310 indicate by adding `:?` within `{}` placeholders.
312 The `Debug` trait allows you to print instances of a type for debugging
313 purposes, so you and other programmers using your type can inspect an instance
314 at a particular point in a program’s execution.
316 The `Debug` trait is required, for example, in use of the `assert_eq!` macro.
317 This macro prints the values of instances given as arguments if the equality
318 assertion fails so programmers can see why the two instances weren’t equal.
320 ### `PartialEq` and `Eq` for Equality Comparisons
322 The `PartialEq` trait allows you to compare instances of a type to check for
323 equality and enables use of the `==` and `!=` operators.
325 Deriving `PartialEq` implements the `eq` method. When `PartialEq` is derived on
326 structs, two instances are equal only if *all* fields are equal and not equal
327 if any fields are not equal. When derived on enums, each variant is equal to
328 itself and not equal to the other variants.
330 The `PartialEq` trait is required, for example, with the use of the
331 `assert_eq!` macro, which needs to be able to compare two instances of a type
334 The `Eq` trait has no methods. Its purpose is to signal that for every value of
335 the annotated type, the value is equal to itself. The `Eq` trait can only be
336 applied to types that also implement `PartialEq`, although not all types that
337 implement `PartialEq` can implement `Eq`. One example of this is floating point
338 number types: the implementation of floating point numbers states that two
339 instances of the not-a-number (`NaN`) value are not equal to each other.
341 An example of when `Eq` is required is for keys in a `HashMap` so the `HashMap`
342 can tell whether two keys are the same.
344 ### `PartialOrd` and `Ord` for Ordering Comparisons
346 The `PartialOrd` trait allows you to compare instances of a type for sorting
347 purposes. A type that implements `PartialOrd` can be used with the `<`, `>`,
348 `<=`, and `>=` operators. You can only apply the `PartialOrd` trait to types
349 that also implement `PartialEq`.
351 Deriving `PartialOrd` implements the `partial_cmp` method, which returns an
352 `Option<Ordering>` that will be `None` when the values given don’t produce an
353 ordering. An example of a value that doesn’t produce an ordering, even though
354 most values of that type can be compared, is the not-a-number (`NaN`) floating
355 point value. Calling `partial_cmp` with any floating point number and the `NaN`
356 floating point value will return `None`.
358 When derived on structs, `PartialOrd` compares two instances by comparing the
359 value in each field in the order in which the fields appear in the struct
360 definition. When derived on enums, variants of the enum declared earlier in the
361 enum definition are considered less than the variants listed later.
363 The `PartialOrd` trait is required, for example, for the `gen_range` method
364 from the `rand` crate that generates a random value in the range specified by a
365 low value and a high value.
367 The `Ord` trait allows you to know that for any two values of the annotated
368 type, a valid ordering will exist. The `Ord` trait implements the `cmp` method,
369 which returns an `Ordering` rather than an `Option<Ordering>` because a valid
370 ordering will always be possible. You can only apply the `Ord` trait to types
371 that also implement `PartialOrd` and `Eq` (and `Eq` requires `PartialEq`). When
372 derived on structs and enums, `cmp` behaves the same way as the derived
373 implementation for `partial_cmp` does with `PartialOrd`.
375 An example of when `Ord` is required is when storing values in a `BTreeSet<T>`,
376 a data structure that stores data based on the sort order of the values.
378 ### `Clone` and `Copy` for Duplicating Values
380 The `Clone` trait allows you to explicitly create a deep copy of a value, and
381 the duplication process might involve running arbitrary code and copying heap
382 data. See the “Ways Variables and Data Interact: Clone” section in Chapter 4
383 for more information on `Clone`.
385 Deriving `Clone` implements the `clone` method, which when implemented for the
386 whole type, calls `clone` on each of the parts of the type. This means all the
387 fields or values in the type must also implement `Clone` to derive `Clone`.
389 An example of when `Clone` is required is when calling the `to_vec` method on a
390 slice. The slice doesn’t own the type instances it contains, but the vector
391 returned from `to_vec` will need to own its instances, so `to_vec` calls
392 `clone` on each item. Thus, the type stored in the slice must implement `Clone`.
394 The `Copy` trait allows you to duplicate a value by only copying bits stored on
395 the stack; no arbitrary code is necessary. See the “Stack-Only Data: Copy”
396 section in Chapter 4 for more information on `Copy`.
398 The `Copy` trait doesn’t define any methods to prevent programmers from
399 overloading those methods and violating the assumption that no arbitrary code
400 is being run. That way, all programmers can assume that copying a value will be
403 You can derive `Copy` on any type whose parts all implement `Copy`. You can
404 only apply the `Copy` trait to types that also implement `Clone`, because a
405 type that implements `Copy` has a trivial implementation of `Clone` that
406 performs the same task as `Copy`.
408 The `Copy` trait is rarely required; types that implement `Copy` have
409 optimizations available, meaning you don’t have to call `clone`, which makes
410 the code more concise.
412 Everything possible with `Copy` you can also accomplish with `Clone`, but the
413 code might be slower or have to use `clone` in places.
415 ### `Hash` for Mapping a Value to a Value of Fixed Size
417 The `Hash` trait allows you to take an instance of a type of arbitrary size and
418 map that instance to a value of fixed size, using a hash function. Deriving
419 `Hash` implements the `hash` method. The derived implementation of the `hash`
420 method combines the result of calling `hash` on each of the parts of the type,
421 meaning all fields or values must also implement `Hash` to derive `Hash`.
423 An example of when `Hash` is required is in storing keys in a `HashMap` to
424 store data efficiently.
426 ### `Default` for Default Values
428 The `Default` trait allows you to create a default value for a type. Deriving
429 `Default` implements the `default` function. The derived implementation of the
430 `default` function calls the `default` function on each part of the type,
431 meaning all fields or values in the type must also implement `Default` to
434 The `Default::default` function is commonly used in combination with the struct
435 update syntax discussed in the “Creating Instances From Other Instances With
436 Struct Update Syntax” section in Chapter 5. You can customize a few fields of a
437 struct and then set and use a default value for the rest of the fields by using
438 `..Default::default()`.
440 The `Default` trait is required when, for example, you use the
441 `unwrap_or_default` method on `Option<T>` instances. If the `Option<T>` is
442 `None`, the `unwrap_or_default` method will return the result of
443 `Default::default` for the type `T` stored in the `Option<T>`.
445 ## Appendix D: Macros
447 We’ve used macros like `println!` throughout this book but haven’t fully
448 explored what a macro is and how it works. This appendix explains macros as
451 * What macros are and how they differ from functions
452 * How to define a declarative macro to do metaprogramming
453 * How to define a procedural macro to create custom `derive` traits
455 We’re covering the details of macros in an appendix because they’re still
456 evolving in Rust. Macros have changed and, in the near future, will change at a
457 quicker rate than the rest of the language and standard library since Rust 1.0,
458 so this section is more likely to date than the rest of the book. Due to Rust’s
459 stability guarantees, the code shown here will continue to work with future
460 versions. But there may be additional capabilities or easier ways to write
461 macros that weren’t available at the time of this publication. Bear that in
462 mind when you try to implement anything from this appendix.
464 ### The Difference Between Macros and Functions
466 Fundamentally, macros are a way of writing code that writes other code, which
467 is known as *metaprogramming*. In Appendix C, we discussed the `derive`
468 attribute, which generates an implementation of various traits for you. We’ve
469 also used the `println!` and `vec!` macros throughout the book. All of these
470 macros *expand* to produce more code than the code you’ve written manually.
472 Metaprogramming is useful for reducing the amount of code you have to write and
473 maintain, which is also one of the roles of functions. However, macros have
474 some additional powers that functions don’t have.
476 A function signature must declare the number and type of parameters the
477 function has. Macros, on the other hand, can take a variable number of
478 parameters: we can call `println!("hello")` with one argument or
479 `println!("hello {}", name)` with two arguments. Also, macros are expanded
480 before the compiler interprets the meaning of the code, so a macro can, for
481 example, implement a trait on a given type. A function can’t, because it gets
482 called at runtime and a trait needs to be implemented at compile time.
484 The downside to implementing a macro instead of a function is that macro
485 definitions are more complex than function definitions because you’re writing
486 Rust code that writes Rust code. Due to this indirection, macro definitions are
487 generally more difficult to read, understand, and maintain than function
490 Another difference between macros and functions is that macro definitions
491 aren’t namespaced within modules like function definitions are. To prevent
492 unexpected name clashes when using external crates, you have to explicitly
493 bring the macros into the scope of your project at the same time as you bring
494 the external crate into scope, using the `#[macro_use]` annotation. The
495 following example would bring all the macros defined in the `serde` crate into
496 the scope of the current crate:
503 If `extern crate` was able to bring macros into scope by default without this
504 explicit annotation, you would be prevented from using two crates that happened
505 to define macros with the same name. In practice, this conflict doesn’t occur
506 often, but the more crates you use, the more likely it is.
508 There is one last important difference between macros and functions: you must
509 define or bring macros into scope *before* you call them in a file, whereas you
510 can define functions anywhere and call them anywhere.
512 ### Declarative Macros with `macro_rules!` for General Metaprogramming
514 The most widely used form of macros in Rust are *declarative macros*. These are
515 also sometimes referred to as *macros by example*, *`macro_rules!` macros*, or
516 just plain *macros*. At their core, declarative macros allow you to write
517 something similar to a Rust `match` expression. As discussed in Chapter 6,
518 `match` expressions are control structures that take an expression, compare the
519 resulting value of the expression to patterns, and then run the code associated
520 with the matching pattern. Macros also compare a value to patterns that have
521 code associated with them; in this situation, the value is the literal Rust
522 source code passed to the macro, the patterns are compared with the structure
523 of that source code, and the code associated with each pattern is the code that
524 replaces the code passed to the macro. This all happens during compilation.
526 To define a macro, you use the `macro_rules!` construct. Let’s explore how to
527 use `macro_rules!` by looking at how the `vec!` macro is defined. Chapter 8
528 covered how we can use the `vec!` macro to create a new vector with particular
529 values. For example, the following macro creates a new vector with three
533 let v: Vec<u32> = vec![1, 2, 3];
536 We could also use the `vec!` macro to make a vector of two integers or a vector
537 of five string slices: we wouldn’t be able to use a function to do the same
538 because we wouldn’t know the number or type of values up front.
540 Let’s look at a slightly simplified definition of the `vec!` macro in Listing
546 ( $( $x:expr ),* ) => {
548 let mut temp_vec = Vec::new();
558 Listing D-1: A simplified version of the `vec!` macro definition
560 > Note: The actual definition of the `vec!` macro in the standard library
561 > includes code to preallocate the correct amount of memory up front. That code
562 > is an optimization that we don’t include here to make the example simpler.
564 The `#[macro_export]` annotation indicates that this macro should be made
565 available whenever the crate in which we’re defining the macro is imported.
566 Without this annotation, even if someone depending on this crate uses the
567 `#[macro_use]` annotation, the macro wouldn’t be brought into scope.
569 We then start the macro definition with `macro_rules!` and the name of the
570 macro we’re defining *without* the exclamation mark. The name, in this case
571 `vec`, is followed by curly brackets denoting the body of the macro definition.
573 The structure in the `vec!` body is similar to the structure of a `match`
574 expression. Here we have one arm with the pattern `( $( $x:expr ),* )`,
575 followed by `=>` and the block of code associated with this pattern. If the
576 pattern matches, the associated block of code will be emitted. Given that this
577 is the only pattern in this macro, there is only one valid way to match; any
578 other will be an error. More complex macros will have more than one arm.
580 Valid pattern syntax in macro definitions is different than the pattern syntax
581 covered in Chapter 18 because macro patterns are matched against Rust code
582 structure rather than values. Let’s walk through what the pieces of the pattern
583 in Listing D-1 mean; for the full macro pattern syntax, see the reference at
584 *https://doc.rust-lang.org/stable/reference/macros.html*.
586 First, a set of parentheses encompasses the whole pattern. Next comes a dollar
587 sign (`$`) followed by a set of parentheses, which captures values that match
588 the pattern within the parentheses for use in the replacement code. Within
589 `$()` is `$x:expr`, which matches any Rust expression and gives the expression
592 The comma following `$()` indicates that a literal comma separator character
593 could optionally appear after the code that matches the code captured in `$()`.
594 The `*` following the comma specifies that the pattern matches zero or more of
595 whatever precedes the `*`.
597 When we call this macro with `vec![1, 2, 3];`, the `$x` pattern matches three
598 times with the three expressions `1`, `2`, and `3`.
600 Now let’s look at the pattern in the body of the code associated with this arm:
601 the `temp_vec.push()` code within the `$()*` part is generated for each part
602 that matches `$()` in the pattern, zero or more times depending on how many
603 times the pattern matches. The `$x` is replaced with each expression matched.
604 When we call this macro with `vec![1, 2, 3];`, the code generated that replaces
605 this macro call will be the following:
608 let mut temp_vec = Vec::new();
615 We’ve defined a macro that can take any number of arguments of any type and can
616 generate code to create a vector containing the specified elements.
618 Given that most Rust programmers will *use* macros more than *write* macros, we
619 won’t discuss `macro_rules!` any further. To learn more about how to write
620 macros, consult the online documentation or other resources, such as “The
621 Little Book of Rust Macros” at
622 *https://danielkeep.github.io/tlborm/book/index.html*.
624 ### Procedural Macros for Custom `derive`
626 The second form of macros is called *procedural macros* because they’re more
627 like functions (which are a type of procedure). Procedural macros accept some
628 Rust code as an input, operate on that code, and produce some Rust code as an
629 output rather than matching against patterns and replacing the code with other
630 code as declarative macros do. At the time of this writing, you can only define
631 procedural macros to allow your traits to be implemented on a type by
632 specifying the trait name in a `derive` annotation.
634 We’ll create a crate named `hello_macro` that defines a trait named
635 `HelloMacro` with one associated function named `hello_macro`. Rather than
636 making our crate users implement the `HelloMacro` trait for each of their
637 types, we’ll provide a procedural macro so users can annotate their type with
638 `#[derive(HelloMacro)]` to get a default implementation of the `hello_macro`
639 function. The default implementation will print `Hello, Macro! My name is
640 TypeName!` where `TypeName` is the name of the type on which this trait has
641 been defined. In other words, we’ll write a crate that enables another
642 programmer to write code like Listing D-2 using our crate.
644 Filename: src/main.rs
647 extern crate hello_macro;
649 extern crate hello_macro_derive;
651 use hello_macro::HelloMacro;
653 #[derive(HelloMacro)]
657 Pancakes::hello_macro();
661 Listing D-2: The code a user of our crate will be able to write when using our
664 This code will print `Hello, Macro! My name is Pancakes!` when we’re done. The
665 first step is to make a new library crate, like this:
668 $ cargo new hello_macro --lib
671 Next, we’ll define the `HelloMacro` trait and its associated function:
676 pub trait HelloMacro {
681 We have a trait and its function. At this point, our crate user could implement
682 the trait to achieve the desired functionality, like so:
685 extern crate hello_macro;
687 use hello_macro::HelloMacro;
691 impl HelloMacro for Pancakes {
693 println!("Hello, Macro! My name is Pancakes!");
698 Pancakes::hello_macro();
702 However, they would need to write the implementation block for each type they
703 wanted to use with `hello_macro`; we want to spare them from having to do this
706 Additionally, we can’t yet provide a default implementation for the
707 `hello_macro` function that will print the name of the type the trait is
708 implemented on: Rust doesn’t have reflection capabilities, so it can’t look up
709 the type’s name at runtime. We need a macro to generate code at compile time.
711 The next step is to define the procedural macro. At the time of this writing,
712 procedural macros need to be in their own crate. Eventually, this restriction
713 might be lifted. The convention for structuring crates and macro crates is as
714 follows: for a crate named `foo`, a custom derive procedural macro crate is
715 called `foo_derive`. Let’s start a new crate called `hello_macro_derive` inside
716 our `hello_macro` project:
719 $ cargo new hello_macro_derive --lib
722 Our two crates are tightly related, so we create the procedural macro crate
723 within the directory of our `hello_macro` crate. If we change the trait
724 definition in `hello_macro`, we’ll have to change the implementation of the
725 procedural macro in `hello_macro_derive` as well. The two crates will need to
726 be published separately, and programmers using these crates will need to add
727 both as dependencies and bring them both into scope. We could instead have the
728 `hello_macro` crate use `hello_macro_derive` as a dependency and reexport the
729 procedural macro code. But the way we’ve structured the project makes it
730 possible for programmers to use `hello_macro` even if they don’t want the
731 `derive` functionality.
733 We need to declare the `hello_macro_derive` crate as a procedural macro crate.
734 We’ll also need functionality from the `syn` and `quote` crates, as you’ll see
735 in a moment, so we need to add them as dependencies. Add the following to the
736 *Cargo.toml* file for `hello_macro_derive`:
738 Filename: hello_macro_derive/Cargo.toml
749 To start defining the procedural macro, place the code in Listing D-3 into your
750 *src/lib.rs* file for the `hello_macro_derive` crate. Note that this code won’t
751 compile until we add a definition for the `impl_hello_macro` function.
753 Notice the way we’ve split the functions in D-3; this will be the same for
754 almost every procedural macro crate you see or create, because it makes writing
755 a procedural macro more convenient. What you choose to do in the place where
756 the `impl_hello_macro` function is called will be different depending on your
757 procedural macro’s purpose.
759 Filename: hello_macro_derive/src/lib.rs
762 extern crate proc_macro;
767 use proc_macro::TokenStream;
769 #[proc_macro_derive(HelloMacro)]
770 pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
771 // Construct a string representation of the type definition
772 let s = input.to_string();
774 // Parse the string representation
775 let ast = syn::parse_derive_input(&s).unwrap();
778 let gen = impl_hello_macro(&ast);
780 // Return the generated impl
785 Listing D-3: Code that most procedural macro crates will need to have for
788 We’ve introduced three new crates: `proc_macro`, `syn` (available from
789 *https://crates.io/crates/syn*), and `quote` (available from
790 *https://crates.io/crates/quote*). The `proc_macro` crate comes with Rust, so
791 we didn’t need to add that to the dependencies in *Cargo.toml*. The
792 `proc_macro` crate allows us to convert Rust code into a string containing that
793 Rust code. The `syn` crate parses Rust code from a string into a data structure
794 that we can perform operations on. The `quote` crate takes `syn` data
795 structures and turns them back into Rust code. These crates make it much
796 simpler to parse any sort of Rust code we might want to handle: writing a full
797 parser for Rust code is no simple task.
799 The `hello_macro_derive` function will get called when a user of our library
800 specifies `#[derive(HelloMacro)]` on a type. The reason is that we’ve annotated
801 the `hello_macro_derive` function here with `proc_macro_derive` and specified
802 the name, `HelloMacro`, which matches our trait name; that’s the convention
803 most procedural macros follow.
805 This function first converts the `input` from a `TokenStream` to a `String` by
806 calling `to_string`. This `String` is a string representation of the Rust code
807 for which we are deriving `HelloMacro`. In the example in Listing D-2, `s` will
808 have the `String` value `struct Pancakes;` because that is the Rust code we
809 added the `#[derive(HelloMacro)]` annotation to.
811 > Note: At the time of this writing, you can only convert a `TokenStream` to a
812 > string. A richer API will exist in the future.
814 Now we need to parse the Rust code `String` into a data structure that we can
815 then interpret and perform operations on. This is where `syn` comes into play.
816 The `parse_derive_input` function in `syn` takes a `String` and returns a
817 `DeriveInput` struct representing the parsed Rust code. The following code
818 shows the relevant parts of the `DeriveInput` struct we get from parsing the
819 string `struct Pancakes;`:
834 The fields of this struct show that the Rust code we’ve parsed is a unit struct
835 with the `ident` (identifier, meaning the name) of `Pancakes`. There are more
836 fields on this struct for describing all sorts of Rust code; check the `syn`
837 documentation for `DeriveInput` at
838 *https://docs.rs/syn/0.11.11/syn/struct.DeriveInput.html* for more information.
840 At this point, we haven’t defined the `impl_hello_macro` function, which is
841 where we’ll build the new Rust code we want to include. But before we do, note
842 that the last part of this `hello_macro_derive` function uses the `parse`
843 function from the `quote` crate to turn the output of the `impl_hello_macro`
844 function back into a `TokenStream`. The returned `TokenStream` is added to the
845 code that our crate users write, so when they compile their crate, they get
846 extra functionality that we provide.
848 You might have noticed that we’re calling `unwrap` to panic if the calls to the
849 `parse_derive_input` or `parse` functions fail here. Panicking on errors is
850 necessary in procedural macro code because `proc_macro_derive` functions must
851 return `TokenStream` rather than `Result` to conform to the procedural macro
852 API. We’ve chosen to simplify this example by using `unwrap`; in production
853 code, you should provide more specific error messages about what went wrong by
854 using `panic!` or `expect`.
856 Now that we have the code to turn the annotated Rust code from a `TokenStream`
857 into a `String` and a `DeriveInput` instance, let’s generate the code that
858 implements the `HelloMacro` trait on the annotated type:
860 hello_macro_derive/src/lib.rs
863 fn impl_hello_macro(ast: &syn::DeriveInput) -> quote::Tokens {
864 let name = &ast.ident;
866 impl HelloMacro for #name {
868 println!("Hello, Macro! My name is {}", stringify!(#name));
875 We get an `Ident` struct instance containing the name (identifier) of the
876 annotated type using `ast.ident`. The code in Listing D-2 specifies that the
877 `name` will be `Ident("Pancakes")`.
879 The `quote!` macro lets us write the Rust code that we want to return and
880 convert it into `quote::Tokens`. This macro also provides some very cool
881 templating mechanics; we can write `#name` and `quote!` will replace it with
882 the value in the variable named `name`. You can even do some repetition similar
883 to the way regular macros work. Check out the `quote` crate’s docs at
884 *https://docs.rs/quote* for a thorough introduction.
886 We want our procedural macro to generate an implementation of our `HelloMacro`
887 trait for the type the user annotated, which we can get by using `#name`. The
888 trait implementation has one function, `hello_macro`, whose body contains the
889 functionality we want to provide: printing `Hello, Macro! My name is` and then
890 the name of the annotated type.
892 The `stringify!` macro used here is built into Rust. It takes a Rust
893 expression, such as `1 + 2`, and at compile time turns the expression into a
894 string literal, such as `"1 + 2"`. This is different than `format!` or
895 `println!`, which evaluate the expression and then turn the result into a
896 `String`. There is a possibility that the `#name` input might be an expression
897 to print literally, so we use `stringify!`. Using `stringify!` also saves an
898 allocation by converting `#name` to a string literal at compile time.
900 At this point, `cargo build` should complete successfully in both `hello_macro`
901 and `hello_macro_derive`. Let’s hook up these crates to the code in Listing D-2
902 to see the procedural macro in action! Create a new binary project in your
903 *projects* directory using `cargo new --bin pancakes`. We need to add
904 `hello_macro` and `hello_macro_derive` as dependencies in the `pancakes`
905 crate’s *Cargo.toml*. If you’re publishing your versions of `hello_macro` and
906 `hello_macro_derive` to *https://crates.io/*, they would be regular
907 dependencies; if not, you can specify them as `path` dependencies as follows:
911 hello_macro = { path = "../hello_macro" }
912 hello_macro_derive = { path = "../hello_macro/hello_macro_derive" }
915 Put the code from Listing D-2 into *src/main.rs*, and run `cargo run`: it
916 should print `Hello, Macro! My name is Pancakes!` The implementation of the
917 `HelloMacro` trait from the procedural macro was included without the
918 `pancakes` crate needing to implement it; the `#[derive(HelloMacro)]` added the
919 trait implementation.
921 ### The Future of Macros
923 In the future, Rust will expand declarative and procedural macros. Rust will
924 use a better declarative macro system with the `macro` keyword and will add
925 more types of procedural macros for more powerful tasks than just `derive`.
926 These systems are still under development at the time of this publication;
927 please consult the online Rust documentation for the latest information.