]> git.proxmox.com Git - rustc.git/blob - src/doc/book/second-edition/nostarch/appendix.md
New upstream version 1.33.0+dfsg1
[rustc.git] / src / doc / book / second-edition / nostarch / appendix.md
1
2 [TOC]
3
4 ## Appendix A: Keywords
5
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.
10
11 ### Keywords Currently in Use
12
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
51
52 ### Keywords Reserved for Future Use
53
54 The following keywords do not have any functionality but are reserved by Rust
55 for potential future use.
56
57 * `abstract`
58 * `alignof`
59 * `become`
60 * `box`
61 * `do`
62 * `final`
63 * `macro`
64 * `offsetof`
65 * `override`
66 * `priv`
67 * `proc`
68 * `pure`
69 * `sizeof`
70 * `typeof`
71 * `unsized`
72 * `virtual`
73 * `yield`
74
75 ## Appendix B: Operators and Symbols
76
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.
80
81 ### Operators
82
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.
87
88
89 * `!` (`ident!(...)`, `ident!{...}`, `ident![...]`): denotes macro
90 expansion.
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
95 (`RemAssign`).
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
100 (`BitAndAssign`).
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
106 (`MulAssign`).
107 * `+` (`trait + trait`, `'a + trait`): compound type constraint.
108 * `+` (`expr + expr`): arithmetic addition. Overloadable (`Add`).
109 * `+=` (`var += expr`): arithmetic addition and assignment. Overloadable
110 (`AddAssign`).
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
115 (`SubAssign`).
116 * `->` (`fn(...) -> type`, `|...| -> type`): function and closure
117 return type.
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
122 binding.
123 * `...` (`expr...expr`) *in a pattern*: inclusive range pattern.
124 * `/` (`expr / expr`): arithmetic division. Overloadable (`Div`).
125 * `/=` (`var /= expr`): arithmetic division and assignment. Overloadable
126 (`DivAssign`).
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
136 (`PartialOrd`).
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
142 (`PartialOrd`).
143 * `>>` (`expr >> expr`): right-shift. Overloadable (`Shr`).
144 * `>>=` (`var >>= expr`): right-shift and assignment. Overloadable
145 (`ShrAssign`).
146 * `@` (`ident @ pat`): pattern binding.
147 * `^` (`expr ^ expr`): bitwise exclusive OR. Overloadable (`BitXor`).
148 * `^=` (`var ^= expr`): bitwise exclusive OR and assignment. Overloadable
149 (`BitXorAssign`).
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.
157
158 ### Non-operator Symbols
159
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.
162
163 #### Stand-Alone Syntax
164
165 * `'ident`: named lifetime or loop label.
166 * `...u8`, `...i32`, `...f64`, `...usize`, *etc.*: numeric literal of
167 specific type.
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.
178
179 #### Path-Related Syntax
180
181 * `ident::ident`: namespace path.
182 * `::path`: path relative to the crate root (*i.e.*, an explicitly absolute
183 path).
184 * `self::path`: path relative to the current module (*i.e.*, an explicitly
185 relative path).
186 * `super::path`: path relative to the parent of the current module.
187 * `type::ident`, `<type as trait>::ident`: associated constants, functions, and
188 types.
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
192 that defines it.
193 * `type::method(...)`: disambiguating a method call by naming the type for
194 which it’s defined.
195 * `<type as trait>::method(...)`: disambiguating a method call by naming
196 the trait *and* type.
197
198 #### Generics
199
200 * `path<...>` (*e.g.*, `Vec<u8>`): specifies parameters to generic type *in
201 a type*.
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.
212
213 #### Trait Bound Constraints
214
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
220 than `'static` ones.
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.
224
225 #### Macros and Attributes
226
227 * `#[meta]`: outer attribute.
228 * `#![meta]`: inner attribute.
229 * `$ident`: macro substitution.
230 * `$ident:kind`: macro capture.
231 * `$(…)…`: macro repetition.
232
233 #### Comments
234
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.
241
242 #### Tuples
243
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.
254
255 #### Curly Brackets
256
257 * `{...}`: block expression.
258 * `Type {...}`: `struct` literal.
259
260 #### Square Brackets
261
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.”
269
270 ## Appendix C: Derivable Traits
271
272 In various places in the book, we’ve discussed the `derive` attribute that you
273 can apply to a struct or enum definition.
274
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:
279
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
285
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.
289
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.
294
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.
301
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.”
306
307 ### `Debug` for Programmer Output
308
309 The `Debug` trait enables debug formatting in format strings, which you
310 indicate by adding `:?` within `{}` placeholders.
311
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.
315
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.
319
320 ### `PartialEq` and `Eq` for Equality Comparisons
321
322 The `PartialEq` trait allows you to compare instances of a type to check for
323 equality and enables use of the `==` and `!=` operators.
324
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.
329
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
332 for equality.
333
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.
340
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.
343
344 ### `PartialOrd` and `Ord` for Ordering Comparisons
345
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`.
350
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`.
357
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.
362
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.
366
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`.
374
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.
377
378 ### `Clone` and `Copy` for Duplicating Values
379
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`.
384
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`.
388
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`.
393
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`.
397
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
401 very fast.
402
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`.
407
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.
411
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.
414
415 ### `Hash` for Mapping a Value to a Value of Fixed Size
416
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`.
422
423 An example of when `Hash` is required is in storing keys in a `HashMap` to
424 store data efficiently.
425
426 ### `Default` for Default Values
427
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
432 derive `Default.`
433
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()`.
439
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>`.
444
445 ## Appendix D: Macros
446
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
449 follows:
450
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
454
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.
463
464 ### The Difference Between Macros and Functions
465
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.
471
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.
475
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.
483
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
488 definitions.
489
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:
497
498 ```
499 #[macro_use]
500 extern crate serde;
501 ```
502
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.
507
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.
511
512 ### Declarative Macros with `macro_rules!` for General Metaprogramming
513
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.
525
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
530 integers inside:
531
532 ```
533 let v: Vec<u32> = vec![1, 2, 3];
534 ```
535
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.
539
540 Let’s look at a slightly simplified definition of the `vec!` macro in Listing
541 D-1:
542
543 ```
544 #[macro_export]
545 macro_rules! vec {
546 ( $( $x:expr ),* ) => {
547 {
548 let mut temp_vec = Vec::new();
549 $(
550 temp_vec.push($x);
551 )*
552 temp_vec
553 }
554 };
555 }
556 ```
557
558 Listing D-1: A simplified version of the `vec!` macro definition
559
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.
563
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.
568
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.
572
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.
579
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*.
585
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
590 the name `$x`.
591
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 `*`.
596
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`.
599
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:
606
607 ```
608 let mut temp_vec = Vec::new();
609 temp_vec.push(1);
610 temp_vec.push(2);
611 temp_vec.push(3);
612 temp_vec
613 ```
614
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.
617
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*.
623
624 ### Procedural Macros for Custom `derive`
625
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.
633
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.
643
644 Filename: src/main.rs
645
646 ```
647 extern crate hello_macro;
648 #[macro_use]
649 extern crate hello_macro_derive;
650
651 use hello_macro::HelloMacro;
652
653 #[derive(HelloMacro)]
654 struct Pancakes;
655
656 fn main() {
657 Pancakes::hello_macro();
658 }
659 ```
660
661 Listing D-2: The code a user of our crate will be able to write when using our
662 procedural macro
663
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:
666
667 ```
668 $ cargo new hello_macro --lib
669 ```
670
671 Next, we’ll define the `HelloMacro` trait and its associated function:
672
673 Filename: src/lib.rs
674
675 ```
676 pub trait HelloMacro {
677 fn hello_macro();
678 }
679 ```
680
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:
683
684 ```
685 extern crate hello_macro;
686
687 use hello_macro::HelloMacro;
688
689 struct Pancakes;
690
691 impl HelloMacro for Pancakes {
692 fn hello_macro() {
693 println!("Hello, Macro! My name is Pancakes!");
694 }
695 }
696
697 fn main() {
698 Pancakes::hello_macro();
699 }
700 ```
701
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
704 work.
705
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.
710
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:
717
718 ```
719 $ cargo new hello_macro_derive --lib
720 ```
721
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.
732
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`:
737
738 Filename: hello_macro_derive/Cargo.toml
739
740 ```
741 [lib]
742 proc-macro = true
743
744 [dependencies]
745 syn = "0.11.11"
746 quote = "0.3.15"
747 ```
748
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.
752
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.
758
759 Filename: hello_macro_derive/src/lib.rs
760
761 ```
762 extern crate proc_macro;
763 extern crate syn;
764 #[macro_use]
765 extern crate quote;
766
767 use proc_macro::TokenStream;
768
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();
773
774 // Parse the string representation
775 let ast = syn::parse_derive_input(&s).unwrap();
776
777 // Build the impl
778 let gen = impl_hello_macro(&ast);
779
780 // Return the generated impl
781 gen.parse().unwrap()
782 }
783 ```
784
785 Listing D-3: Code that most procedural macro crates will need to have for
786 processing Rust code
787
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.
798
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.
804
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.
810
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.
813
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;`:
820
821 ```
822 DeriveInput {
823 // --snip--
824
825 ident: Ident(
826 "Pancakes"
827 ),
828 body: Struct(
829 Unit
830 )
831 }
832 ```
833
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.
839
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.
847
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`.
855
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:
859
860 hello_macro_derive/src/lib.rs
861
862 ```
863 fn impl_hello_macro(ast: &syn::DeriveInput) -> quote::Tokens {
864 let name = &ast.ident;
865 quote! {
866 impl HelloMacro for #name {
867 fn hello_macro() {
868 println!("Hello, Macro! My name is {}", stringify!(#name));
869 }
870 }
871 }
872 }
873 ```
874
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")`.
878
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.
885
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.
891
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.
899
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:
908
909 ```
910 [dependencies]
911 hello_macro = { path = "../hello_macro" }
912 hello_macro_derive = { path = "../hello_macro/hello_macro_derive" }
913 ```
914
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.
920
921 ### The Future of Macros
922
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.