diff --git a/build.sh b/build.sh
index 87ad2e9..ca5aefd 100755
--- a/build.sh
+++ b/build.sh
@@ -1,6 +1,7 @@
#! /bin/sh
-RUN="cargo run --release --"
+RUN="cargo run --"
-$RUN --prefix=trpl --source=trpl --meta=trpl_meta.yml && \
-$RUN --prefix=nomicon --source=nomicon --meta=nomicon_meta.yml
+# $RUN --prefix=trpl-1st-ed --source=trpl-1st-edition --meta=trpl_meta.yml && \
+$RUN --prefix=trpl-2nd-ed --source=trpl-2nd-edition --meta=trpl_meta.yml
+# $RUN --prefix=nomicon --source=nomicon --meta=nomicon_meta.yml
diff --git a/img/trpl04-01.svg b/img/trpl04-01.svg
new file mode 100644
index 0000000..7f5ee8d
--- /dev/null
+++ b/img/trpl04-01.svg
@@ -0,0 +1,65 @@
+
+
+
+
+
diff --git a/img/trpl04-02.svg b/img/trpl04-02.svg
new file mode 100644
index 0000000..7d3a29a
--- /dev/null
+++ b/img/trpl04-02.svg
@@ -0,0 +1,90 @@
+
+
+
+
+
diff --git a/img/trpl04-03.svg b/img/trpl04-03.svg
new file mode 100644
index 0000000..a606851
--- /dev/null
+++ b/img/trpl04-03.svg
@@ -0,0 +1,117 @@
+
+
+
+
+
diff --git a/img/trpl04-04.svg b/img/trpl04-04.svg
new file mode 100644
index 0000000..1a17b27
--- /dev/null
+++ b/img/trpl04-04.svg
@@ -0,0 +1,91 @@
+
+
+
+
+
diff --git a/img/trpl04-05.svg b/img/trpl04-05.svg
new file mode 100644
index 0000000..33e5b49
--- /dev/null
+++ b/img/trpl04-05.svg
@@ -0,0 +1,82 @@
+
+
+
+
+
diff --git a/img/trpl04-06.svg b/img/trpl04-06.svg
new file mode 100644
index 0000000..1a87522
--- /dev/null
+++ b/img/trpl04-06.svg
@@ -0,0 +1,110 @@
+
+
+
+
+
diff --git a/img/trpl15-01.svg b/img/trpl15-01.svg
new file mode 100644
index 0000000..b873825
--- /dev/null
+++ b/img/trpl15-01.svg
@@ -0,0 +1,42 @@
+
+
+
+
+
diff --git a/img/trpl15-02.svg b/img/trpl15-02.svg
new file mode 100644
index 0000000..5b86985
--- /dev/null
+++ b/img/trpl15-02.svg
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/img/trpl15-03.svg b/img/trpl15-03.svg
new file mode 100644
index 0000000..e26024f
--- /dev/null
+++ b/img/trpl15-03.svg
@@ -0,0 +1,94 @@
+
+
+
+
+
diff --git a/img/trpl15-04.svg b/img/trpl15-04.svg
new file mode 100644
index 0000000..96ad98c
--- /dev/null
+++ b/img/trpl15-04.svg
@@ -0,0 +1,55 @@
+
+
+
+
+
diff --git a/lib/epub.css b/lib/epub.css
index d63c7e1..ee877d8 100644
--- a/lib/epub.css
+++ b/lib/epub.css
@@ -14,4 +14,4 @@ ol.toc { padding: 0; margin-left: 1em; }
ol.toc li { list-style-type: none; margin: 0; padding: 0; }
a.footnoteRef { vertical-align: super; }
-pre { text-align: left; white-space: pre-wrap; font-size: 0.6em; }
+pre { text-align: left; white-space: pre-wrap; font-size: 0.85em}
diff --git a/lib/template.tex b/lib/template.tex
index 213ae78..f65357e 100644
--- a/lib/template.tex
+++ b/lib/template.tex
@@ -16,7 +16,9 @@
\fi
$endif$
-\usepackage[$if(papersize)$$papersize$$else$a4paper$endif$]{geometry}
+\usepackage[$if(papersize)$$papersize$$else$a4paper$endif$,margin=27mm]{geometry}
+\addtolength{\topmargin}{-7mm}
+\addtolength{\textheight}{18mm}
\usepackage{graphicx}
diff --git a/nomicon/README.md b/nomicon/README.md
index 0654313..d577d7b 100644
--- a/nomicon/README.md
+++ b/nomicon/README.md
@@ -1,8 +1,8 @@
-% The Rustonomicon
+# The Rustonomicon
#### The Dark Arts of Advanced and Unsafe Rust Programming
-**NOTE: This is a draft document, and may contain serious errors**
+# NOTE: This is a draft document, and may contain serious errors
> Instead of the programs I had hoped for, there came only a shuddering blackness
and ineffable loneliness; and I saw at last a fearful truth which no one had
@@ -35,4 +35,4 @@ exception-safety, pointer aliasing, memory models, and even some type-theory.
We will also be spending a lot of time talking about the different kinds
of safety and guarantees.
-[trpl]: ../book/
+[trpl]: ../book/index.html
diff --git a/nomicon/SUMMARY.md b/nomicon/SUMMARY.md
index 7d4ef9c..e33dcbb 100644
--- a/nomicon/SUMMARY.md
+++ b/nomicon/SUMMARY.md
@@ -1,5 +1,7 @@
# Summary
+[Introduction](README.md)
+
* [Meet Safe and Unsafe](meet-safe-and-unsafe.md)
* [How Safe and Unsafe Interact](safe-unsafe-meaning.md)
* [Working with Unsafe](working-with-unsafe.md)
diff --git a/nomicon/arc-and-mutex.md b/nomicon/arc-and-mutex.md
index fcafe55..fedc7b8 100644
--- a/nomicon/arc-and-mutex.md
+++ b/nomicon/arc-and-mutex.md
@@ -1,4 +1,4 @@
-% Implementing Arc and Mutex
+# Implementing Arc and Mutex
Knowing the theory is all fine and good, but the *best* way to understand
something is to use it. To better understand atomics and interior mutability,
diff --git a/nomicon/atomics.md b/nomicon/atomics.md
index 1efca08..e9ed21a 100644
--- a/nomicon/atomics.md
+++ b/nomicon/atomics.md
@@ -1,4 +1,4 @@
-% Atomics
+# Atomics
Rust pretty blatantly just inherits C11's memory model for atomics. This is not
due to this model being particularly excellent or easy to understand. Indeed,
@@ -24,10 +24,10 @@ exactly what we said but, you know, fast. Wouldn't that be great?
# Compiler Reordering
-Compilers fundamentally want to be able to do all sorts of crazy transformations
-to reduce data dependencies and eliminate dead code. In particular, they may
-radically change the actual order of events, or make events never occur! If we
-write something like
+Compilers fundamentally want to be able to do all sorts of complicated
+transformations to reduce data dependencies and eliminate dead code. In
+particular, they may radically change the actual order of events, or make events
+never occur! If we write something like
```rust,ignore
x = 1;
diff --git a/nomicon/borrow-splitting.md b/nomicon/borrow-splitting.md
index cc5bc8a..28ddb50 100644
--- a/nomicon/borrow-splitting.md
+++ b/nomicon/borrow-splitting.md
@@ -1,4 +1,4 @@
-% Splitting Borrows
+# Splitting Borrows
The mutual exclusion property of mutable references can be very limiting when
working with a composite structure. The borrow checker understands some basic
diff --git a/nomicon/casts.md b/nomicon/casts.md
index 6cc41bd..31b7858 100644
--- a/nomicon/casts.md
+++ b/nomicon/casts.md
@@ -1,4 +1,4 @@
-% Casts
+# Casts
Casts are a superset of coercions: every coercion can be explicitly
invoked via a cast. However some conversions require a cast.
diff --git a/nomicon/checked-uninit.md b/nomicon/checked-uninit.md
index f7c4482..4423404 100644
--- a/nomicon/checked-uninit.md
+++ b/nomicon/checked-uninit.md
@@ -1,4 +1,4 @@
-% Checked Uninitialized Memory
+# Checked Uninitialized Memory
Like C, all stack variables in Rust are uninitialized until a value is
explicitly assigned to them. Unlike C, Rust statically prevents you from ever
diff --git a/nomicon/coercions.md b/nomicon/coercions.md
index 6a9ebd6..1a51bb5 100644
--- a/nomicon/coercions.md
+++ b/nomicon/coercions.md
@@ -1,4 +1,4 @@
-% Coercions
+# Coercions
Types can implicitly be coerced to change in certain contexts. These changes are
generally just *weakening* of types, largely focused around pointers and
@@ -17,6 +17,7 @@ Coercion is allowed between the following types:
* `&T` to `*const T`
* `&mut T` to `*mut T`
* Unsizing: `T` to `U` if `T` implements `CoerceUnsized`
+* Deref coercion: Expression `&x` of type `&T` to `&*x` of type `&U` if `T` derefs to `U` (i.e. `T: Deref`)
`CoerceUnsized> for Pointer where T: Unsize` is implemented
for all pointer types (including smart pointers like Box and Rc). Unsize is
@@ -27,8 +28,9 @@ only implemented automatically, and enables the following transformations:
* `Foo<..., T, ...>` => `Foo<..., U, ...>` where:
* `T: Unsize`
* `Foo` is a struct
- * Only the last field of `Foo` has type `T`
+ * Only the last field of `Foo` has type involving `T`
* `T` is not part of the type of any other fields
+ * `Bar: Unsize>`, if the last field of `Foo` has type `Bar`
Coercions occur at a *coercion site*. Any location that is explicitly typed
will cause a coercion to its type. If inference is necessary, the coercion will
diff --git a/nomicon/concurrency.md b/nomicon/concurrency.md
index b93b303..6205199 100644
--- a/nomicon/concurrency.md
+++ b/nomicon/concurrency.md
@@ -1,4 +1,4 @@
-% Concurrency and Parallelism
+# Concurrency and Parallelism
Rust as a language doesn't *really* have an opinion on how to do concurrency or
parallelism. The standard library exposes OS threads and blocking sys-calls
diff --git a/nomicon/constructors.md b/nomicon/constructors.md
index 97817cd..b79e72d 100644
--- a/nomicon/constructors.md
+++ b/nomicon/constructors.md
@@ -1,4 +1,4 @@
-% Constructors
+# Constructors
There is exactly one way to create an instance of a user-defined type: name it,
and initialize all its fields at once:
diff --git a/nomicon/conversions.md b/nomicon/conversions.md
index b099a78..388d003 100644
--- a/nomicon/conversions.md
+++ b/nomicon/conversions.md
@@ -1,4 +1,4 @@
-% Type Conversions
+# Type Conversions
At the end of the day, everything is just a pile of bits somewhere, and type
systems are just there to help us use those bits right. There are two common
diff --git a/nomicon/data.md b/nomicon/data.md
index d0a796b..bf202ad 100644
--- a/nomicon/data.md
+++ b/nomicon/data.md
@@ -1,4 +1,4 @@
-% Data Representation in Rust
+# Data Representation in Rust
Low-level programming cares a lot about data layout. It's a big deal. It also
pervasively influences the rest of the language, so we're going to start by
diff --git a/nomicon/destructors.md b/nomicon/destructors.md
index c6fa5b0..8c395fe 100644
--- a/nomicon/destructors.md
+++ b/nomicon/destructors.md
@@ -1,4 +1,4 @@
-% Destructors
+# Destructors
What the language *does* provide is full-blown automatic destructors through the
`Drop` trait, which provides the following method:
@@ -26,7 +26,7 @@ this is totally fine.
For instance, a custom implementation of `Box` might write `Drop` like this:
```rust
-#![feature(alloc, heap_api, drop_in_place, unique)]
+#![feature(alloc, heap_api, unique)]
extern crate alloc;
@@ -57,7 +57,7 @@ use-after-free the `ptr` because when drop exits, it becomes inaccessible.
However this wouldn't work:
```rust
-#![feature(alloc, heap_api, drop_in_place, unique)]
+#![feature(alloc, heap_api, unique)]
extern crate alloc;
@@ -135,7 +135,7 @@ The classic safe solution to overriding recursive drop and allowing moving out
of Self during `drop` is to use an Option:
```rust
-#![feature(alloc, heap_api, drop_in_place, unique)]
+#![feature(alloc, heap_api, unique)]
extern crate alloc;
diff --git a/nomicon/dot-operator.md b/nomicon/dot-operator.md
index 5d2010d..a1fc33b 100644
--- a/nomicon/dot-operator.md
+++ b/nomicon/dot-operator.md
@@ -1,4 +1,4 @@
-% The Dot Operator
+# The Dot Operator
The dot operator will perform a lot of magic to convert types. It will perform
auto-referencing, auto-dereferencing, and coercion until types match.
diff --git a/nomicon/drop-flags.md b/nomicon/drop-flags.md
index cfceafe..e69264f 100644
--- a/nomicon/drop-flags.md
+++ b/nomicon/drop-flags.md
@@ -1,4 +1,4 @@
-% Drop Flags
+# Drop Flags
The examples in the previous section introduce an interesting problem for Rust.
We have seen that it's possible to conditionally initialize, deinitialize, and
@@ -79,17 +79,5 @@ if condition {
}
```
-As of Rust 1.0, the drop flags are actually not-so-secretly stashed in a hidden
-field of any type that implements Drop. Rust sets the drop flag by overwriting
-the entire value with a particular bit pattern. This is pretty obviously Not
-The Fastest and causes a bunch of trouble with optimizing code. It's legacy from
-a time when you could do much more complex conditional initialization.
-
-As such work is currently under way to move the flags out onto the stack frame
-where they more reasonably belong. Unfortunately, this work will take some time
-as it requires fairly substantial changes to the compiler.
-
-Regardless, Rust programs don't need to worry about uninitialized values on
-the stack for correctness. Although they might care for performance. Thankfully,
-Rust makes it easy to take control here! Uninitialized values are there, and
-you can work with them in Safe Rust, but you're never in danger.
+The drop flags are tracked on the stack and no longer stashed in types that
+implement drop.
diff --git a/nomicon/dropck.md b/nomicon/dropck.md
index ad7c650..3903969 100644
--- a/nomicon/dropck.md
+++ b/nomicon/dropck.md
@@ -1,4 +1,4 @@
-% Drop Check
+# Drop Check
We have seen how lifetimes provide us some fairly simple rules for ensuring
that we never read dangling references. However up to this point we have only ever
@@ -125,7 +125,7 @@ is that some Drop implementations will not access borrowed data even
though their type gives them the capability for such access.
For example, this variant of the above `Inspector` example will never
-accessed borrowed data:
+access borrowed data:
```rust,ignore
struct Inspector<'a>(&'a u8, &'static str);
@@ -199,24 +199,42 @@ assert (unsafely) that a generic type's destructor is *guaranteed* to
not access any expired data, even if its type gives it the capability
to do so.
-That attribute is called `unsafe_destructor_blind_to_params`.
+That attribute is called `may_dangle` and was introduced in [RFC 1327]
+(https://github.com/rust-lang/rfcs/blob/master/text/1327-dropck-param-eyepatch.md).
To deploy it on the Inspector example from above, we would write:
```rust,ignore
struct Inspector<'a>(&'a u8, &'static str);
-impl<'a> Drop for Inspector<'a> {
- #[unsafe_destructor_blind_to_params]
+unsafe impl<#[may_dangle] 'a> Drop for Inspector<'a> {
fn drop(&mut self) {
println!("Inspector(_, {}) knows when *not* to inspect.", self.1);
}
}
```
-This attribute has the word `unsafe` in it because the compiler is not
-checking the implicit assertion that no potentially expired data
+Use of this attribute requires the `Drop` impl to be marked `unsafe` because the
+compiler is not checking the implicit assertion that no potentially expired data
(e.g. `self.0` above) is accessed.
+The attribute can be applied to any number of lifetime and type parameters. In
+the following example, we assert that we access no data behind a reference of
+lifetime `'b` and that the only uses of `T` will be moves or drops, but omit
+the attribute from `'a` and `U`, because we do access data with that lifetime
+and that type:
+
+```rust,ignore
+use std::fmt::Display;
+
+struct Inspector<'a, 'b, T, U: Display>(&'a u8, &'b u8, T, U);
+
+unsafe impl<'a, #[may_dangle] 'b, #[may_dangle] T, U: Display> Drop for Inspector<'a, 'b, T, U> {
+ fn drop(&mut self) {
+ println!("Inspector({}, _, _, {})", self.0, self.3);
+ }
+}
+```
+
It is sometimes obvious that no such access can occur, like the case above.
However, when dealing with a generic type parameter, such access can
occur indirectly. Examples of such indirect access are:
@@ -263,7 +281,7 @@ some other method invoked by the destructor, rather than being written
directly within it.
In all of the above cases where the `&'a u8` is accessed in the
-destructor, adding the `#[unsafe_destructor_blind_to_params]`
+destructor, adding the `#[may_dangle]`
attribute makes the type vulnerable to misuse that the borrower
checker will not catch, inviting havoc. It is better to avoid adding
the attribute.
diff --git a/nomicon/exception-safety.md b/nomicon/exception-safety.md
index 74f7831..a3cbc6a 100644
--- a/nomicon/exception-safety.md
+++ b/nomicon/exception-safety.md
@@ -1,4 +1,4 @@
-% Exception Safety
+# Exception Safety
Although programs should use unwinding sparingly, there's a lot of code that
*can* panic. If you unwrap a None, index out of bounds, or divide by 0, your
@@ -93,7 +93,7 @@ uselessly. We would rather have the following:
```text
bubble_up(heap, index):
let elem = heap[index]
- while index != 0 && element < heap[parent(index)]:
+ while index != 0 && elem < heap[parent(index)]:
heap[index] = heap[parent(index)]
index = parent(index)
heap[index] = elem
@@ -137,7 +137,7 @@ If Rust had `try` and `finally` like in Java, we could do the following:
bubble_up(heap, index):
let elem = heap[index]
try:
- while index != 0 && element < heap[parent(index)]:
+ while index != 0 && elem < heap[parent(index)]:
heap[index] = heap[parent(index)]
index = parent(index)
finally:
diff --git a/nomicon/exotic-sizes.md b/nomicon/exotic-sizes.md
index 052e3c5..9f858d1 100644
--- a/nomicon/exotic-sizes.md
+++ b/nomicon/exotic-sizes.md
@@ -1,4 +1,4 @@
-% Exotically Sized Types
+# Exotically Sized Types
Most of the time, we think in terms of types with a fixed, positive size. This
is not always the case, however.
diff --git a/nomicon/hrtb.md b/nomicon/hrtb.md
index 8692832..645986a 100644
--- a/nomicon/hrtb.md
+++ b/nomicon/hrtb.md
@@ -1,4 +1,4 @@
-% Higher-Rank Trait Bounds (HRTBs)
+# Higher-Rank Trait Bounds (HRTBs)
Rust's `Fn` traits are a little bit magic. For instance, we can write the
following code:
diff --git a/nomicon/leaking.md b/nomicon/leaking.md
index a5d5742..38b70b8 100644
--- a/nomicon/leaking.md
+++ b/nomicon/leaking.md
@@ -1,4 +1,4 @@
-% Leaking
+# Leaking
Ownership-based resource management is intended to simplify composition. You
acquire resources when you create the object, and you release the resources when
diff --git a/nomicon/lifetime-elision.md b/nomicon/lifetime-elision.md
index bcd93a5..e92d735 100644
--- a/nomicon/lifetime-elision.md
+++ b/nomicon/lifetime-elision.md
@@ -1,4 +1,4 @@
-% Lifetime Elision
+# Lifetime Elision
In order to make common patterns more ergonomic, Rust allows lifetimes to be
*elided* in function signatures.
diff --git a/nomicon/lifetime-mismatch.md b/nomicon/lifetime-mismatch.md
index 0ad8a78..30b4f09 100644
--- a/nomicon/lifetime-mismatch.md
+++ b/nomicon/lifetime-mismatch.md
@@ -1,4 +1,4 @@
-% Limits of Lifetimes
+# Limits of Lifetimes
Given the following code:
diff --git a/nomicon/lifetimes.md b/nomicon/lifetimes.md
index 45eb68b..e2f0cc8 100644
--- a/nomicon/lifetimes.md
+++ b/nomicon/lifetimes.md
@@ -1,4 +1,4 @@
-% Lifetimes
+# Lifetimes
Rust enforces these rules through *lifetimes*. Lifetimes are effectively
just names for scopes somewhere in the program. Each reference,
diff --git a/nomicon/meet-safe-and-unsafe.md b/nomicon/meet-safe-and-unsafe.md
index 978d051..d42d0b6 100644
--- a/nomicon/meet-safe-and-unsafe.md
+++ b/nomicon/meet-safe-and-unsafe.md
@@ -1,4 +1,4 @@
-% Meet Safe and Unsafe
+# Meet Safe and Unsafe
Programmers in safe "high-level" languages face a fundamental dilemma. On one
hand, it would be *really* great to just say what you want and not worry about
@@ -22,7 +22,7 @@ Well, Rust *has* a safe programming language. Let's step back a bit.
Rust can be thought of as being composed of two programming languages: *Safe
Rust* and *Unsafe Rust*. Safe Rust is For Reals Totally Safe. Unsafe Rust,
unsurprisingly, is *not* For Reals Totally Safe. In fact, Unsafe Rust lets you
-do some really crazy unsafe things.
+do some really, *really* unsafe things.
Safe Rust is the *true* Rust programming language. If all you do is write Safe
Rust, you will never have to worry about type-safety or memory-safety. You will
diff --git a/nomicon/obrm.md b/nomicon/obrm.md
index 2c49524..19e5ec3 100644
--- a/nomicon/obrm.md
+++ b/nomicon/obrm.md
@@ -1,4 +1,4 @@
-% The Perils Of Ownership Based Resource Management (OBRM)
+# The Perils Of Ownership Based Resource Management (OBRM)
OBRM (AKA RAII: Resource Acquisition Is Initialization) is something you'll
interact with a lot in Rust. Especially if you use the standard library.
diff --git a/nomicon/other-reprs.md b/nomicon/other-reprs.md
index b124f3f..02f39e3 100644
--- a/nomicon/other-reprs.md
+++ b/nomicon/other-reprs.md
@@ -1,4 +1,4 @@
-% Alternative representations
+# Alternative representations
Rust allows you to specify alternative data layout strategies from the default.
diff --git a/nomicon/ownership.md b/nomicon/ownership.md
index 6be8d3b..dd9e9db 100644
--- a/nomicon/ownership.md
+++ b/nomicon/ownership.md
@@ -1,4 +1,4 @@
-% Ownership and Lifetimes
+# Ownership and Lifetimes
Ownership is the breakout feature of Rust. It allows Rust to be completely
memory-safe and efficient, while avoiding garbage collection. Before getting
@@ -52,7 +52,7 @@ let mut data = vec![1, 2, 3];
let x = &data[0];
// OH NO! `push` causes the backing storage of `data` to be reallocated.
-// Dangling pointer! User after free! Alas!
+// Dangling pointer! Use after free! Alas!
// (this does not compile in Rust)
data.push(4);
diff --git a/nomicon/phantom-data.md b/nomicon/phantom-data.md
index 0d7ec7f..32539c2 100644
--- a/nomicon/phantom-data.md
+++ b/nomicon/phantom-data.md
@@ -1,4 +1,4 @@
-% PhantomData
+# PhantomData
When working with unsafe code, we can often end up in a situation where
types or lifetimes are logically associated with a struct, but not actually
@@ -50,13 +50,13 @@ struct Vec {
}
```
-Unlike the previous example it *appears* that everything is exactly as we
-want. Every generic argument to Vec shows up in the at least one field.
+Unlike the previous example, it *appears* that everything is exactly as we
+want. Every generic argument to Vec shows up in at least one field.
Good to go!
Nope.
-The drop checker will generously determine that Vec does not own any values
+The drop checker will generously determine that `Vec` does not own any values
of type T. This will in turn make it conclude that it doesn't need to worry
about Vec dropping any T's in its destructor for determining drop check
soundness. This will in turn allow people to create unsoundness using
@@ -81,7 +81,24 @@ Raw pointers that own an allocation is such a pervasive pattern that the
standard library made a utility for itself called `Unique` which:
* wraps a `*const T` for variance
-* includes a `PhantomData`,
-* auto-derives Send/Sync as if T was contained
-* marks the pointer as NonZero for the null-pointer optimization
-
+* includes a `PhantomData`
+* auto-derives `Send`/`Sync` as if T was contained
+* marks the pointer as `NonZero` for the null-pointer optimization
+
+## Table of `PhantomData` patterns
+
+Here’s a table of all the wonderful ways `PhantomData` could be used:
+
+| Phantom type | `'a` | `T` |
+|-----------------------------|-----------|---------------------------|
+| `PhantomData` | - | variant (with drop check) |
+| `PhantomData<&'a T>` | variant | variant |
+| `PhantomData<&'a mut T>` | variant | invariant |
+| `PhantomData<*const T>` | - | variant |
+| `PhantomData<*mut T>` | - | invariant |
+| `PhantomData` | - | contravariant (*) |
+| `PhantomData T>` | - | variant |
+| `PhantomData T>` | - | invariant |
+| `PhantomData>` | invariant | - |
+
+(*) If contravariance gets scrapped, this would be invariant.
diff --git a/nomicon/poisoning.md b/nomicon/poisoning.md
index 70de91a..9b5dec3 100644
--- a/nomicon/poisoning.md
+++ b/nomicon/poisoning.md
@@ -1,4 +1,4 @@
-% Poisoning
+# Poisoning
Although all unsafe code *must* ensure it has minimal exception safety, not all
types ensure *maximal* exception safety. Even if the type does, your code may
diff --git a/nomicon/races.md b/nomicon/races.md
index f0732cf..c9b8c3d 100644
--- a/nomicon/races.md
+++ b/nomicon/races.md
@@ -1,4 +1,4 @@
-% Data Races and Race Conditions
+# Data Races and Race Conditions
Safe Rust guarantees an absence of data races, which are defined as:
@@ -21,11 +21,11 @@ prevent *all* race conditions would be pretty awful to use, if not just
incorrect.
So it's perfectly "fine" for a Safe Rust program to get deadlocked or do
-something incredibly stupid with incorrect synchronization. Obviously such a
-program isn't very good, but Rust can only hold your hand so far. Still, a
-race condition can't violate memory safety in a Rust program on
-its own. Only in conjunction with some other unsafe code can a race condition
-actually violate memory safety. For instance:
+something nonsensical with incorrect synchronization. Obviously such a program
+isn't very good, but Rust can only hold your hand so far. Still, a race
+condition can't violate memory safety in a Rust program on its own. Only in
+conjunction with some other unsafe code can a race condition actually violate
+memory safety. For instance:
```rust,no_run
use std::thread;
diff --git a/nomicon/references.md b/nomicon/references.md
index 3d7369e..5d80f1e 100644
--- a/nomicon/references.md
+++ b/nomicon/references.md
@@ -1,4 +1,4 @@
-% References
+# References
This section gives a high-level view of the memory model that *all* Rust
programs must satisfy to be correct. Safe code is statically verified
diff --git a/nomicon/repr-rust.md b/nomicon/repr-rust.md
index effeaf8..c02cf44 100644
--- a/nomicon/repr-rust.md
+++ b/nomicon/repr-rust.md
@@ -1,4 +1,4 @@
-% repr(Rust)
+# repr(Rust)
First and foremost, all types have an alignment specified in bytes. The
alignment of a type specifies what addresses are valid to store the value at. A
diff --git a/nomicon/safe-unsafe-meaning.md b/nomicon/safe-unsafe-meaning.md
index 5fd61eb..0a655a3 100644
--- a/nomicon/safe-unsafe-meaning.md
+++ b/nomicon/safe-unsafe-meaning.md
@@ -1,150 +1,123 @@
-% How Safe and Unsafe Interact
-
-So what's the relationship between Safe and Unsafe Rust? How do they interact?
-
-Rust models the separation between Safe and Unsafe Rust with the `unsafe`
-keyword, which can be thought as a sort of *foreign function interface* (FFI)
-between Safe and Unsafe Rust. This is the magic behind why we can say Safe Rust
-is a safe language: all the scary unsafe bits are relegated exclusively to FFI
-*just like every other safe language*.
-
-However because one language is a subset of the other, the two can be cleanly
-intermixed as long as the boundary between Safe and Unsafe Rust is denoted with
-the `unsafe` keyword. No need to write headers, initialize runtimes, or any of
-that other FFI boiler-plate.
-
-There are several places `unsafe` can appear in Rust today, which can largely be
-grouped into two categories:
-
-* There are unchecked contracts here. To declare you understand this, I require
-you to write `unsafe` elsewhere:
- * On functions, `unsafe` is declaring the function to be unsafe to call.
- Users of the function must check the documentation to determine what this
- means, and then have to write `unsafe` somewhere to identify that they're
- aware of the danger.
- * On trait declarations, `unsafe` is declaring that *implementing* the trait
- is an unsafe operation, as it has contracts that other unsafe code is free
- to trust blindly. (More on this below.)
-
-* I am declaring that I have, to the best of my knowledge, adhered to the
-unchecked contracts:
- * On trait implementations, `unsafe` is declaring that the contract of the
- `unsafe` trait has been upheld.
- * On blocks, `unsafe` is declaring any unsafety from an unsafe
- operation within to be handled, and therefore the parent function is safe.
-
-There is also `#[unsafe_no_drop_flag]`, which is a special case that exists for
-historical reasons and is in the process of being phased out. See the section on
-[drop flags] for details.
-
-Some examples of unsafe functions:
-
-* `slice::get_unchecked` will perform unchecked indexing, allowing memory
- safety to be freely violated.
-* every raw pointer to sized type has intrinsic `offset` method that invokes
- Undefined Behavior if it is not "in bounds" as defined by LLVM.
-* `mem::transmute` reinterprets some value as having the given type,
- bypassing type safety in arbitrary ways. (see [conversions] for details)
-* All FFI functions are `unsafe` because they can do arbitrary things.
- C being an obvious culprit, but generally any language can do something
- that Rust isn't happy about.
+# How Safe and Unsafe Interact
+
+What's the relationship between Safe Rust and Unsafe Rust? How do they
+interact?
+
+The separation between Safe Rust and Unsafe Rust is controlled with the
+`unsafe` keyword, which acts as an interface from one to the other. This is
+why we can say Safe Rust is a safe language: all the unsafe parts are kept
+exclusively behind the boundary.
+
+The `unsafe` keyword has two uses: to declare the existence of contracts the
+compiler can't check, and to declare that the adherence of some code to
+those contracts has been checked by the programmer.
+
+You can use `unsafe` to indicate the existence of unchecked contracts on
+_functions_ and on _trait declarations_. On functions, `unsafe` means that
+users of the function must check that function's documentation to ensure
+they are using it in a way that maintains the contracts the function
+requires. On trait declarations, `unsafe` means that implementors of the
+trait must check the trait documentation to ensure their implementation
+maintains the contracts the trait requires.
+
+You can use `unsafe` on a block to declare that all constraints required
+by an unsafe function within the block have been adhered to, and the code
+can therefore be trusted. You can use `unsafe` on a trait implementation
+to declare that the implementation of that trait has adhered to whatever
+contracts the trait's documentation requires.
+
+The standard library has a number of unsafe functions, including:
+
+* `slice::get_unchecked`, which performs unchecked indexing, allowing
+ memory safety to be freely violated.
+* `mem::transmute` reinterprets some value as having a given type, bypassing
+ type safety in arbitrary ways (see [conversions] for details).
+* Every raw pointer to a sized type has an intrinstic `offset` method that
+ invokes Undefined Behavior if the passed offset is not "in bounds" as
+ defined by LLVM.
+* All FFI functions are `unsafe` because the other language can do arbitrary
+ operations that the Rust compiler can't check.
As of Rust 1.0 there are exactly two unsafe traits:
-* `Send` is a marker trait (it has no actual API) that promises implementors
- are safe to send (move) to another thread.
-* `Sync` is a marker trait that promises that threads can safely share
- implementors through a shared reference.
-
-The need for unsafe traits boils down to the fundamental property of safe code:
-
-**No matter how completely awful Safe code is, it can't cause Undefined
-Behavior.**
-
-This means that Unsafe Rust, **the royal vanguard of Undefined Behavior**, has to be
-*super paranoid* about generic safe code. To be clear, Unsafe Rust is totally free to trust
-specific safe code. Anything else would degenerate into infinite spirals of
-paranoid despair. In particular it's generally regarded as ok to trust the standard library
-to be correct. `std` is effectively an extension of the language, and you
-really just have to trust the language. If `std` fails to uphold the
-guarantees it declares, then it's basically a language bug.
-
-That said, it would be best to minimize *needlessly* relying on properties of
-concrete safe code. Bugs happen! Of course, I must reinforce that this is only
-a concern for Unsafe code. Safe code can blindly trust anyone and everyone
-as far as basic memory-safety is concerned.
-
-On the other hand, safe traits are free to declare arbitrary contracts, but because
-implementing them is safe, unsafe code can't trust those contracts to actually
-be upheld. This is different from the concrete case because *anyone* can
-randomly implement the interface. There is something fundamentally different
-about trusting a particular piece of code to be correct, and trusting *all the
-code that will ever be written* to be correct.
-
-For instance Rust has `PartialOrd` and `Ord` traits to try to differentiate
-between types which can "just" be compared, and those that actually implement a
-total ordering. Pretty much every API that wants to work with data that can be
-compared wants Ord data. For instance, a sorted map like BTreeMap
-*doesn't even make sense* for partially ordered types. If you claim to implement
-Ord for a type, but don't actually provide a proper total ordering, BTreeMap will
-get *really confused* and start making a total mess of itself. Data that is
-inserted may be impossible to find!
-
-But that's okay. BTreeMap is safe, so it guarantees that even if you give it a
-completely garbage Ord implementation, it will still do something *safe*. You
-won't start reading uninitialized or unallocated memory. In fact, BTreeMap
-manages to not actually lose any of your data. When the map is dropped, all the
-destructors will be successfully called! Hooray!
-
-However BTreeMap is implemented using a modest spoonful of Unsafe Rust (most collections
-are). That means that it's not necessarily *trivially true* that a bad Ord
-implementation will make BTreeMap behave safely. BTreeMap must be sure not to rely
-on Ord *where safety is at stake*. Ord is provided by safe code, and safety is not
-safe code's responsibility to uphold.
-
-But wouldn't it be grand if there was some way for Unsafe to trust some trait
-contracts *somewhere*? This is the problem that unsafe traits tackle: by marking
-*the trait itself* as unsafe to implement, unsafe code can trust the implementation
-to uphold the trait's contract. Although the trait implementation may be
-incorrect in arbitrary other ways.
-
-For instance, given a hypothetical UnsafeOrd trait, this is technically a valid
-implementation:
+* `Send` is a marker trait (a trait with no API) that promises implementors are
+ safe to send (move) to another thread.
+* `Sync` is a marker trait that promises threads can safely share implementors
+ through a shared reference.
+
+Much of the Rust standard library also uses Unsafe Rust internally, although
+these implementations are rigorously manually checked, and the Safe Rust
+interfaces provided on top of these implementations can be assumed to be safe.
+
+The need for all of this separation boils down a single fundamental property
+of Safe Rust:
+
+**No matter what, Safe Rust can't cause Undefined Behavior.**
+
+The design of the safe/unsafe split means that Safe Rust inherently has to
+trust that any Unsafe Rust it touches has been written correctly (meaning
+the Unsafe Rust actually maintains whatever contracts it is supposed to
+maintain). On the other hand, Unsafe Rust has to be very careful about
+trusting Safe Rust.
+
+As an example, Rust has the `PartialOrd` and `Ord` traits to differentiate
+between types which can "just" be compared, and those that provide a total
+ordering (where every value of the type is either equal to, greater than,
+or less than any other value of the same type). The sorted map type
+`BTreeMap` doesn't make sense for partially-ordered types, and so it
+requires that any key type for it implements the `Ord` trait. However,
+`BTreeMap` has Unsafe Rust code inside of its implementation, and this
+Unsafe Rust code cannot assume that any `Ord` implementation it gets makes
+sense. The unsafe portions of `BTreeMap`'s internals have to be careful to
+maintain all necessary contracts, even if a key type's `Ord` implementation
+does not implement a total ordering.
+
+Unsafe Rust cannot automatically trust Safe Rust. When writing Unsafe Rust,
+you must be careful to only rely on specific Safe Rust code, and not make
+assumptions about potential future Safe Rust code providing the same
+guarantees.
+
+This is the problem that `unsafe` traits exist to resolve. The `BTreeMap`
+type could theoretically require that keys implement a new trait called
+`UnsafeOrd`, rather than `Ord`, that might look like this:
```rust
-# use std::cmp::Ordering;
-# struct MyType;
-# unsafe trait UnsafeOrd { fn cmp(&self, other: &Self) -> Ordering; }
-unsafe impl UnsafeOrd for MyType {
- fn cmp(&self, other: &Self) -> Ordering {
- Ordering::Equal
- }
+use std::cmp::Ordering;
+
+unsafe trait UnsafeOrd {
+ fn cmp(&self, other: &Self) -> Ordering;
}
```
-But it's probably not the implementation you want.
-
-Rust has traditionally avoided making traits unsafe because it makes Unsafe
-pervasive, which is not desirable. The reason Send and Sync are unsafe is because thread
-safety is a *fundamental property* that unsafe code cannot possibly hope to defend
-against in the same way it would defend against a bad Ord implementation. The
-only way to possibly defend against thread-unsafety would be to *not use
-threading at all*. Making every load and store atomic isn't even sufficient,
-because it's possible for complex invariants to exist between disjoint locations
-in memory. For instance, the pointer and capacity of a Vec must be in sync.
-
-Even concurrent paradigms that are traditionally regarded as Totally Safe like
-message passing implicitly rely on some notion of thread safety -- are you
-really message-passing if you pass a pointer? Send and Sync therefore require
-some fundamental level of trust that Safe code can't provide, so they must be
-unsafe to implement. To help obviate the pervasive unsafety that this would
-introduce, Send (resp. Sync) is automatically derived for all types composed only
-of Send (resp. Sync) values. 99% of types are Send and Sync, and 99% of those
-never actually say it (the remaining 1% is overwhelmingly synchronization
-primitives).
-
-
-
+Then, a type would use `unsafe` to implement `UnsafeOrd`, indicating that
+they've ensured their implementation maintains whatever contracts the
+trait expects. In this situation, the Unsafe Rust in the internals of
+`BTreeMap` could trust that the key type's `UnsafeOrd` implementation is
+correct. If it isn't, it's the fault of the unsafe trait implementation
+code, which is consistent with Rust's safety guarantees.
+
+The decision of whether to mark a trait `unsafe` is an API design choice.
+Rust has traditionally avoided marking traits unsafe because it makes Unsafe
+Rust pervasive, which is not desirable. `Send` and `Sync` are marked unsafe
+because thread safety is a *fundamental property* that unsafe code can't
+possibly hope to defend against in the way it could defend against a bad
+`Ord` implementation. The decision of whether to mark your own traits `unsafe`
+depends on the same sort of consideration. If `unsafe` code cannot reasonably
+expect to defend against a bad implementation of the trait, then marking the
+trait `unsafe` is a reasonable choice.
+
+As an aside, while `Send` and `Sync` are `unsafe` traits, they are
+automatically implemented for types when such derivations are provably safe
+to do. `Send` is automatically derived for all types composed only of values
+whose types also implement `Send`. `Sync` is automatically derived for all
+types composed only of values whose types also implement `Sync`.
+
+This is the dance of Safe Rust and Unsafe Rust. It is designed to make using
+Safe Rust as ergonomic as possible, but requires extra effort and care when
+writing Unsafe Rust. The rest of the book is largely a discussion of the sort
+of care that must be taken, and what contracts it is expected of Unsafe Rust
+to uphold.
[drop flags]: drop-flags.html
[conversions]: conversions.html
+
diff --git a/nomicon/send-and-sync.md b/nomicon/send-and-sync.md
index 134e47f..959f870 100644
--- a/nomicon/send-and-sync.md
+++ b/nomicon/send-and-sync.md
@@ -1,4 +1,4 @@
-% Send and Sync
+# Send and Sync
Not everything obeys inherited mutability, though. Some types allow you to
multiply alias a location in memory while mutating it. Unless these types use
diff --git a/nomicon/subtyping.md b/nomicon/subtyping.md
index eb940e8..d771712 100644
--- a/nomicon/subtyping.md
+++ b/nomicon/subtyping.md
@@ -1,4 +1,4 @@
-% Subtyping and Variance
+# Subtyping and Variance
Although Rust doesn't have any notion of structural inheritance, it *does*
include subtyping. In Rust, subtyping derives entirely from lifetimes. Since
diff --git a/nomicon/transmutes.md b/nomicon/transmutes.md
index f1478b7..043c8fe 100644
--- a/nomicon/transmutes.md
+++ b/nomicon/transmutes.md
@@ -1,4 +1,4 @@
-% Transmutes
+# Transmutes
Get out of our way type system! We're going to reinterpret these bits or die
trying! Even though this book is all about doing things that are unsafe, I
diff --git a/nomicon/unbounded-lifetimes.md b/nomicon/unbounded-lifetimes.md
index 1f2961b..b41cf8b 100644
--- a/nomicon/unbounded-lifetimes.md
+++ b/nomicon/unbounded-lifetimes.md
@@ -1,4 +1,4 @@
-% Unbounded Lifetimes
+# Unbounded Lifetimes
Unsafe code can often end up producing references or lifetimes out of thin air.
Such lifetimes come into the world as *unbounded*. The most common source of this
@@ -11,7 +11,7 @@ lifetime can be regarded as `'static`.
Almost no reference is `'static`, so this is probably wrong. `transmute` and
`transmute_copy` are the two other primary offenders. One should endeavor to
-bound an unbounded lifetime as quick as possible, especially across function
+bound an unbounded lifetime as quickly as possible, especially across function
boundaries.
Given a function, any output lifetimes that don't derive from inputs are
diff --git a/nomicon/unchecked-uninit.md b/nomicon/unchecked-uninit.md
index c72ed8a..ef31a35 100644
--- a/nomicon/unchecked-uninit.md
+++ b/nomicon/unchecked-uninit.md
@@ -1,4 +1,4 @@
-% Unchecked Uninitialized Memory
+# Unchecked Uninitialized Memory
One interesting exception to this rule is working with arrays. Safe Rust doesn't
permit you to partially initialize an array. When you initialize an array, you
diff --git a/nomicon/uninitialized.md b/nomicon/uninitialized.md
index 05615d8..eafc679 100644
--- a/nomicon/uninitialized.md
+++ b/nomicon/uninitialized.md
@@ -1,4 +1,4 @@
-% Working With Uninitialized Memory
+# Working With Uninitialized Memory
All runtime-allocated memory in a Rust program begins its life as
*uninitialized*. In this state the value of the memory is an indeterminate pile
diff --git a/nomicon/unwinding.md b/nomicon/unwinding.md
index e81f06b..6dc396d 100644
--- a/nomicon/unwinding.md
+++ b/nomicon/unwinding.md
@@ -1,4 +1,4 @@
-% Unwinding
+# Unwinding
Rust has a *tiered* error-handling scheme:
diff --git a/nomicon/vec-alloc.md b/nomicon/vec-alloc.md
index bc60a57..ef4c527 100644
--- a/nomicon/vec-alloc.md
+++ b/nomicon/vec-alloc.md
@@ -1,4 +1,4 @@
-% Allocating Memory
+# Allocating Memory
Using Unique throws a wrench in an important feature of Vec (and indeed all of
the std collections): an empty Vec doesn't actually allocate at all. So if we
diff --git a/nomicon/vec-dealloc.md b/nomicon/vec-dealloc.md
index 706fe68..83ab5b2 100644
--- a/nomicon/vec-dealloc.md
+++ b/nomicon/vec-dealloc.md
@@ -1,4 +1,4 @@
-% Deallocating
+# Deallocating
Next we should implement Drop so that we don't massively leak tons of resources.
The easiest way is to just call `pop` until it yields None, and then deallocate
diff --git a/nomicon/vec-deref.md b/nomicon/vec-deref.md
index 6460eab..e21542c 100644
--- a/nomicon/vec-deref.md
+++ b/nomicon/vec-deref.md
@@ -1,4 +1,4 @@
-% Deref
+# Deref
Alright! We've got a decent minimal stack implemented. We can push, we can
pop, and we can clean up after ourselves. However there's a whole mess of
diff --git a/nomicon/vec-drain.md b/nomicon/vec-drain.md
index 6e732ee..5bd2bf0 100644
--- a/nomicon/vec-drain.md
+++ b/nomicon/vec-drain.md
@@ -1,4 +1,4 @@
-% Drain
+# Drain
Let's move on to Drain. Drain is largely the same as IntoIter, except that
instead of consuming the Vec, it borrows the Vec and leaves its allocation
diff --git a/nomicon/vec-final.md b/nomicon/vec-final.md
index 1f4377a..39746ca 100644
--- a/nomicon/vec-final.md
+++ b/nomicon/vec-final.md
@@ -1,4 +1,4 @@
-% The Final Code
+# The Final Code
```rust
#![feature(unique)]
diff --git a/nomicon/vec-insert-remove.md b/nomicon/vec-insert-remove.md
index bcecd78..2c14bc4 100644
--- a/nomicon/vec-insert-remove.md
+++ b/nomicon/vec-insert-remove.md
@@ -1,4 +1,4 @@
-% Insert and Remove
+# Insert and Remove
Something *not* provided by slice is `insert` and `remove`, so let's do those
next.
diff --git a/nomicon/vec-into-iter.md b/nomicon/vec-into-iter.md
index ebb0a79..f2f5995 100644
--- a/nomicon/vec-into-iter.md
+++ b/nomicon/vec-into-iter.md
@@ -1,4 +1,4 @@
-% IntoIter
+# IntoIter
Let's move on to writing iterators. `iter` and `iter_mut` have already been
written for us thanks to The Magic of Deref. However there's two interesting
diff --git a/nomicon/vec-layout.md b/nomicon/vec-layout.md
index 7ca369d..1dc09ae 100644
--- a/nomicon/vec-layout.md
+++ b/nomicon/vec-layout.md
@@ -1,4 +1,4 @@
-% Layout
+# Layout
First off, we need to come up with the struct layout. A Vec has three parts:
a pointer to the allocation, the size of the allocation, and the number of
diff --git a/nomicon/vec-push-pop.md b/nomicon/vec-push-pop.md
index 5e747a8..d31a74c 100644
--- a/nomicon/vec-push-pop.md
+++ b/nomicon/vec-push-pop.md
@@ -1,4 +1,4 @@
-% Push and Pop
+# Push and Pop
Alright. We can initialize. We can allocate. Let's actually implement some
functionality! Let's start with `push`. All it needs to do is check if we're
diff --git a/nomicon/vec-raw.md b/nomicon/vec-raw.md
index 8f78462..20fa8ab 100644
--- a/nomicon/vec-raw.md
+++ b/nomicon/vec-raw.md
@@ -1,4 +1,4 @@
-% RawVec
+# RawVec
We've actually reached an interesting situation here: we've duplicated the logic
for specifying a buffer and freeing its memory in Vec and IntoIter. Now that
diff --git a/nomicon/vec-zsts.md b/nomicon/vec-zsts.md
index 5f3b2a8..5ae9bdd 100644
--- a/nomicon/vec-zsts.md
+++ b/nomicon/vec-zsts.md
@@ -1,4 +1,4 @@
-% Handling Zero-Sized Types
+# Handling Zero-Sized Types
It's time. We're going to fight the specter that is zero-sized types. Safe Rust
*never* needs to care about this, but Vec is very intensive on raw pointers and
diff --git a/nomicon/vec.md b/nomicon/vec.md
index 6913019..ad98e45 100644
--- a/nomicon/vec.md
+++ b/nomicon/vec.md
@@ -1,4 +1,4 @@
-% Example: Implementing Vec
+# Example: Implementing Vec
To bring everything together, we're going to write `std::Vec` from scratch.
Because all the best tools for writing unsafe code are unstable, this
diff --git a/nomicon/working-with-unsafe.md b/nomicon/working-with-unsafe.md
index b20dff7..5724f3d 100644
--- a/nomicon/working-with-unsafe.md
+++ b/nomicon/working-with-unsafe.md
@@ -1,4 +1,4 @@
-% Working with Unsafe
+# Working with Unsafe
Rust generally only gives us the tools to talk about Unsafe Rust in a scoped and
binary manner. Unfortunately, reality is significantly more complicated than
diff --git a/src/convert_book/markdown.rs b/src/convert_book/markdown.rs
index d17b588..d827a6f 100644
--- a/src/convert_book/markdown.rs
+++ b/src/convert_book/markdown.rs
@@ -24,8 +24,8 @@ struct Chapter {
fn get_chapters(toc: &str) -> Vec {
let toc_pattern = Regex::new(r"(?x)
- (?P\s*?)
- \*\s
+ (?P\s-?)
+ \s
\[
(?P.+?)
\]
@@ -76,10 +76,10 @@ pub fn to_single_file(src_path: &Path, meta: &str) -> Result>
{
// Readme ~ "Getting Started"
- let file = try!(file::get_file_content(&src_path.join("README.md")));
- let mut content = try!(adjust_header_level::adjust_header_level(&file, 1));
+ let file = try!(file::get_file_content(&src_path.join("ch01-00-introduction.md")));
+ let mut content = try!(adjust_header_level::adjust_header_level(&file, 0));
content = try!(remove_file_title::remove_file_title(&content));
- content = try!(adjust_reference_names::adjust_reference_name(&content, "readme"));
+ content = try!(adjust_reference_names::adjust_reference_name(&content, "ch01-00-introduction"));
content = try!(normalize::normalize(&content));
put!(".");
@@ -93,7 +93,7 @@ pub fn to_single_file(src_path: &Path, meta: &str) -> Result>
for chapter in &get_chapters(&toc) {
let file = try!(file::get_file_content(&src_path.join(&chapter.file)));
- let mut content = try!(adjust_header_level::adjust_header_level(&file, 3));
+ let mut content = try!(adjust_header_level::adjust_header_level(&file, 0));
content = try!(remove_file_title::remove_file_title(&content));
content = try!(adjust_reference_names::adjust_reference_name(&content, &chapter.file));
content = try!(normalize::normalize(&content));
diff --git a/src/convert_book/options.rs b/src/convert_book/options.rs
index f04e857..212642d 100644
--- a/src/convert_book/options.rs
+++ b/src/convert_book/options.rs
@@ -1,4 +1,4 @@
-pub const RELEASE_DATE: &'static str = "2016-10-01";
+pub const RELEASE_DATE: &'static str = "2017-06-12";
pub const MARKDOWN: &'static str = "markdown+grid_tables+pipe_tables-simple_tables+raw_html+implicit_figures+footnotes+intraword_underscores+auto_identifiers-inline_code_attributes";
@@ -6,4 +6,4 @@ pub const HTML: &'static str = "--smart --normalize --standalone --self-containe
pub const EPUB: &'static str = "--smart --normalize --standalone --self-contained --highlight-style=tango --epub-stylesheet=lib/epub.css --table-of-contents";
-pub const LATEX: &'static str = "--smart --normalize --standalone --self-contained --highlight-style=tango --chapters --table-of-contents --template=lib/template.tex --latex-engine=xelatex --to=latex";
+pub const LATEX: &'static str = "--smart --normalize --standalone --self-contained --highlight-style=tango --top-level-division=chapter --table-of-contents --template=lib/template.tex --latex-engine=xelatex --to=latex";
diff --git a/src/convert_book/pandoc.rs b/src/convert_book/pandoc.rs
index 8093efc..a7b5a64 100644
--- a/src/convert_book/pandoc.rs
+++ b/src/convert_book/pandoc.rs
@@ -17,7 +17,7 @@ pub fn save_as(book: &str, prefix: &str, format: &str, opts: &str) -> Result<(),
release_date = options::RELEASE_DATE,
format = format);
- try!(run(&opts, &book));
+ run(&opts, &book).expect("pandoc not found, please install pandoc");
println!("[✓] {}", format.to_ascii_uppercase());
diff --git a/src/main.rs b/src/main.rs
index efb8993..4447847 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -26,7 +26,7 @@ Usage:
compile-trpl [--prefix=] [--source=] [--meta=]
Options:
- --prefix= Prefix/short name of your book, e.g. "trpl" or "nomicon".
+ --prefix= Prefix/short name of your book, e.g. "trpl-1st-edition" or "nomicon".
--source= Directory containing the git book files, especially SUMMARY.md and README.md.
--meta= Meta data of your book, needs to contain `date: {release_date}`.
"#;
@@ -43,8 +43,8 @@ fn main() {
.and_then(|d| d.decode())
.unwrap_or_else(|e| e.exit());
- let prefix = args.flag_prefix.unwrap_or("trpl".to_owned());
- let source = args.flag_source.unwrap_or("trpl".to_owned());
+ let prefix = args.flag_prefix.unwrap_or("trpl-1st-edition".to_owned());
+ let source = args.flag_source.unwrap_or("trpl-1st-ed".to_owned());
let meta = args.flag_meta.unwrap_or("trpl_meta.yml".to_owned());
convert_book::render_book(&prefix, &Path::new(&source), &meta).unwrap();
diff --git a/trpl/README.md b/trpl-1st-edition/README.md
similarity index 89%
rename from trpl/README.md
rename to trpl-1st-edition/README.md
index 9f9b6a9..72842d4 100644
--- a/trpl/README.md
+++ b/trpl-1st-edition/README.md
@@ -1,4 +1,4 @@
-% The Rust Programming Language
+# The Rust Programming Language
Welcome! This book will teach you about the [Rust Programming Language][rust].
Rust is a systems programming language focused on three goals: safety, speed,
@@ -21,7 +21,6 @@ is the first. After this:
* [Tutorial: Guessing Game][gg] - Learn some Rust with a small project.
* [Syntax and Semantics][ss] - Each bit of Rust, broken down into small chunks.
* [Effective Rust][er] - Higher-level concepts for writing excellent Rust code.
-* [Nightly Rust][nr] - Cutting-edge features that aren’t in stable builds yet.
* [Glossary][gl] - A reference of terms used in the book.
* [Bibliography][bi] - Background on Rust's influences, papers about Rust.
@@ -29,7 +28,6 @@ is the first. After this:
[gg]: guessing-game.html
[er]: effective-rust.html
[ss]: syntax-and-semantics.html
-[nr]: nightly-rust.html
[gl]: glossary.html
[bi]: bibliography.html
@@ -38,4 +36,4 @@ is the first. After this:
The source files from which this book is generated can be found on
[GitHub][book].
-[book]: https://github.com/rust-lang/rust/tree/master/src/doc/book
+[book]: https://github.com/rust-lang/book/tree/master/first-edition/src
diff --git a/trpl/SUMMARY.md b/trpl-1st-edition/SUMMARY.md
similarity index 80%
rename from trpl/SUMMARY.md
rename to trpl-1st-edition/SUMMARY.md
index 18aa9f2..c3763cd 100644
--- a/trpl/SUMMARY.md
+++ b/trpl-1st-edition/SUMMARY.md
@@ -1,5 +1,7 @@
# Summary
+[Introduction](README.md)
+
* [Getting Started](getting-started.md)
* [Tutorial: Guessing Game](guessing-game.md)
* [Syntax and Semantics](syntax-and-semantics.md)
@@ -52,18 +54,7 @@
* [Borrow and AsRef](borrow-and-asref.md)
* [Release Channels](release-channels.md)
* [Using Rust without the standard library](using-rust-without-the-standard-library.md)
-* [Nightly Rust](nightly-rust.md)
- * [Compiler Plugins](compiler-plugins.md)
- * [Inline Assembly](inline-assembly.md)
- * [No stdlib](no-stdlib.md)
- * [Intrinsics](intrinsics.md)
- * [Lang items](lang-items.md)
- * [Advanced linking](advanced-linking.md)
- * [Benchmark Tests](benchmark-tests.md)
- * [Box Syntax and Patterns](box-syntax-and-patterns.md)
- * [Slice Patterns](slice-patterns.md)
- * [Associated Constants](associated-constants.md)
- * [Custom Allocators](custom-allocators.md)
+ * [Procedural Macros (and custom derive)](procedural-macros.md)
* [Glossary](glossary.md)
* [Syntax Index](syntax-index.md)
* [Bibliography](bibliography.md)
diff --git a/trpl/associated-types.md b/trpl-1st-edition/associated-types.md
similarity index 97%
rename from trpl/associated-types.md
rename to trpl-1st-edition/associated-types.md
index cb54ac2..4db2b9e 100644
--- a/trpl/associated-types.md
+++ b/trpl-1st-edition/associated-types.md
@@ -1,4 +1,4 @@
-% Associated Types
+# Associated Types
Associated types are a powerful part of Rust’s type system. They’re related to
the idea of a ‘type family’, in other words, grouping multiple types together. That
@@ -11,7 +11,7 @@ this:
trait Graph {
fn has_edge(&self, &N, &N) -> bool;
fn edges(&self, &N) -> Vec;
- // etc
+ // Etc.
}
```
@@ -36,7 +36,7 @@ trait Graph {
fn has_edge(&self, &Self::N, &Self::N) -> bool;
fn edges(&self, &Self::N) -> Vec;
- // etc
+ // Etc.
}
```
@@ -67,7 +67,7 @@ trait Graph {
Simple enough. Associated types use the `type` keyword, and go inside the body
of the trait, with the functions.
-These `type` declarations can have all the same thing as functions do. For example,
+These type declarations work the same way as those for functions. For example,
if we wanted our `N` type to implement `Display`, so we can print the nodes out,
we could do this:
diff --git a/trpl/attributes.md b/trpl-1st-edition/attributes.md
similarity index 95%
rename from trpl/attributes.md
rename to trpl-1st-edition/attributes.md
index 6349647..49ac9b2 100644
--- a/trpl/attributes.md
+++ b/trpl-1st-edition/attributes.md
@@ -1,4 +1,4 @@
-% Attributes
+# Attributes
Declarations can be annotated with ‘attributes’ in Rust. They look like this:
@@ -67,4 +67,4 @@ Rust attributes are used for a number of different things. There is a full list
of attributes [in the reference][reference]. Currently, you are not allowed to
create your own attributes, the Rust compiler defines them.
-[reference]: ../reference.html#attributes
+[reference]: ../../reference/attributes.html
diff --git a/trpl/bibliography.md b/trpl-1st-edition/bibliography.md
similarity index 97%
rename from trpl/bibliography.md
rename to trpl-1st-edition/bibliography.md
index 6f6f51d..483c1e6 100644
--- a/trpl/bibliography.md
+++ b/trpl-1st-edition/bibliography.md
@@ -1,4 +1,4 @@
-% Bibliography
+# Bibliography
This is a reading list of material relevant to Rust. It includes prior
research that has - at one time or another - influenced the design of
@@ -81,3 +81,4 @@ Language](http://www.cs.indiana.edu/~eholk/papers/hips2013.pdf). Early GPU work
Munksgaard's master's thesis. Research for Servo.
* [Ownership is Theft: Experiences Building an Embedded OS in Rust - Amit Levy, et. al.](http://amitlevy.com/papers/tock-plos2015.pdf)
* [You can't spell trust without Rust](https://raw.githubusercontent.com/Gankro/thesis/master/thesis.pdf). Alexis Beingessner's master's thesis.
+* [Rust as a Language for High Performance GC Implementation](http://users.cecs.anu.edu.au/~steveb/downloads/pdf/rust-ismm-2016.pdf)
diff --git a/trpl/borrow-and-asref.md b/trpl-1st-edition/borrow-and-asref.md
similarity index 85%
rename from trpl/borrow-and-asref.md
rename to trpl-1st-edition/borrow-and-asref.md
index 1cfeb26..3b1ef1a 100644
--- a/trpl/borrow-and-asref.md
+++ b/trpl-1st-edition/borrow-and-asref.md
@@ -1,14 +1,14 @@
-% Borrow and AsRef
+# Borrow and AsRef
The [`Borrow`][borrow] and [`AsRef`][asref] traits are very similar, but
different. Here’s a quick refresher on what these two traits mean.
-[borrow]: ../std/borrow/trait.Borrow.html
-[asref]: ../std/convert/trait.AsRef.html
+[borrow]: ../../std/borrow/trait.Borrow.html
+[asref]: ../../std/convert/trait.AsRef.html
# Borrow
-The `Borrow` trait is used when you’re writing a datastructure, and you want to
+The `Borrow` trait is used when you’re writing a data structure, and you want to
use either an owned or borrowed type as synonymous for some purpose.
For example, [`HashMap`][hashmap] has a [`get` method][get] which uses `Borrow`:
@@ -19,8 +19,8 @@ fn get(&self, k: &Q) -> Option<&V>
Q: Hash + Eq
```
-[hashmap]: ../std/collections/struct.HashMap.html
-[get]: ../std/collections/struct.HashMap.html#method.get
+[hashmap]: ../../std/collections/struct.HashMap.html
+[get]: ../../std/collections/struct.HashMap.html#method.get
This signature is pretty complicated. The `K` parameter is what we’re interested
in here. It refers to a parameter of the `HashMap` itself:
@@ -86,7 +86,7 @@ We can see how they’re kind of the same: they both deal with owned and borrowe
versions of some type. However, they’re a bit different.
Choose `Borrow` when you want to abstract over different kinds of borrowing, or
-when you’re building a datastructure that treats owned and borrowed values in
+when you’re building a data structure that treats owned and borrowed values in
equivalent ways, such as hashing and comparison.
Choose `AsRef` when you want to convert something to a reference directly, and
diff --git a/trpl/casting-between-types.md b/trpl-1st-edition/casting-between-types.md
similarity index 85%
rename from trpl/casting-between-types.md
rename to trpl-1st-edition/casting-between-types.md
index a101f39..26cd718 100644
--- a/trpl/casting-between-types.md
+++ b/trpl-1st-edition/casting-between-types.md
@@ -1,4 +1,4 @@
-% Casting Between Types
+# Casting Between Types
Rust, with its focus on safety, provides two different ways of casting
different types between each other. The first, `as`, is for safe casts.
@@ -16,20 +16,20 @@ function result.
The most common case of coercion is removing mutability from a reference:
- * `&mut T` to `&T`
+* `&mut T` to `&T`
An analogous conversion is to remove mutability from a
-[raw pointer](raw-pointers.md):
+[raw pointer](raw-pointers.html):
- * `*mut T` to `*const T`
+* `*mut T` to `*const T`
References can also be coerced to raw pointers:
- * `&T` to `*const T`
+* `&T` to `*const T`
- * `&mut T` to `*mut T`
+* `&mut T` to `*mut T`
-Custom coercions may be defined using [`Deref`](deref-coercions.md).
+Custom coercions may be defined using [`Deref`](deref-coercions.html).
Coercion is transitive.
@@ -59,11 +59,11 @@ A cast `e as U` is valid if `e` has type `T` and `T` *coerces* to `U`.
A cast `e as U` is also valid in any of the following cases:
- * `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast*
- * `e` is a C-like enum (with no data attached to the variants),
- and `U` is an integer type; *enum-cast*
- * `e` has type `bool` or `char` and `U` is an integer type; *prim-int-cast*
- * `e` has type `u8` and `U` is `char`; *u8-char-cast*
+* `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast*
+* `e` is a C-like enum (with no data attached to the variants),
+ and `U` is an integer type; *enum-cast*
+* `e` has type `bool` or `char` and `U` is an integer type; *prim-int-cast*
+* `e` has type `u8` and `U` is `char`; *u8-char-cast*
For example
@@ -101,12 +101,12 @@ The semantics of numeric casts are:
## Pointer casts
-Perhaps surprisingly, it is safe to cast [raw pointers](raw-pointers.md) to and
+Perhaps surprisingly, it is safe to cast [raw pointers](raw-pointers.html) to and
from integers, and to cast between pointers to different types subject to
some constraints. It is only unsafe to dereference the pointer:
```rust
-let a = 300 as *const char; // a pointer to location 300
+let a = 300 as *const char; // `a` is a pointer to location 300.
let b = a as u32;
```
@@ -135,14 +135,14 @@ cast four bytes into a `u32`:
```rust,ignore
let a = [0u8, 0u8, 0u8, 0u8];
-let b = a as u32; // four u8s makes a u32
+let b = a as u32; // Four u8s makes a u32.
```
This errors with:
```text
error: non-scalar cast: `[u8; 4]` as `u32`
-let b = a as u32; // four u8s makes a u32
+let b = a as u32; // Four u8s makes a u32.
^~~~~~~~
```
@@ -151,12 +151,9 @@ elements of the array. These kinds of casts are very dangerous, because they
make assumptions about the way that multiple underlying structures are
implemented. For this, we need something more dangerous.
-The `transmute` function is provided by a [compiler intrinsic][intrinsics], and
-what it does is very simple, but very scary. It tells Rust to treat a value of
-one type as though it were another type. It does this regardless of the
-typechecking system, and completely trusts you.
-
-[intrinsics]: intrinsics.html
+The `transmute` function is very simple, but very scary. It tells Rust to treat
+a value of one type as though it were another type. It does this regardless of
+the typechecking system, and completely trusts you.
In our previous example, we know that an array of four `u8`s represents a `u32`
properly, and so we want to do the cast. Using `transmute` instead of `as`,
@@ -170,7 +167,7 @@ fn main() {
let a = [0u8, 1u8, 0u8, 0u8];
let b = mem::transmute::<[u8; 4], u32>(a);
println!("{}", b); // 256
- // or, more concisely:
+ // Or, more concisely:
let c: u32 = mem::transmute(a);
println!("{}", c); // 256
}
diff --git a/trpl-1st-edition/chapter_1.md b/trpl-1st-edition/chapter_1.md
new file mode 100644
index 0000000..b743fda
--- /dev/null
+++ b/trpl-1st-edition/chapter_1.md
@@ -0,0 +1 @@
+# Chapter 1
diff --git a/trpl/choosing-your-guarantees.md b/trpl-1st-edition/choosing-your-guarantees.md
similarity index 94%
rename from trpl/choosing-your-guarantees.md
rename to trpl-1st-edition/choosing-your-guarantees.md
index d88f619..b1ba4df 100644
--- a/trpl/choosing-your-guarantees.md
+++ b/trpl-1st-edition/choosing-your-guarantees.md
@@ -1,4 +1,4 @@
-% Choosing your Guarantees
+# Choosing your Guarantees
One important feature of Rust is that it lets us control the costs and guarantees
of a program.
@@ -25,7 +25,7 @@ the following:
```rust
let x = Box::new(1);
let y = x;
-// x no longer accessible here
+// `x` is no longer accessible here.
```
Here, the box was _moved_ into `y`. As `x` no longer owns it, the compiler will no longer allow the
@@ -38,7 +38,7 @@ This is a zero-cost abstraction for dynamic allocation. If you want to allocate
heap and safely pass around a pointer to that memory, this is ideal. Note that you will only be
allowed to share references to this by the regular borrowing rules, checked at compile time.
-[box]: ../std/boxed/struct.Box.html
+[box]: ../../std/boxed/struct.Box.html
## `&T` and `&mut T`
@@ -104,7 +104,7 @@ two `usize` values) as compared to a regular `Box` (for "strong" and "weak" r
or goes out of scope respectively. Note that a clone will not do a deep copy, rather it will simply
increment the inner reference count and return a copy of the `Rc`.
-[rc]: ../std/rc/struct.Rc.html
+[rc]: ../../std/rc/struct.Rc.html
# Cell types
@@ -118,7 +118,8 @@ These types are _generally_ found in struct fields, but they may be found elsewh
## `Cell`
-[`Cell`][cell] is a type that provides zero-cost interior mutability, but only for `Copy` types.
+[`Cell`][cell] is a type that provides zero-cost interior mutability by moving data in and
+out of the cell.
Since the compiler knows that all the data owned by the contained value is on the stack, there's
no worry of leaking any data behind references (or worse!) by simply replacing the data.
@@ -160,7 +161,7 @@ This relaxes the “no aliasing with mutability” restriction in places
unnecessary. However, this also relaxes the guarantees that the restriction provides; so if your
invariants depend on data stored within `Cell`, you should be careful.
-This is useful for mutating primitives and other `Copy` types when there is no easy way of
+This is useful for mutating primitives and other types when there is no easy way of
doing it in line with the static rules of `&` and `&mut`.
`Cell` does not let you obtain interior references to the data, which makes it safe to freely
@@ -168,16 +169,17 @@ mutate.
#### Cost
-There is no runtime cost to using `Cell`, however if you are using it to wrap larger (`Copy`)
+There is no runtime cost to using `Cell`, however if you are using it to wrap larger
structs, it might be worthwhile to instead wrap individual fields in `Cell` since each write is
otherwise a full copy of the struct.
## `RefCell`
-[`RefCell`][refcell] also provides interior mutability, but isn't restricted to `Copy` types.
+[`RefCell`][refcell] also provides interior mutability, but doesn't move data in and out of the
+cell.
-Instead, it has a runtime cost. `RefCell` enforces the read-write lock pattern at runtime (it's
+However, it has a runtime cost. `RefCell` enforces the read-write lock pattern at runtime (it's
like a single-threaded mutex), unlike `&T`/`&mut T` which do so at compile time. This is done by the
`borrow()` and `borrow_mut()` functions, which modify an internal reference count and return smart
pointers which can be dereferenced immutably and mutably respectively. The refcount is restored when
@@ -232,9 +234,9 @@ indicator (one word in size) along with the data.
At runtime each borrow causes a modification/check of the refcount.
-[cell-mod]: ../std/cell/index.html
-[cell]: ../std/cell/struct.Cell.html
-[refcell]: ../std/cell/struct.RefCell.html
+[cell-mod]: ../../std/cell/index.html
+[cell]: ../../std/cell/struct.Cell.html
+[refcell]: ../../std/cell/struct.RefCell.html
# Synchronous types
@@ -250,7 +252,7 @@ time.
There are many useful wrappers for concurrent programming in the [sync][sync] module, but only the
major ones will be covered below.
-[sync]: ../std/sync/index.html
+[sync]: ../../std/sync/index.html
## `Arc`
@@ -278,7 +280,7 @@ This has the added cost of using atomics for changing the refcount (which will h
cloned or goes out of scope). When sharing data from an `Arc` in a single thread, it is preferable
to share `&` pointers whenever possible.
-[arc]: ../std/sync/struct.Arc.html
+[arc]: ../../std/sync/struct.Arc.html
## `Mutex` and `RwLock`
@@ -291,9 +293,9 @@ the inner data (mutably), and the lock will be released when the guard goes out
```rust,ignore
{
let guard = mutex.lock();
- // guard dereferences mutably to the inner type
+ // `guard` dereferences mutably to the inner type.
*guard += 1;
-} // lock released when destructor runs
+} // Lock is released when destructor runs.
```
@@ -314,8 +316,8 @@ These use internal atomic-like types to maintain the locks, which are pretty cos
all memory reads across processors till they're done). Waiting on these locks can also be slow when
there's a lot of concurrent access happening.
-[rwlock]: ../std/sync/struct.RwLock.html
-[mutex]: ../std/sync/struct.Mutex.html
+[rwlock]: ../../std/sync/struct.RwLock.html
+[mutex]: ../../std/sync/struct.Mutex.html
[sessions]: https://github.com/Munksgaard/rust-sessions
# Composition
diff --git a/trpl/closures.md b/trpl-1st-edition/closures.md
similarity index 91%
rename from trpl/closures.md
rename to trpl-1st-edition/closures.md
index 1470eac..0fe08bf 100644
--- a/trpl/closures.md
+++ b/trpl-1st-edition/closures.md
@@ -1,4 +1,4 @@
-% Closures
+# Closures
Sometimes it is useful to wrap up a function and _free variables_ for better
clarity and reuse. The free variables that can be used come from the
@@ -116,7 +116,7 @@ let mut num = 5;
{
let plus_num = |x: i32| x + num;
-} // plus_num goes out of scope, borrow of num ends
+} // `plus_num` goes out of scope; borrow of `num` ends.
let y = &mut num;
```
@@ -222,26 +222,11 @@ operator. From this, everything else clicks into place. In Rust, we use the
trait system to overload operators. Calling functions is no different. We have
three separate traits to overload with:
-```rust
-# #![feature(unboxed_closures)]
-# mod foo {
-pub trait Fn : FnMut {
- extern "rust-call" fn call(&self, args: Args) -> Self::Output;
-}
-
-pub trait FnMut : FnOnce {
- extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
-}
-
-pub trait FnOnce {
- type Output;
-
- extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-}
-# }
-```
+* `Fn`
+* `FnMut`
+* `FnOnce`
-You’ll notice a few differences between these traits, but a big one is `self`:
+There are a few differences between these traits, but a big one is `self`:
`Fn` takes `&self`, `FnMut` takes `&mut self`, and `FnOnce` takes `self`. This
covers all three kinds of `self` via the usual method call syntax. But we’ve
split them up into three traits, rather than having a single one. This gives us
@@ -262,7 +247,7 @@ the result:
```rust
fn call_with_one(some_closure: F) -> i32
- where F : Fn(i32) -> i32 {
+ where F: Fn(i32) -> i32 {
some_closure(1)
}
@@ -279,21 +264,21 @@ Let’s examine the signature of `call_with_one` in more depth:
```rust
fn call_with_one(some_closure: F) -> i32
-# where F : Fn(i32) -> i32 {
+# where F: Fn(i32) -> i32 {
# some_closure(1) }
```
-We take one parameter, and it has the type `F`. We also return a `i32`. This part
+We take one parameter, and it has the type `F`. We also return an `i32`. This part
isn’t interesting. The next part is:
```rust
# fn call_with_one(some_closure: F) -> i32
- where F : Fn(i32) -> i32 {
+ where F: Fn(i32) -> i32 {
# some_closure(1) }
```
Because `Fn` is a trait, we can use it as a bound for our generic type. In
-this case, our closure takes a `i32` as an argument and returns an `i32`, and
+this case, our closure takes an `i32` as an argument and returns an `i32`, and
so the generic bound we use is `Fn(i32) -> i32`.
There’s one other key point here: because we’re bounding a generic with a
@@ -327,7 +312,7 @@ that takes a reference like so:
fn call_with_ref(some_closure:F) -> i32
where F: Fn(&i32) -> i32 {
- let mut value = 0;
+ let value = 0;
some_closure(&value)
}
```
@@ -340,14 +325,15 @@ fn call_with_ref<'a, F>(some_closure:F) -> i32
where F: Fn(&'a i32) -> i32 {
```
-However this presents a problem with in our case. When you specify the explicit
-lifetime on a function it binds that lifetime to the *entire* scope of the function
-instead of just the invocation scope of our closure. This means that the borrow checker
-will see a mutable reference in the same lifetime as our immutable reference and fail
-to compile.
+However, this presents a problem in our case. When a function has an explicit
+lifetime parameter, that lifetime must be at least as long as the *entire*
+call to that function. The borrow checker will complain that `value` doesn't
+live long enough, because it is only in scope after its declaration inside the
+function body.
-In order to say that we only need the lifetime to be valid for the invocation scope
-of the closure we can use Higher-Ranked Trait Bounds with the `for<...>` syntax:
+What we need is a closure that can borrow its argument only for its own
+invocation scope, not for the outer function's scope. In order to say that,
+we can use Higher-Ranked Trait Bounds with the `for<...>` syntax:
```ignore
fn call_with_ref(some_closure:F) -> i32
@@ -362,7 +348,7 @@ expect.
fn call_with_ref(some_closure:F) -> i32
where F: for<'a> Fn(&'a i32) -> i32 {
- let mut value = 0;
+ let value = 0;
some_closure(&value)
}
```
@@ -510,12 +496,11 @@ fn factory() -> Box i32> {
Box::new(|x| x + num)
}
-# fn main() {
+
let f = factory();
let answer = f(1);
assert_eq!(6, answer);
-# }
```
There’s just one last problem:
@@ -540,12 +525,11 @@ fn factory() -> Box i32> {
Box::new(move |x| x + num)
}
-fn main() {
+
let f = factory();
let answer = f(1);
assert_eq!(6, answer);
-}
```
By making the inner closure a `move Fn`, we create a new stack frame for our
diff --git a/trpl/comments.md b/trpl-1st-edition/comments.md
similarity index 97%
rename from trpl/comments.md
rename to trpl-1st-edition/comments.md
index e7eb48d..0e68ab2 100644
--- a/trpl/comments.md
+++ b/trpl-1st-edition/comments.md
@@ -1,4 +1,4 @@
-% Comments
+# Comments
Now that we have some functions, it’s a good idea to learn about comments.
Comments are notes that you leave to other programmers to help explain things
@@ -10,7 +10,7 @@ and *doc comments*.
```rust
// Line comments are anything after ‘//’ and extend to the end of the line.
-let x = 5; // this is also a line comment.
+let x = 5; // This is also a line comment.
// If you have a long explanation for something, you can put line comments next
// to each other. Put a space between the // and your comment so that it’s
diff --git a/trpl/concurrency.md b/trpl-1st-edition/concurrency.md
similarity index 95%
rename from trpl/concurrency.md
rename to trpl-1st-edition/concurrency.md
index a783650..0fd71ee 100644
--- a/trpl/concurrency.md
+++ b/trpl-1st-edition/concurrency.md
@@ -1,10 +1,10 @@
-% Concurrency
+# Concurrency
Concurrency and parallelism are incredibly important topics in computer
science, and are also a hot topic in industry today. Computers are gaining more
and more cores, yet many programmers aren't prepared to fully utilize them.
-Rust's memory safety features also apply to its concurrency story too. Even
+Rust's memory safety features also apply to its concurrency story. Even
concurrent Rust programs must be memory safe, having no data races. Rust's type
system is up to the task, and gives you powerful ways to reason about
concurrent code at compile time.
@@ -26,7 +26,7 @@ to help us make sense of code that can possibly be concurrent.
### `Send`
The first trait we're going to talk about is
-[`Send`](../std/marker/trait.Send.html). When a type `T` implements `Send`, it
+[`Send`](../../std/marker/trait.Send.html). When a type `T` implements `Send`, it
indicates that something of this type is able to have ownership transferred
safely between threads.
@@ -36,14 +36,14 @@ down the channel and to the other thread. Therefore, we'd ensure that `Send` was
implemented for that type.
In the opposite way, if we were wrapping a library with [FFI][ffi] that isn't
-threadsafe, we wouldn't want to implement `Send`, and so the compiler will help
+thread-safe, we wouldn't want to implement `Send`, and so the compiler will help
us enforce that it can't leave the current thread.
[ffi]: ffi.html
### `Sync`
-The second of these traits is called [`Sync`](../std/marker/trait.Sync.html).
+The second of these traits is called [`Sync`](../../std/marker/trait.Sync.html).
When a type `T` implements `Sync`, it indicates that something
of this type has no possibility of introducing memory unsafety when used from
multiple threads concurrently through shared references. This implies that
@@ -213,10 +213,10 @@ fn main() {
let mut data = Rc::new(vec![1, 2, 3]);
for i in 0..3 {
- // create a new owned reference
+ // Create a new owned reference:
let data_ref = data.clone();
- // use it in a thread
+ // Use it in a thread:
thread::spawn(move || {
data_ref[0] += i;
});
@@ -238,7 +238,7 @@ This won't work, however, and will give us the error:
As the error message mentions, `Rc` cannot be sent between threads safely. This
is because the internal reference count is not maintained in a thread safe
-matter and can have a data race.
+manner and can have a data race.
To solve this, we'll use `Arc`, Rust's standard atomic reference count type.
@@ -281,8 +281,8 @@ And... still gives us an error.
```
`Arc` by default has immutable contents. It allows the _sharing_ of data
-between threads, but shared mutable data is unsafe and when threads are
-involved can cause data races!
+between threads, but shared mutable data is unsafe—and when threads are
+involved—can cause data races!
Usually when we wish to make something in an immutable position mutable, we use
@@ -333,8 +333,8 @@ locked, it will wait until the other thread releases the lock.
The lock "release" here is implicit; when the result of the lock (in this case,
`data`) goes out of scope, the lock is automatically released.
-Note that [`lock`](../std/sync/struct.Mutex.html#method.lock) method of
-[`Mutex`](../std/sync/struct.Mutex.html) has this signature:
+Note that [`lock`](../../std/sync/struct.Mutex.html#method.lock) method of
+[`Mutex`](../../std/sync/struct.Mutex.html) has this signature:
```rust,ignore
fn lock(&self) -> LockResult>
@@ -390,8 +390,8 @@ use std::sync::mpsc;
fn main() {
let data = Arc::new(Mutex::new(0));
- // `tx` is the "transmitter" or "sender"
- // `rx` is the "receiver"
+ // `tx` is the "transmitter" or "sender".
+ // `rx` is the "receiver".
let (tx, rx) = mpsc::channel();
for _ in 0..10 {
diff --git a/trpl/conditional-compilation.md b/trpl-1st-edition/conditional-compilation.md
similarity index 91%
rename from trpl/conditional-compilation.md
rename to trpl-1st-edition/conditional-compilation.md
index 78ab3c1..0562e9f 100644
--- a/trpl/conditional-compilation.md
+++ b/trpl-1st-edition/conditional-compilation.md
@@ -1,4 +1,4 @@
-% Conditional Compilation
+# Conditional Compilation
Rust has a special attribute, `#[cfg]`, which allows you to compile code
based on a flag passed to the compiler. It has two forms:
@@ -79,8 +79,7 @@ Will be the same as `#[b]` if `a` is set by `cfg` attribute, and nothing otherwi
# cfg!
-The `cfg!` [syntax extension][compilerplugins] lets you use these kinds of flags
-elsewhere in your code, too:
+The `cfg!` macro lets you use these kinds of flags elsewhere in your code, too:
```rust
if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
@@ -88,7 +87,5 @@ if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
}
```
-[compilerplugins]: compiler-plugins.html
-
These will be replaced by a `true` or `false` at compile-time, depending on the
configuration settings.
diff --git a/trpl/const-and-static.md b/trpl-1st-edition/const-and-static.md
similarity index 95%
rename from trpl/const-and-static.md
rename to trpl-1st-edition/const-and-static.md
index 11aa25a..66a4856 100644
--- a/trpl/const-and-static.md
+++ b/trpl-1st-edition/const-and-static.md
@@ -1,4 +1,4 @@
-% `const` and `static`
+# const and static
Rust has a way of defining constants with the `const` keyword:
@@ -32,7 +32,7 @@ static N: i32 = 5;
Unlike [`let`][let] bindings, you must annotate the type of a `static`.
Statics live for the entire lifetime of a program, and therefore any
-reference stored in a constant has a [`'static` lifetime][lifetimes]:
+reference stored in a static has a [`'static` lifetime][lifetimes]:
```rust
static NAME: &'static str = "Steve";
diff --git a/trpl/crates-and-modules.md b/trpl-1st-edition/crates-and-modules.md
similarity index 96%
rename from trpl/crates-and-modules.md
rename to trpl-1st-edition/crates-and-modules.md
index fcb7e0b..10e66d4 100644
--- a/trpl/crates-and-modules.md
+++ b/trpl-1st-edition/crates-and-modules.md
@@ -1,4 +1,4 @@
-% Crates and Modules
+# Crates and Modules
When a project starts getting large, it’s considered good software
engineering practice to split it up into a bunch of smaller pieces, and then
@@ -126,7 +126,7 @@ Instead of declaring a module like this:
```rust,ignore
mod english {
- // contents of our module go here
+ // Contents of our module go here.
}
```
@@ -176,23 +176,28 @@ mod english;
mod japanese;
```
-These two declarations tell Rust to look for either `src/english.rs` and
-`src/japanese.rs`, or `src/english/mod.rs` and `src/japanese/mod.rs`, depending
-on our preference. In this case, because our modules have sub-modules, we’ve
-chosen the second. Both `src/english/mod.rs` and `src/japanese/mod.rs` look
-like this:
+These two declarations tell Rust to look for
+
+- either `src/english.rs` or `src/english/mod.rs`, and
+- either `src/japanese.rs` or `src/japanese/mod.rs`,
+
+depending on our preference. In this case, because our modules have sub-modules,
+we’ve chosen the `mod.rs` approach. Both `src/english/mod.rs` and
+`src/japanese/mod.rs` look like this:
```rust,ignore
mod greetings;
mod farewells;
```
-Again, these declarations tell Rust to look for either
-`src/english/greetings.rs`, `src/english/farewells.rs`,
-`src/japanese/greetings.rs` and `src/japanese/farewells.rs` or
-`src/english/greetings/mod.rs`, `src/english/farewells/mod.rs`,
-`src/japanese/greetings/mod.rs` and
-`src/japanese/farewells/mod.rs`. Because these sub-modules don’t have
+Again, these declarations tell Rust to look for
+
+- `src/english/greetings.rs` or `src/english/greetings/mod.rs`,
+- `src/english/farewells.rs` or `src/english/farewells/mod.rs`,
+- `src/japanese/greetings.rs` or `src/japanese/greetings/mod.rs`,
+- and `src/japanese/farewells.rs` or `src/japanese/farewells/mod.rs`.
+
+Because these sub-modules don’t have
their own sub-modules, we’ve chosen to make them
`src/english/greetings.rs`, `src/english/farewells.rs`,
`src/japanese/greetings.rs` and `src/japanese/farewells.rs`. Whew!
diff --git a/trpl/deref-coercions.md b/trpl-1st-edition/deref-coercions.md
similarity index 85%
rename from trpl/deref-coercions.md
rename to trpl-1st-edition/deref-coercions.md
index beb65c4..e62c50a 100644
--- a/trpl/deref-coercions.md
+++ b/trpl-1st-edition/deref-coercions.md
@@ -1,4 +1,4 @@
-% `Deref` coercions
+# `Deref` coercions
The standard library provides a special trait, [`Deref`][deref]. It’s normally
used to overload `*`, the dereference operator:
@@ -24,7 +24,7 @@ fn main() {
}
```
-[deref]: ../std/ops/trait.Deref.html
+[deref]: ../../std/ops/trait.Deref.html
This is useful for writing custom pointer types. However, there’s a language
feature related to `Deref`: ‘deref coercions’. Here’s the rule: If you have a
@@ -33,13 +33,13 @@ automatically coerce to a `&T`. Here’s an example:
```rust
fn foo(s: &str) {
- // borrow a string for a second
+ // Borrow a string for a second.
}
-// String implements Deref
+// String implements Deref.
let owned = "Hello".to_string();
-// therefore, this works:
+// Therefore, this works:
foo(&owned);
```
@@ -55,31 +55,31 @@ type implements `Deref`, so this works:
use std::rc::Rc;
fn foo(s: &str) {
- // borrow a string for a second
+ // Borrow a string for a second.
}
-// String implements Deref
+// String implements Deref.
let owned = "Hello".to_string();
let counted = Rc::new(owned);
-// therefore, this works:
+// Therefore, this works:
foo(&counted);
```
All we’ve done is wrap our `String` in an `Rc`. But we can now pass the
`Rc` around anywhere we’d have a `String`. The signature of `foo`
didn’t change, but works just as well with either type. This example has two
-conversions: `Rc` to `String` and then `String` to `&str`. Rust will do
+conversions: `&Rc` to `&String` and then `&String` to `&str`. Rust will do
this as many times as possible until the types match.
Another very common implementation provided by the standard library is:
```rust
fn foo(s: &[i32]) {
- // borrow a slice for a second
+ // Borrow a slice for a second.
}
-// Vec implements Deref
+// Vec implements Deref.
let owned = vec![1, 2, 3];
foo(&owned);
diff --git a/trpl/documentation.md b/trpl-1st-edition/documentation.md
similarity index 94%
rename from trpl/documentation.md
rename to trpl-1st-edition/documentation.md
index 6292ba9..6a2c850 100644
--- a/trpl/documentation.md
+++ b/trpl-1st-edition/documentation.md
@@ -1,4 +1,4 @@
-% Documentation
+# Documentation
Documentation is an important part of any software project, and it's
first-class in Rust. Let's talk about the tooling Rust gives you to
@@ -28,7 +28,7 @@ code. You can use documentation comments for this purpose:
/// let five = Rc::new(5);
/// ```
pub fn new(value: T) -> Rc {
- // implementation goes here
+ // Implementation goes here.
}
```
@@ -76,7 +76,7 @@ This [unfortunate error](https://github.com/rust-lang/rust/issues/22547) is
correct; documentation comments apply to the thing after them, and there's
nothing after that last comment.
-[rc-new]: ../std/rc/struct.Rc.html#method.new
+[rc-new]: ../../std/rc/struct.Rc.html#method.new
### Writing documentation comments
@@ -170,8 +170,6 @@ more than one section:
# fn foo() {}
```
-Let's discuss the details of these code blocks.
-
#### Code block annotations
To write some Rust code in a comment, use the triple graves:
@@ -183,23 +181,8 @@ To write some Rust code in a comment, use the triple graves:
# fn foo() {}
```
-If you want something that's not Rust code, you can add an annotation:
-
-```rust
-/// ```c
-/// printf("Hello, world\n");
-/// ```
-# fn foo() {}
-```
-
-This will highlight according to whatever language you're showing off.
-If you're only showing plain text, choose `text`.
-
-It's important to choose the correct annotation here, because `rustdoc` uses it
-in an interesting way: It can be used to actually test your examples in a
-library crate, so that they don't get out of date. If you have some C code but
-`rustdoc` thinks it's Rust because you left off the annotation, `rustdoc` will
-complain when trying to generate the documentation.
+This will add code highlighting. If you are only showing plain text, put `text`
+instead of `rust` after the triple graves (see below).
## Documentation as tests
@@ -460,8 +443,9 @@ not actually pass as a test.
```
The `no_run` attribute will compile your code, but not run it. This is
-important for examples such as "Here's how to start up a network service,"
-which you would want to make sure compile, but might run in an infinite loop!
+important for examples such as "Here's how to retrieve a web page,"
+which you would want to ensure compiles, but might be run in a test
+environment that has no network access.
### Documenting modules
@@ -483,7 +467,7 @@ you have a module in `foo.rs`, you'll often open its code and see this:
```rust
//! A module for using `foo`s.
//!
-//! The `foo` module contains a lot of useful functionality blah blah blah
+//! The `foo` module contains a lot of useful functionality blah blah blah...
```
### Crate documentation
@@ -600,7 +584,7 @@ is documented, especially when you are working on a library. Rust allows you to
to generate warnings or errors, when an item is missing documentation.
To generate warnings you use `warn`:
-```rust
+```rust,ignore
#![warn(missing_docs)]
```
@@ -630,7 +614,7 @@ struct Hidden;
You can control a few aspects of the HTML that `rustdoc` generates through the
`#![doc]` version of the attribute:
-```rust
+```rust,ignore
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/")]
diff --git a/trpl/drop.md b/trpl-1st-edition/drop.md
similarity index 91%
rename from trpl/drop.md
rename to trpl-1st-edition/drop.md
index 5513523..1d8c9a3 100644
--- a/trpl/drop.md
+++ b/trpl-1st-edition/drop.md
@@ -1,10 +1,10 @@
-% Drop
+# Drop
Now that we’ve discussed traits, let’s talk about a particular trait provided
by the Rust standard library, [`Drop`][drop]. The `Drop` trait provides a way
to run some code when a value goes out of scope. For example:
-[drop]: ../std/ops/trait.Drop.html
+[drop]: ../../std/ops/trait.Drop.html
```rust
struct HasDrop;
@@ -18,9 +18,9 @@ impl Drop for HasDrop {
fn main() {
let x = HasDrop;
- // do stuff
+ // Do stuff.
-} // x goes out of scope here
+} // `x` goes out of scope here.
```
When `x` goes out of scope at the end of `main()`, the code for `Drop` will
@@ -64,4 +64,4 @@ reference-counted type. When `Drop` is called, it will decrement the reference
count, and if the total number of references is zero, will clean up the
underlying value.
-[arc]: ../std/sync/struct.Arc.html
+[arc]: ../../std/sync/struct.Arc.html
diff --git a/trpl/effective-rust.md b/trpl-1st-edition/effective-rust.md
similarity index 95%
rename from trpl/effective-rust.md
rename to trpl-1st-edition/effective-rust.md
index 65873c8..ce2dfe4 100644
--- a/trpl/effective-rust.md
+++ b/trpl-1st-edition/effective-rust.md
@@ -1,4 +1,4 @@
-% Effective Rust
+# Effective Rust
So you’ve learned how to write some Rust code. But there’s a difference between
writing *any* Rust code and writing *good* Rust code.
diff --git a/trpl/enums.md b/trpl-1st-edition/enums.md
similarity index 97%
rename from trpl/enums.md
rename to trpl-1st-edition/enums.md
index 5e05b4e..9cf5e6b 100644
--- a/trpl/enums.md
+++ b/trpl-1st-edition/enums.md
@@ -1,4 +1,4 @@
-% Enums
+# Enums
An `enum` in Rust is a type that represents data that is one of
several possible variants. Each variant in the `enum` can optionally
@@ -51,7 +51,7 @@ possible variants:
```rust,ignore
fn process_color_change(msg: Message) {
- let Message::ChangeColor(r, g, b) = msg; // compile-time error
+ let Message::ChangeColor(r, g, b) = msg; // This causes a compile-time error.
}
```
diff --git a/trpl/error-handling.md b/trpl-1st-edition/error-handling.md
similarity index 95%
rename from trpl/error-handling.md
rename to trpl-1st-edition/error-handling.md
index 6e13b46..02bd675 100644
--- a/trpl/error-handling.md
+++ b/trpl-1st-edition/error-handling.md
@@ -1,4 +1,4 @@
-% Error Handling
+# Error Handling
Like most programming languages, Rust encourages the programmer to handle
errors in a particular way. Generally speaking, error handling is divided into
@@ -59,13 +59,13 @@ handling is reducing the amount of explicit case analysis the programmer has to
do while keeping code composable.
Keeping code composable is important, because without that requirement, we
-could [`panic`](../std/macro.panic!.html) whenever we
+could [`panic`](../../std/macro.panic.html) whenever we
come across something unexpected. (`panic` causes the current task to unwind,
and in most cases, the entire program aborts.) Here's an example:
```rust,should_panic
// Guess a number between 1 and 10.
-// If it matches the number we had in mind, return true. Else, return false.
+// If it matches the number we had in mind, return `true`. Else, return `false`.
fn guess(n: i32) -> bool {
if n < 1 || n > 10 {
panic!("Invalid number: {}", n);
@@ -236,7 +236,7 @@ fn extension_explicit(file_name: &str) -> Option<&str> {
```
(Pro-tip: don't use this code. Use the
-[`extension`](../std/path/struct.Path.html#method.extension)
+[`extension`](../../std/path/struct.Path.html#method.extension)
method in the standard library instead.)
The code stays simple, but the important thing to notice is that the type of
@@ -350,7 +350,7 @@ fn file_path_ext_explicit(file_path: &str) -> Option<&str> {
}
fn file_name(file_path: &str) -> Option<&str> {
- // implementation elided
+ // Implementation elided.
unimplemented!()
}
```
@@ -360,7 +360,7 @@ analysis, but its type doesn't quite fit...
```rust,ignore
fn file_path_ext(file_path: &str) -> Option<&str> {
- file_name(file_path).map(|x| extension(x)) //Compilation error
+ file_name(file_path).map(|x| extension(x)) // This causes a compilation error.
}
```
@@ -530,10 +530,10 @@ above is generic over all the different number types defined in the
standard library. We could (and probably should) also make our
function generic, but let's favor explicitness for the moment. We only
care about `i32`, so we need to [find its implementation of
-`FromStr`](../std/primitive.i32.html) (do a `CTRL-F` in your browser
+`FromStr`](../../std/primitive.i32.html) (do a `CTRL-F` in your browser
for “FromStr”) and look at its [associated type][10] `Err`. We did
this so we can find the concrete error type. In this case, it's
-[`std::num::ParseIntError`](../std/num/struct.ParseIntError.html).
+[`std::num::ParseIntError`](../../std/num/struct.ParseIntError.html).
Finally, we can rewrite our function:
```rust
@@ -577,12 +577,12 @@ fn main() {
```
The usual suspects are all there for `Result`, including
-[`unwrap_or`](../std/result/enum.Result.html#method.unwrap_or) and
-[`and_then`](../std/result/enum.Result.html#method.and_then).
+[`unwrap_or`](../../std/result/enum.Result.html#method.unwrap_or) and
+[`and_then`](../../std/result/enum.Result.html#method.and_then).
Additionally, since `Result` has a second type parameter, there are
combinators that affect only the error type, such as
-[`map_err`](../std/result/enum.Result.html#method.map_err) (instead of
-`map`) and [`or_else`](../std/result/enum.Result.html#method.or_else)
+[`map_err`](../../std/result/enum.Result.html#method.map_err) (instead of
+`map`) and [`or_else`](../../std/result/enum.Result.html#method.or_else)
(instead of `and_then`).
### The `Result` type alias idiom
@@ -611,11 +611,11 @@ Why would we do this? Well, if we have a lot of functions that could return
uses `ParseIntError` so that we don't have to write it out all the time.
The most prominent place this idiom is used in the standard library is
-with [`io::Result`](../std/io/type.Result.html). Typically, one writes
+with [`io::Result`](../../std/io/type.Result.html). Typically, one writes
`io::Result`, which makes it clear that you're using the `io`
module's type alias instead of the plain definition from
`std::result`. (This idiom is also used for
-[`fmt::Result`](../std/fmt/type.Result.html).)
+[`fmt::Result`](../../std/fmt/type.Result.html).)
## A brief interlude: unwrapping isn't evil
@@ -639,7 +639,7 @@ summarize some of my *opinions* on the matter.
This is probably not an exhaustive list. Moreover, when using an
`Option`, it is often better to use its
-[`expect`](../std/option/enum.Option.html#method.expect)
+[`expect`](../../std/option/enum.Option.html#method.expect)
method. `expect` does exactly the same thing as `unwrap`, except it
prints a message you give to `expect`. This makes the resulting panic
a bit nicer to deal with, since it will show your message instead of
@@ -719,7 +719,7 @@ fn main() {
```
There are a couple new things in this example. The first is the use of the
-[`Option::ok_or`](../std/option/enum.Option.html#method.ok_or)
+[`Option::ok_or`](../../std/option/enum.Option.html#method.ok_or)
combinator. This is one way to convert an `Option` into a `Result`. The
conversion requires you to specify what error to use if `Option` is `None`.
Like the other combinators we've seen, its definition is very simple:
@@ -734,7 +734,7 @@ fn ok_or(option: Option, err: E) -> Result {
```
The other new combinator used here is
-[`Result::map_err`](../std/result/enum.Result.html#method.map_err).
+[`Result::map_err`](../../std/result/enum.Result.html#method.map_err).
This is like `Result::map`, except it maps a function on to the *error*
portion of a `Result` value. If the `Result` is an `Ok(...)` value, then it is
returned unmodified.
@@ -781,7 +781,7 @@ fn main() {
(N.B. The `AsRef` is used because those are the
[same bounds used on
-`std::fs::File::open`](../std/fs/struct.File.html#method.open).
+`std::fs::File::open`](../../std/fs/struct.File.html#method.open).
This makes it ergonomic to use any kind of string as a file path.)
There are three different errors that can occur here:
@@ -791,16 +791,16 @@ There are three different errors that can occur here:
3. A problem parsing the data as a number.
The first two problems are described via the
-[`std::io::Error`](../std/io/struct.Error.html) type. We know this
+[`std::io::Error`](../../std/io/struct.Error.html) type. We know this
because of the return types of
-[`std::fs::File::open`](../std/fs/struct.File.html#method.open) and
-[`std::io::Read::read_to_string`](../std/io/trait.Read.html#method.read_to_string).
+[`std::fs::File::open`](../../std/fs/struct.File.html#method.open) and
+[`std::io::Read::read_to_string`](../../std/io/trait.Read.html#method.read_to_string).
(Note that they both use the [`Result` type alias
idiom](#the-result-type-alias-idiom) described previously. If you
click on the `Result` type, you'll [see the type
-alias](../std/io/type.Result.html), and consequently, the underlying
+alias](../../std/io/type.Result.html), and consequently, the underlying
`io::Error` type.) The third problem is described by the
-[`std::num::ParseIntError`](../std/num/struct.ParseIntError.html)
+[`std::num::ParseIntError`](../../std/num/struct.ParseIntError.html)
type. The `io::Error` type in particular is *pervasive* throughout the
standard library. You will see it again and again.
@@ -944,7 +944,7 @@ macro_rules! try {
}
```
-(The [real definition](../std/macro.try!.html) is a bit more
+(The [real definition](../../std/macro.try.html) is a bit more
sophisticated. We will address that later.)
Using the `try!` macro makes it very easy to simplify our last example. Since
@@ -1003,7 +1003,7 @@ determine the type of error is not robust. (Admittedly, this downside is far
more important inside of a library as opposed to, say, an application.)
For example, the `io::Error` type embeds an
-[`io::ErrorKind`](../std/io/enum.ErrorKind.html),
+[`io::ErrorKind`](../../std/io/enum.ErrorKind.html),
which is *structured data* that represents what went wrong during an IO
operation. This is important because you might want to react differently
depending on the error. (e.g., A `BrokenPipe` error might mean quitting your
@@ -1076,8 +1076,8 @@ that you don't remove choices from the caller unnecessarily.
# Standard library traits used for error handling
The standard library defines two integral traits for error handling:
-[`std::error::Error`](../std/error/trait.Error.html) and
-[`std::convert::From`](../std/convert/trait.From.html). While `Error`
+[`std::error::Error`](../../std/error/trait.Error.html) and
+[`std::convert::From`](../../std/convert/trait.From.html). While `Error`
is designed specifically for generically describing errors, the `From`
trait serves a more general role for converting values between two
distinct types.
@@ -1085,7 +1085,7 @@ distinct types.
## The `Error` trait
The `Error` trait is [defined in the standard
-library](../std/error/trait.Error.html):
+library](../../std/error/trait.Error.html):
```rust
use std::fmt::{Debug, Display};
@@ -1113,7 +1113,7 @@ The first two are a result of `Error` requiring impls for both `Debug` and
`Display`. The latter two are from the two methods defined on `Error`. The
power of `Error` comes from the fact that all error types impl `Error`, which
means errors can be existentially quantified as a
-[trait object](../book/trait-objects.html).
+[trait object](trait-objects.html).
This manifests as either `Box` or `&Error`. Indeed, the `cause` method
returns an `&Error`, which is itself a trait object. We'll revisit the
`Error` trait's utility as a trait object later.
@@ -1189,7 +1189,7 @@ different error types and satisfy the contracts defined for `description` and
The `std::convert::From` trait is
[defined in the standard
-library](../std/convert/trait.From.html):
+library](../../std/convert/trait.From.html):
@@ -1204,7 +1204,7 @@ way to talk about conversion *from* a particular type `T` to some other type
(in this case, “some other type” is the subject of the impl, or `Self`).
The crux of `From` is the
[set of implementations provided by the standard
-library](../std/convert/trait.From.html).
+library](../../std/convert/trait.From.html).
Here are a few simple examples demonstrating how `From` works:
@@ -1235,11 +1235,11 @@ use std::fs;
use std::io;
use std::num;
-// We have to jump through some hoops to actually get error values.
+// We have to jump through some hoops to actually get error values:
let io_err: io::Error = io::Error::last_os_error();
let parse_err: num::ParseIntError = "not a number".parse::().unwrap_err();
-// OK, here are the conversions.
+// OK, here are the conversions:
let err1: Box = From::from(io_err);
let err2: Box = From::from(parse_err);
```
@@ -1271,7 +1271,7 @@ macro_rules! try {
```
This is not its real definition. Its real definition is
-[in the standard library](../std/macro.try!.html):
+[in the standard library](../../std/macro.try.html):
@@ -1340,8 +1340,8 @@ There's one little nit left: the `Box` type is *opaque*. If we
return a `Box` to the caller, the caller can't (easily) inspect
underlying error type. The situation is certainly better than `String`
because the caller can call methods like
-[`description`](../std/error/trait.Error.html#tymethod.description)
-and [`cause`](../std/error/trait.Error.html#method.cause), but the
+[`description`](../../std/error/trait.Error.html#tymethod.description)
+and [`cause`](../../std/error/trait.Error.html#method.cause), but the
limitation remains: `Box` is opaque. (N.B. This isn't entirely
true because Rust does have runtime reflection, which is useful in
some scenarios that are [beyond the scope of this
@@ -1484,14 +1484,14 @@ And that's it!
If your library needs to report custom errors, then you should
probably define your own error type. It's up to you whether or not to
expose its representation (like
-[`ErrorKind`](../std/io/enum.ErrorKind.html)) or keep it hidden (like
-[`ParseIntError`](../std/num/struct.ParseIntError.html)). Regardless
+[`ErrorKind`](../../std/io/enum.ErrorKind.html)) or keep it hidden (like
+[`ParseIntError`](../../std/num/struct.ParseIntError.html)). Regardless
of how you do it, it's usually good practice to at least provide some
information about the error beyond its `String`
representation. But certainly, this will vary depending on use cases.
At a minimum, you should probably implement the
-[`Error`](../std/error/trait.Error.html)
+[`Error`](../../std/error/trait.Error.html)
trait. This will give users of your library some minimum flexibility for
[composing errors](#the-real-try-macro). Implementing the `Error` trait also
means that users are guaranteed the ability to obtain a string representation
@@ -1507,8 +1507,8 @@ provides `From` impls for both `io::Error` and `byteorder::Error`.
Finally, depending on your tastes, you may also want to define a
[`Result` type alias](#the-result-type-alias-idiom), particularly if your
library defines a single error type. This is used in the standard library
-for [`io::Result`](../std/io/type.Result.html)
-and [`fmt::Result`](../std/fmt/type.Result.html).
+for [`io::Result`](../../std/io/type.Result.html)
+and [`fmt::Result`](../../std/fmt/type.Result.html).
# Case study: A program to read population data
@@ -1609,7 +1609,7 @@ fn main() {
let data_path = &matches.free[0];
let city: &str = &matches.free[1];
- // Do stuff with information
+ // Do stuff with information.
}
```
@@ -1702,9 +1702,9 @@ fn main() {
Let's outline the errors. We can start with the obvious: the three places that
`unwrap` is called:
-1. [`File::open`](../std/fs/struct.File.html#method.open)
+1. [`File::open`](../../std/fs/struct.File.html#method.open)
can return an
- [`io::Error`](../std/io/struct.Error.html).
+ [`io::Error`](../../std/io/struct.Error.html).
2. [`csv::Reader::decode`](http://burntsushi.net/rustdoc/csv/struct.Reader.html#method.decode)
decodes one record at a time, and
[decoding a
@@ -1747,7 +1747,7 @@ simply ignoring that row.
use std::path::Path;
struct Row {
- // unchanged
+ // This struct remains unchanged.
}
struct PopulationCount {
@@ -1769,7 +1769,7 @@ fn search>(file_path: P, city: &str) -> Vec {
for row in rdr.decode::() {
let row = row.unwrap();
match row.population {
- None => { } // skip it
+ None => { } // Skip it.
Some(count) => if row.city == city {
found.push(PopulationCount {
city: row.city,
@@ -1825,7 +1825,7 @@ Let's try it:
```rust,ignore
use std::error::Error;
-// The rest of the code before this is unchanged
+// The rest of the code before this is unchanged.
fn search>
(file_path: P, city: &str)
@@ -1836,7 +1836,7 @@ fn search>
for row in rdr.decode::() {
let row = try!(row);
match row.population {
- None => { } // skip it
+ None => { } // Skip it.
Some(count) => if row.city == city {
found.push(PopulationCount {
city: row.city,
@@ -1859,7 +1859,7 @@ Instead of `x.unwrap()`, we now have `try!(x)`. Since our function returns a
error occurs.
At the end of `search` we also convert a plain string to an error type
-by using the [corresponding `From` impls](../std/convert/trait.From.html):
+by using the [corresponding `From` impls](../../std/convert/trait.From.html):
```rust,ignore
// We are making use of this impl in the code above, since we call `From::from`
@@ -1957,7 +1957,7 @@ that it is generic on some type parameter `R` that satisfies
```rust,ignore
use std::io;
-// The rest of the code before this is unchanged
+// The rest of the code before this is unchanged.
fn search>
(file_path: &Option
, city: &str)
@@ -2070,7 +2070,7 @@ fn search>
for row in rdr.decode::() {
let row = try!(row);
match row.population {
- None => { } // skip it
+ None => { } // Skip it.
Some(count) => if row.city == city {
found.push(PopulationCount {
city: row.city,
@@ -2162,10 +2162,10 @@ heuristics!
* If you're writing short example code that would be overburdened by error
handling, it's probably fine to use `unwrap` (whether that's
- [`Result::unwrap`](../std/result/enum.Result.html#method.unwrap),
- [`Option::unwrap`](../std/option/enum.Option.html#method.unwrap)
+ [`Result::unwrap`](../../std/result/enum.Result.html#method.unwrap),
+ [`Option::unwrap`](../../std/option/enum.Option.html#method.unwrap)
or preferably
- [`Option::expect`](../std/option/enum.Option.html#method.expect)).
+ [`Option::expect`](../../std/option/enum.Option.html#method.expect)).
Consumers of your code should know to use proper error handling. (If they
don't, send them here!)
* If you're writing a quick 'n' dirty program, don't feel ashamed if you use
@@ -2175,37 +2175,37 @@ heuristics!
anyway, then use either a `String` or a `Box` for your
error type.
* Otherwise, in a program, define your own error types with appropriate
- [`From`](../std/convert/trait.From.html)
+ [`From`](../../std/convert/trait.From.html)
and
- [`Error`](../std/error/trait.Error.html)
- impls to make the [`try!`](../std/macro.try!.html)
+ [`Error`](../../std/error/trait.Error.html)
+ impls to make the [`try!`](../../std/macro.try.html)
macro more ergonomic.
* If you're writing a library and your code can produce errors, define your own
error type and implement the
- [`std::error::Error`](../std/error/trait.Error.html)
+ [`std::error::Error`](../../std/error/trait.Error.html)
trait. Where appropriate, implement
- [`From`](../std/convert/trait.From.html) to make both
+ [`From`](../../std/convert/trait.From.html) to make both
your library code and the caller's code easier to write. (Because of Rust's
coherence rules, callers will not be able to impl `From` on your error type,
so your library should do it.)
* Learn the combinators defined on
- [`Option`](../std/option/enum.Option.html)
+ [`Option`](../../std/option/enum.Option.html)
and
- [`Result`](../std/result/enum.Result.html).
+ [`Result`](../../std/result/enum.Result.html).
Using them exclusively can be a bit tiring at times, but I've personally
found a healthy mix of `try!` and combinators to be quite appealing.
`and_then`, `map` and `unwrap_or` are my favorites.
-[1]: ../book/patterns.html
-[2]: ../std/option/enum.Option.html#method.map
-[3]: ../std/option/enum.Option.html#method.unwrap_or
-[4]: ../std/option/enum.Option.html#method.unwrap_or_else
-[5]: ../std/option/enum.Option.html
-[6]: ../std/result/index.html
-[7]: ../std/result/enum.Result.html#method.unwrap
-[8]: ../std/fmt/trait.Debug.html
-[9]: ../std/primitive.str.html#method.parse
-[10]: ../book/associated-types.html
+[1]: patterns.html
+[2]: ../../std/option/enum.Option.html#method.map
+[3]: ../../std/option/enum.Option.html#method.unwrap_or
+[4]: ../../std/option/enum.Option.html#method.unwrap_or_else
+[5]: ../../std/option/enum.Option.html
+[6]: ../../std/result/index.html
+[7]: ../../std/result/enum.Result.html#method.unwrap
+[8]: ../../std/fmt/trait.Debug.html
+[9]: ../../std/primitive.str.html#method.parse
+[10]: associated-types.html
[11]: https://github.com/petewarden/dstkdata
[12]: http://burntsushi.net/stuff/worldcitiespop.csv.gz
[13]: http://burntsushi.net/stuff/uscitiespop.csv.gz
diff --git a/trpl/ffi.md b/trpl-1st-edition/ffi.md
similarity index 92%
rename from trpl/ffi.md
rename to trpl-1st-edition/ffi.md
index ca104ff..067d061 100644
--- a/trpl/ffi.md
+++ b/trpl-1st-edition/ffi.md
@@ -1,4 +1,4 @@
-% Foreign Function Interface
+# Foreign Function Interface
# Introduction
@@ -28,8 +28,7 @@ and add `extern crate libc;` to your crate root.
The following is a minimal example of calling a foreign function which will
compile if snappy is installed:
-```rust,no_run
-# #![feature(libc)]
+```rust,ignore
extern crate libc;
use libc::size_t;
@@ -56,14 +55,13 @@ almost any function that takes a pointer argument isn't valid for all possible
inputs since the pointer could be dangling, and raw pointers fall outside of
Rust's safe memory model.
-When declaring the argument types to a foreign function, the Rust compiler can
-not check if the declaration is correct, so specifying it correctly is part of
-keeping the binding correct at runtime.
+When declaring the argument types to a foreign function, the Rust compiler
+cannot check if the declaration is correct, so specifying it correctly is part
+of keeping the binding correct at runtime.
The `extern` block can be extended to cover the entire snappy API:
-```rust,no_run
-# #![feature(libc)]
+```rust,ignore
extern crate libc;
use libc::{c_int, size_t};
@@ -95,11 +93,10 @@ internal details.
Wrapping the functions which expect buffers involves using the `slice::raw` module to manipulate Rust
vectors as pointers to memory. Rust's vectors are guaranteed to be a contiguous block of memory. The
-length is number of elements currently contained, and the capacity is the total size in elements of
+length is the number of elements currently contained, and the capacity is the total size in elements of
the allocated memory. The length is less than or equal to the capacity.
-```rust
-# #![feature(libc)]
+```rust,ignore
# extern crate libc;
# use libc::{c_int, size_t};
# unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 }
@@ -123,8 +120,7 @@ required capacity to hold the compressed output. The vector can then be passed t
`snappy_compress` function as an output parameter. An output parameter is also passed to retrieve
the true length after compression for setting the length.
-```rust
-# #![feature(libc)]
+```rust,ignore
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8,
@@ -150,8 +146,7 @@ pub fn compress(src: &[u8]) -> Vec {
Decompression is similar, because snappy stores the uncompressed size as part of the compression
format and `snappy_uncompressed_length` will retrieve the exact buffer size required.
-```rust
-# #![feature(libc)]
+```rust,ignore
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_uncompress(compressed: *const u8,
@@ -185,8 +180,7 @@ pub fn uncompress(src: &[u8]) -> Option> {
Then, we can add some tests to show how to use them.
-```rust
-# #![feature(libc)]
+```rust,ignore
# extern crate libc;
# use libc::{c_int, size_t};
# unsafe fn snappy_compress(input: *const u8,
@@ -246,7 +240,7 @@ Foreign libraries often hand off ownership of resources to the calling code.
When this occurs, we must use Rust's destructors to provide safety and guarantee
the release of these resources (especially in the case of panic).
-For more about destructors, see the [Drop trait](../std/ops/trait.Drop.html).
+For more about destructors, see the [Drop trait](../../std/ops/trait.Drop.html).
# Callbacks from C code to Rust functions
@@ -277,7 +271,7 @@ extern {
fn main() {
unsafe {
register_callback(callback);
- trigger_callback(); // Triggers the callback
+ trigger_callback(); // Triggers the callback.
}
}
```
@@ -294,7 +288,7 @@ int32_t register_callback(rust_callback callback) {
}
void trigger_callback() {
- cb(7); // Will call callback(7) in Rust
+ cb(7); // Will call callback(7) in Rust.
}
```
@@ -309,7 +303,7 @@ However it is often desired that the callback is targeted to a special
Rust object. This could be the object that represents the wrapper for the
respective C object.
-This can be achieved by passing an raw pointer to the object down to the
+This can be achieved by passing a raw pointer to the object down to the
C library. The C library can then include the pointer to the Rust object in
the notification. This will allow the callback to unsafely access the
referenced Rust object.
@@ -320,13 +314,13 @@ Rust code:
#[repr(C)]
struct RustObject {
a: i32,
- // other members
+ // Other members...
}
extern "C" fn callback(target: *mut RustObject, a: i32) {
println!("I'm called from C with value {0}", a);
unsafe {
- // Update the value in RustObject with the value received from the callback
+ // Update the value in RustObject with the value received from the callback:
(*target).a = a;
}
}
@@ -339,7 +333,7 @@ extern {
}
fn main() {
- // Create the object that will be referenced in the callback
+ // Create the object that will be referenced in the callback:
let mut rust_object = Box::new(RustObject { a: 5 });
unsafe {
@@ -363,7 +357,7 @@ int32_t register_callback(void* callback_target, rust_callback callback) {
}
void trigger_callback() {
- cb(cb_target, 7); // Will call callback(&rustObject, 7) in Rust
+ cb(cb_target, 7); // Will call callback(&rustObject, 7) in Rust.
}
```
@@ -408,7 +402,7 @@ libraries:
* Static - `#[link(name = "my_build_dependency", kind = "static")]`
* Frameworks - `#[link(name = "CoreFoundation", kind = "framework")]`
-Note that frameworks are only available on OSX targets.
+Note that frameworks are only available on macOS targets.
The different `kind` values are meant to differentiate how the native library
participates in linkage. From a linkage perspective, the Rust compiler creates
@@ -437,7 +431,7 @@ A few examples of how this model can be used are:
is included in a final target (like a binary), the native library will be
linked in.
-On OSX, frameworks behave with the same semantics as a dynamic library.
+On macOS, frameworks behave with the same semantics as a dynamic library.
# Unsafe blocks
@@ -460,8 +454,7 @@ Foreign APIs often export a global variable which could do something like track
global state. In order to access these variables, you declare them in `extern`
blocks with the `static` keyword:
-```rust,no_run
-# #![feature(libc)]
+```rust,ignore
extern crate libc;
#[link(name = "readline")]
@@ -471,7 +464,7 @@ extern {
fn main() {
println!("You have readline version {} installed.",
- rl_readline_version as i32);
+ unsafe { rl_readline_version as i32 });
}
```
@@ -479,8 +472,7 @@ Alternatively, you may need to alter global state provided by a foreign
interface. To do this, statics can be declared with `mut` so we can mutate
them.
-```rust,no_run
-# #![feature(libc)]
+```rust,ignore
extern crate libc;
use std::ffi::CString;
@@ -512,8 +504,7 @@ Most foreign code exposes a C ABI, and Rust uses the platform's C calling conven
calling foreign functions. Some foreign functions, most notably the Windows API, use other calling
conventions. Rust provides a way to tell the compiler which convention to use:
-```rust
-# #![feature(libc)]
+```rust,ignore
extern crate libc;
#[cfg(all(target_os = "win32", target_arch = "x86"))]
@@ -539,6 +530,7 @@ This is currently hidden behind the `abi_vectorcall` gate and is subject to chan
* `system`
* `C`
* `win64`
+* `sysv64`
Most of the abis in this list are self-explanatory, but the `system` abi may
seem a little odd. This constraint selects whatever the appropriate ABI is for
@@ -573,6 +565,31 @@ The [`libc` crate on crates.io][libc] includes type aliases and function
definitions for the C standard library in the `libc` module, and Rust links
against `libc` and `libm` by default.
+# Variadic functions
+
+In C, functions can be 'variadic', meaning they accept a variable number of arguments. This can
+be achieved in Rust by specifying `...` within the argument list of a foreign function declaration:
+
+```no_run
+extern {
+ fn foo(x: i32, ...);
+}
+
+fn main() {
+ unsafe {
+ foo(10, 20, 30, 40, 50);
+ }
+}
+```
+
+Normal Rust functions can *not* be variadic:
+
+```ignore
+// This will not compile
+
+fn foo(x: i32, ...) { }
+```
+
# The "nullable pointer optimization"
Certain Rust types are defined to never be `null`. This includes references (`&T`,
@@ -598,14 +615,13 @@ callback, which gets called in certain situations. The callback is passed a func
and an integer and it is supposed to run the function with the integer as a parameter. So
we have function pointers flying across the FFI boundary in both directions.
-```rust
-# #![feature(libc)]
+```rust,ignore
extern crate libc;
use libc::c_int;
# #[cfg(hidden)]
extern "C" {
- /// Register the callback.
+ /// Registers the callback.
fn register(cb: Option c_int>, c_int) -> c_int>);
}
# unsafe fn register(_: Option c_int>,
@@ -661,26 +677,31 @@ attribute turns off Rust's name mangling, so that it is easier to link to.
It’s important to be mindful of `panic!`s when working with FFI. A `panic!`
across an FFI boundary is undefined behavior. If you’re writing code that may
-panic, you should run it in another thread, so that the panic doesn’t bubble up
-to C:
+panic, you should run it in a closure with [`catch_unwind`]:
```rust
-use std::thread;
+use std::panic::catch_unwind;
#[no_mangle]
pub extern fn oh_no() -> i32 {
- let h = thread::spawn(|| {
+ let result = catch_unwind(|| {
panic!("Oops!");
});
-
- match h.join() {
- Ok(_) => 1,
- Err(_) => 0,
+ match result {
+ Ok(_) => 0,
+ Err(_) => 1,
}
}
-# fn main() {}
+
+fn main() {}
```
+Please note that [`catch_unwind`] will only catch unwinding panics, not
+those who abort the process. See the documentation of [`catch_unwind`]
+for more information.
+
+[`catch_unwind`]: ../../std/panic/fn.catch_unwind.html
+
# Representing opaque structs
Sometimes, a C library wants to provide a pointer to something, but not let you
@@ -694,8 +715,7 @@ void bar(void *arg);
We can represent this in Rust with the `c_void` type:
-```rust
-# #![feature(libc)]
+```rust,ignore
extern crate libc;
extern "C" {
diff --git a/trpl/functions.md b/trpl-1st-edition/functions.md
similarity index 93%
rename from trpl/functions.md
rename to trpl-1st-edition/functions.md
index b040684..96c8e9f 100644
--- a/trpl/functions.md
+++ b/trpl-1st-edition/functions.md
@@ -1,4 +1,4 @@
-% Functions
+# Functions
Every Rust program has at least one function, the `main` function:
@@ -135,7 +135,7 @@ In Rust, however, using `let` to introduce a binding is _not_ an expression. The
following will produce a compile-time error:
```rust,ignore
-let x = (let y = 5); // expected identifier, found keyword `let`
+let x = (let y = 5); // Expected identifier, found keyword `let`.
```
The compiler is telling us here that it was expecting to see the beginning of
@@ -151,7 +151,7 @@ other returned value would be too surprising:
```rust
let mut y = 5;
-let x = (y = 6); // x has the value `()`, not `6`
+let x = (y = 6); // `x` has the value `()`, not `6`.
```
The second kind of statement in Rust is the *expression statement*. Its
@@ -183,7 +183,7 @@ But what about early returns? Rust does have a keyword for that, `return`:
fn foo(x: i32) -> i32 {
return x;
- // we never run this code!
+ // We never run this code!
x + 1
}
```
@@ -230,6 +230,19 @@ If you want more information, you can get a backtrace by setting the
```text
$ RUST_BACKTRACE=1 ./diverges
thread 'main' panicked at 'This function never returns!', hello.rs:2
+Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
+stack backtrace:
+ hello::diverges
+ at ./hello.rs:2
+ hello::main
+ at ./hello.rs:6
+```
+
+If you want the complete backtrace and filenames:
+
+```text
+$ RUST_BACKTRACE=full ./diverges
+thread 'main' panicked at 'This function never returns!', hello.rs:2
stack backtrace:
1: 0x7f402773a829 - sys::backtrace::write::h0942de78b6c02817K8r
2: 0x7f402773d7fc - panicking::on_panic::h3f23f9d0b5f4c91bu9w
@@ -262,7 +275,7 @@ note: Run with `RUST_BACKTRACE=1` for a backtrace.
`RUST_BACKTRACE` also works with Cargo’s `run` command:
```text
-$ RUST_BACKTRACE=1 cargo run
+$ RUST_BACKTRACE=full cargo run
Running `target/debug/diverges`
thread 'main' panicked at 'This function never returns!', hello.rs:2
stack backtrace:
@@ -307,10 +320,10 @@ fn plus_one(i: i32) -> i32 {
i + 1
}
-// without type inference
+// Without type inference:
let f: fn(i32) -> i32 = plus_one;
-// with type inference
+// With type inference:
let f = plus_one;
```
diff --git a/trpl/generics.md b/trpl-1st-edition/generics.md
similarity index 75%
rename from trpl/generics.md
rename to trpl-1st-edition/generics.md
index 9ab6014..891380c 100644
--- a/trpl/generics.md
+++ b/trpl-1st-edition/generics.md
@@ -1,4 +1,4 @@
-% Generics
+# Generics
Sometimes, when writing a function or data type, we may want it to work for
multiple types of arguments. In Rust, we can do this with generics.
@@ -78,7 +78,7 @@ We can write functions that take generic types with a similar syntax:
```rust
fn takes_anything(x: T) {
- // do something with x
+ // Do something with `x`.
}
```
@@ -140,5 +140,51 @@ container types like [`Vec`][Vec]. On the other hand, often you want to
trade that flexibility for increased expressive power. Read about [trait
bounds][traits] to see why and how.
+## Resolving ambiguities
+
+Most of the time when generics are involved, the compiler can infer the
+generic parameters automatically:
+
+```rust
+// v must be a Vec but we don't know what T is yet
+let mut v = Vec::new();
+// v just got a bool value, so T must be bool!
+v.push(true);
+// Debug-print v
+println!("{:?}", v);
+```
+
+Sometimes though, the compiler needs a little help. For example, had we
+omitted the last line, we would get a compile error:
+
+```rust,ignore
+let v = Vec::new();
+// ^^^^^^^^ cannot infer type for `T`
+//
+// note: type annotations or generic parameter binding required
+println!("{:?}", v);
+```
+
+We can solve this using either a type annotation:
+
+```rust
+let v: Vec = Vec::new();
+println!("{:?}", v);
+```
+
+or by binding the generic parameter `T` via the so-called
+[‘turbofish’][turbofish] `::<>` syntax:
+
+```rust
+let v = Vec::::new();
+println!("{:?}", v);
+```
+
+The second approach is useful in situations where we don’t want to bind the
+result to a variable. It can also be used to bind generic parameters in
+functions or methods. See [Iterators § Consumers](iterators.html#consumers)
+for an example.
+
[traits]: traits.html
-[Vec]: ../std/vec/struct.Vec.html
+[Vec]: ../../std/vec/struct.Vec.html
+[turbofish]: ../../std/iter/trait.Iterator.html#method.collect
diff --git a/trpl/getting-started.md b/trpl-1st-edition/getting-started.md
similarity index 68%
rename from trpl/getting-started.md
rename to trpl-1st-edition/getting-started.md
index 700ab2b..06ea24f 100644
--- a/trpl/getting-started.md
+++ b/trpl-1st-edition/getting-started.md
@@ -1,151 +1,63 @@
-% Getting Started
+# Getting Started
This first chapter of the book will get us going with Rust and its tooling.
First, we’ll install Rust. Then, the classic ‘Hello World’ program. Finally,
we’ll talk about Cargo, Rust’s build system and package manager.
+We’ll be showing off a number of commands using a terminal, and those lines all
+start with `$`. You don't need to type in the `$`s, they are there to indicate
+the start of each command. We’ll see many tutorials and examples around the web
+that follow this convention: `$` for commands run as our regular user, and `#`
+for commands we should be running as an administrator.
+
# Installing Rust
The first step to using Rust is to install it. Generally speaking, you’ll need
an Internet connection to run the commands in this section, as we’ll be
downloading Rust from the Internet.
-We’ll be showing off a number of commands using a terminal, and those lines all
-start with `$`. You don't need to type in the `$`s, they are there to indicate
-the start of each command. We’ll see many tutorials and examples around the web
-that follow this convention: `$` for commands run as our regular user, and `#`
-for commands we should be running as an administrator.
+The Rust compiler runs on, and compiles to, a great number of platforms, but is
+best supported on Linux, Mac, and Windows, on the x86 and x86-64 CPU
+architecture. There are official builds of the Rust compiler and standard
+library for these platforms and more. [For full details on Rust platform support
+see the website][platform-support].
+
+[platform-support]: https://forge.rust-lang.org/platform-support.html
+
+## Installing Rust
-## Platform support
-
-The Rust compiler runs on, and compiles to, a great number of platforms, though
-not all platforms are equally supported. Rust's support levels are organized
-into three tiers, each with a different set of guarantees.
-
-Platforms are identified by their "target triple" which is the string to inform
-the compiler what kind of output should be produced. The columns below indicate
-whether the corresponding component works on the specified platform.
-
-### Tier 1
-
-Tier 1 platforms can be thought of as "guaranteed to build and work".
-Specifically they will each satisfy the following requirements:
-
-* Automated testing is set up to run tests for the platform.
-* Landing changes to the `rust-lang/rust` repository's master branch is gated on
- tests passing.
-* Official release artifacts are provided for the platform.
-* Documentation for how to use and how to build the platform is available.
-
-| Target | std |rustc|cargo| notes |
-|-------------------------------|-----|-----|-----|----------------------------|
-| `i686-apple-darwin` | ✓ | ✓ | ✓ | 32-bit OSX (10.7+, Lion+) |
-| `i686-pc-windows-gnu` | ✓ | ✓ | ✓ | 32-bit MinGW (Windows 7+) |
-| `i686-pc-windows-msvc` | ✓ | ✓ | ✓ | 32-bit MSVC (Windows 7+) |
-| `i686-unknown-linux-gnu` | ✓ | ✓ | ✓ | 32-bit Linux (2.6.18+) |
-| `x86_64-apple-darwin` | ✓ | ✓ | ✓ | 64-bit OSX (10.7+, Lion+) |
-| `x86_64-pc-windows-gnu` | ✓ | ✓ | ✓ | 64-bit MinGW (Windows 7+) |
-| `x86_64-pc-windows-msvc` | ✓ | ✓ | ✓ | 64-bit MSVC (Windows 7+) |
-| `x86_64-unknown-linux-gnu` | ✓ | ✓ | ✓ | 64-bit Linux (2.6.18+) |
-
-### Tier 2
-
-Tier 2 platforms can be thought of as "guaranteed to build". Automated tests
-are not run so it's not guaranteed to produce a working build, but platforms
-often work to quite a good degree and patches are always welcome! Specifically,
-these platforms are required to have each of the following:
-
-* Automated building is set up, but may not be running tests.
-* Landing changes to the `rust-lang/rust` repository's master branch is gated on
- platforms **building**. Note that this means for some platforms only the
- standard library is compiled, but for others the full bootstrap is run.
-* Official release artifacts are provided for the platform.
-
-| Target | std |rustc|cargo| notes |
-|-------------------------------|-----|-----|-----|----------------------------|
-| `aarch64-apple-ios` | ✓ | | | ARM64 iOS |
-| `aarch64-unknown-linux-gnu` | ✓ | ✓ | ✓ | ARM64 Linux (2.6.18+) |
-| `arm-linux-androideabi` | ✓ | | | ARM Android |
-| `arm-unknown-linux-gnueabi` | ✓ | ✓ | ✓ | ARM Linux (2.6.18+) |
-| `arm-unknown-linux-gnueabihf` | ✓ | ✓ | ✓ | ARM Linux (2.6.18+) |
-| `armv7-apple-ios` | ✓ | | | ARM iOS |
-|`armv7-unknown-linux-gnueabihf`| ✓ | ✓ | ✓ | ARMv7 Linux (2.6.18+) |
-| `armv7s-apple-ios` | ✓ | | | ARM iOS |
-| `i386-apple-ios` | ✓ | | | 32-bit x86 iOS |
-| `i586-pc-windows-msvc` | ✓ | | | 32-bit Windows w/o SSE |
-| `mips-unknown-linux-gnu` | ✓ | | | MIPS Linux (2.6.18+) |
-| `mips-unknown-linux-musl` | ✓ | | | MIPS Linux with MUSL |
-| `mipsel-unknown-linux-gnu` | ✓ | | | MIPS (LE) Linux (2.6.18+) |
-| `mipsel-unknown-linux-musl` | ✓ | | | MIPS (LE) Linux with MUSL |
-| `powerpc-unknown-linux-gnu` | ✓ | | | PowerPC Linux (2.6.18+) |
-| `powerpc64-unknown-linux-gnu` | ✓ | | | PPC64 Linux (2.6.18+) |
-|`powerpc64le-unknown-linux-gnu`| ✓ | | | PPC64LE Linux (2.6.18+) |
-| `x86_64-apple-ios` | ✓ | | | 64-bit x86 iOS |
-| `x86_64-rumprun-netbsd` | ✓ | | | 64-bit NetBSD Rump Kernel |
-| `x86_64-unknown-freebsd` | ✓ | ✓ | ✓ | 64-bit FreeBSD |
-| `x86_64-unknown-linux-musl` | ✓ | | | 64-bit Linux with MUSL |
-| `x86_64-unknown-netbsd` | ✓ | ✓ | ✓ | 64-bit NetBSD |
-
-### Tier 3
-
-Tier 3 platforms are those which Rust has support for, but landing changes is
-not gated on the platform either building or passing tests. Working builds for
-these platforms may be spotty as their reliability is often defined in terms of
-community contributions. Additionally, release artifacts and installers are not
-provided, but there may be community infrastructure producing these in
-unofficial locations.
-
-| Target | std |rustc|cargo| notes |
-|-------------------------------|-----|-----|-----|----------------------------|
-| `aarch64-linux-android` | ✓ | | | ARM64 Android |
-| `armv7-linux-androideabi` | ✓ | | | ARM-v7a Android |
-| `i686-linux-android` | ✓ | | | 32-bit x86 Android |
-| `i686-pc-windows-msvc` (XP) | ✓ | | | Windows XP support |
-| `i686-unknown-freebsd` | ✓ | ✓ | ✓ | 32-bit FreeBSD |
-| `x86_64-pc-windows-msvc` (XP) | ✓ | | | Windows XP support |
-| `x86_64-sun-solaris` | ✓ | ✓ | | 64-bit Solaris/SunOS |
-| `x86_64-unknown-bitrig` | ✓ | ✓ | | 64-bit Bitrig |
-| `x86_64-unknown-dragonfly` | ✓ | ✓ | | 64-bit DragonFlyBSD |
-| `x86_64-unknown-openbsd` | ✓ | ✓ | | 64-bit OpenBSD |
-
-Note that this table can be expanded over time, this isn't the exhaustive set of
-tier 3 platforms that will ever be!
-
-## Installing on Linux or Mac
-
-If we're on Linux or a Mac, all we need to do is open a terminal and type this:
+All you need to do on Unix systems like Linux and macOS is open a
+terminal and type this:
```bash
-$ curl -sSf https://static.rust-lang.org/rustup.sh | sh
+$ curl https://sh.rustup.rs -sSf | sh
```
-This will download a script, and start the installation. If it all goes well,
-you’ll see this appear:
+It will download a script, and start the installation. If everything
+goes well, you’ll see this appear:
```text
-Rust is ready to roll.
+Rust is installed now. Great!
```
-From here, press `y` for ‘yes’, and then follow the rest of the prompts.
+Installing on Windows is nearly as easy: download and run
+[rustup-init.exe]. It will start the installation in a console and
+present the above message on success.
-## Installing on Windows
+For other installation options and information, visit the [install]
+page of the Rust website.
-If you're on Windows, please download the appropriate [installer][install-page].
-
-[install-page]: https://www.rust-lang.org/install.html
+[rustup-init.exe]: https://win.rustup.rs
+[install]: https://www.rust-lang.org/install.html
## Uninstalling
-Uninstalling Rust is as easy as installing it. On Linux or Mac, run
-the uninstall script:
+Uninstalling Rust is as easy as installing it:
```bash
-$ sudo /usr/local/lib/rustlib/uninstall.sh
+$ rustup self uninstall
```
-If we used the Windows installer, we can re-run the `.msi` and it will give us
-an uninstall option.
-
## Troubleshooting
If we've got Rust installed, we can open up a shell, and type this:
@@ -158,20 +70,33 @@ You should see the version number, commit hash, and commit date.
If you do, Rust has been installed successfully! Congrats!
-If you don't and you're on Windows, check that Rust is in your %PATH% system
-variable: `$ echo %PATH%`. If it isn't, run the installer again, select "Change"
-on the "Change, repair, or remove installation" page and ensure "Add to PATH" is
-installed on the local hard drive. If you need to configure your path manually,
-you can find the Rust executables in a directory like
-`"C:\Program Files\Rust stable GNU 1.x\bin"`.
+If you don't, that probably means that the `PATH` environment variable
+doesn't include Cargo's binary directory, `~/.cargo/bin` on Unix, or
+`%USERPROFILE%\.cargo\bin` on Windows. This is the directory where
+Rust development tools live, and most Rust developers keep it in their
+`PATH` environment variable, which makes it possible to run `rustc` on
+the command line. Due to differences in operating systems, command
+shells, and bugs in installation, you may need to restart your shell,
+log out of the system, or configure `PATH` manually as appropriate for
+your operating environment.
Rust does not do its own linking, and so you’ll need to have a linker
-installed. Doing so will depend on your specific system, consult its
-documentation for more details.
-
-If not, there are a number of places where we can get help. The easiest is
-[the #rust-beginners IRC channel on irc.mozilla.org][irc-beginners] and for
-general discussion [the #rust IRC channel on irc.mozilla.org][irc], which we
+installed. Doing so will depend on your specific system. For
+Linux-based systems, Rust will attempt to call `cc` for linking. On
+`windows-msvc` (Rust built on Windows with Microsoft Visual Studio),
+this depends on having [Microsoft Visual C++ Build Tools][msvbt]
+installed. These do not need to be in `%PATH%` as `rustc` will find
+them automatically. In general, if you have your linker in a
+non-traditional location you can call `rustc
+linker=/path/to/cc`, where `/path/to/cc` should point to your linker path.
+
+[msvbt]: http://landinghub.visualstudio.com/visual-cpp-build-tools
+
+If you are still stuck, there are a number of places where we can get
+help. The easiest is
+[the #rust-beginners IRC channel on irc.mozilla.org][irc-beginners]
+and for general discussion
+[the #rust IRC channel on irc.mozilla.org][irc], which we
can access through [Mibbit][mibbit]. Then we'll be chatting with other
Rustaceans (a silly nickname we call ourselves) who can help us out. Other great
resources include [the user’s forum][users] and [Stack Overflow][stackoverflow].
@@ -183,9 +108,7 @@ resources include [the user’s forum][users] and [Stack Overflow][stackoverflow
[stackoverflow]: http://stackoverflow.com/questions/tagged/rust
This installer also installs a copy of the documentation locally, so we can
-read it offline. On UNIX systems, `/usr/local/share/doc/rust` is the location.
-On Windows, it's in a `share/doc` directory, inside the directory to which Rust
-was installed.
+read it offline. It's only a `rustup doc` away!
# Hello, world!
@@ -230,12 +153,13 @@ $ cd hello_world
## Writing and Running a Rust Program
-Next, make a new source file and call it *main.rs*. Rust files always end
-in a *.rs* extension. If you’re using more than one word in your filename, use
-an underscore to separate them; for example, you'd use *hello_world.rs* rather
-than *helloworld.rs*.
+We need to create a source file for our Rust program. Rust files always end
+in a *.rs* extension. If you are using more than one word in your filename,
+use an underscore to separate them; for example, you would use
+*my_program.rs* rather than *myprogram.rs*.
-Now open the *main.rs* file you just created, and type the following code:
+Now, make a new file and call it *main.rs*. Open the file and type
+the following code:
```rust
fn main() {
@@ -243,7 +167,7 @@ fn main() {
}
```
-Save the file, and go back to your terminal window. On Linux or OSX, enter the
+Save the file, and go back to your terminal window. On Linux or macOS, enter the
following commands:
```bash
@@ -329,7 +253,7 @@ $ rustc main.rs
If you come from a C or C++ background, you'll notice that this is similar to
`gcc` or `clang`. After compiling successfully, Rust should output a binary
-executable, which you can see on Linux or OSX by entering the `ls` command in
+executable, which you can see on Linux or macOS by entering the `ls` command in
your shell as follows:
```bash
@@ -494,6 +418,9 @@ $ cargo run
Hello, world!
```
+The `run` command comes in handy when you need to rapidly iterate on a
+project.
+
Notice that this example didn’t re-build the project. Cargo figured out that
the file hasn’t changed, and so it just ran the binary. If you'd modified your
source code, Cargo would have rebuilt the project before running it, and you
diff --git a/trpl/glossary.md b/trpl-1st-edition/glossary.md
similarity index 96%
rename from trpl/glossary.md
rename to trpl-1st-edition/glossary.md
index 8aa7fdf..3895303 100644
--- a/trpl/glossary.md
+++ b/trpl-1st-edition/glossary.md
@@ -1,4 +1,4 @@
-% Glossary
+# Glossary
Not every Rustacean has a background in systems programming, nor in computer
science, so we've added explanations of terms that might be unfamiliar.
@@ -56,7 +56,7 @@ They can be used to manage control flow in a modular fashion.
A type without a statically known size or alignment. ([more info][link])
-[link]: ../nomicon/exotic-sizes.html#dynamically-sized-types-dsts
+[link]: ../../nomicon/exotic-sizes.html#dynamically-sized-types-dsts
### Expression
diff --git a/trpl/guessing-game.md b/trpl-1st-edition/guessing-game.md
similarity index 90%
rename from trpl/guessing-game.md
rename to trpl-1st-edition/guessing-game.md
index 22cf606..8464cf0 100644
--- a/trpl/guessing-game.md
+++ b/trpl-1st-edition/guessing-game.md
@@ -1,4 +1,4 @@
-% Guessing Game
+# Guessing Game
Let’s learn some Rust! For our first project, we’ll implement a classic
beginner programming problem: the guessing game. Here’s how it works: Our
@@ -19,6 +19,7 @@ has a command that does that for us. Let’s give it a shot:
```bash
$ cd ~/projects
$ cargo new guessing_game --bin
+ Created binary (application) `guessing_game` project
$ cd guessing_game
```
@@ -51,25 +52,24 @@ Let’s try compiling what Cargo gave us:
```{bash}
$ cargo build
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.53 secs
```
Excellent! Open up your `src/main.rs` again. We’ll be writing all of
our code in this file.
-Before we move on, let me show you one more Cargo command: `run`. `cargo run`
-is kind of like `cargo build`, but it also then runs the produced executable.
-Try it out:
+Remember the `run` command from last chapter? Try it out again here:
```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/guessing_game`
Hello, world!
```
-Great! The `run` command comes in handy when you need to rapidly iterate on a
-project. Our game is such a project, we need to quickly test each
-iteration before moving on to the next one.
+Great! Our game is just the kind of project `run` is good for: we need
+to quickly test each iteration before moving on to the next one.
# Processing a Guess
@@ -106,8 +106,8 @@ prelude, you’ll have to `use` it directly. There is also a second ‘prelude
[`io` prelude][ioprelude], which serves a similar function: you import it, and it
imports a number of useful, `io`-related things.
-[prelude]: ../std/prelude/index.html
-[ioprelude]: ../std/io/prelude/index.html
+[prelude]: ../../std/prelude/index.html
+[ioprelude]: ../../std/io/prelude/index.html
```rust,ignore
fn main() {
@@ -158,8 +158,8 @@ take a name on the left hand side of the assignment, it actually accepts a
to use for now:
```rust
-let foo = 5; // immutable.
-let mut bar = 5; // mutable
+let foo = 5; // `foo` is immutable.
+let mut bar = 5; // `bar` is mutable.
```
[immutable]: mutability.html
@@ -177,7 +177,7 @@ bound to: `String::new()`.
`String` is a string type, provided by the standard library. A
[`String`][string] is a growable, UTF-8 encoded bit of text.
-[string]: ../std/string/struct.String.html
+[string]: ../../std/string/struct.String.html
The `::new()` syntax uses `::` because this is an ‘associated function’ of
a particular type. That is to say, it’s associated with `String` itself,
@@ -209,7 +209,7 @@ have written this line as `std::io::stdin()`.
This particular function returns a handle to the standard input for your
terminal. More specifically, a [std::io::Stdin][iostdin].
-[iostdin]: ../std/io/struct.Stdin.html
+[iostdin]: ../../std/io/struct.Stdin.html
The next part will use this handle to get input from the user:
@@ -217,12 +217,12 @@ The next part will use this handle to get input from the user:
.read_line(&mut guess)
```
-Here, we call the [`read_line()`][read_line] method on our handle.
+Here, we call the [`read_line`] method on our handle.
[Methods][method] are like associated functions, but are only available on a
particular instance of a type, rather than the type itself. We’re also passing
one argument to `read_line()`: `&mut guess`.
-[read_line]: ../std/io/struct.Stdin.html#method.read_line
+[`read_line`]: ../../std/io/struct.Stdin.html#method.read_line
[method]: method-syntax.html
Remember how we bound `guess` above? We said it was mutable. However,
@@ -255,7 +255,7 @@ and other whitespace. This helps you split up long lines. We _could_ have
done:
```rust,ignore
- io::stdin().read_line(&mut guess).expect("failed to read line");
+ io::stdin().read_line(&mut guess).expect("Failed to read line");
```
But that gets hard to read. So we’ve split it up, two lines for two method
@@ -266,8 +266,8 @@ String` we pass it. But it also returns a value: in this case, an
standard library: a generic [`Result`][result], and then specific versions for
sub-libraries, like `io::Result`.
-[ioresult]: ../std/io/type.Result.html
-[result]: ../std/result/enum.Result.html
+[ioresult]: ../../std/io/type.Result.html
+[result]: ../../std/result/enum.Result.html
The purpose of these `Result` types is to encode error handling information.
Values of the `Result` type, like any type, have methods defined on them. In
@@ -276,19 +276,22 @@ it’s called on, and if it isn’t a successful one, [`panic!`][panic]s with a
message you passed it. A `panic!` like this will cause our program to crash,
displaying the message.
-[expect]: ../std/result/enum.Result.html#method.expect
+[expect]: ../../std/result/enum.Result.html#method.expect
[panic]: error-handling.html
-If we leave off calling this method, our program will compile, but
+If we do not call `expect()`, our program will compile, but
we’ll get a warning:
```bash
$ cargo build
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
-src/main.rs:10:5: 10:39 warning: unused result which must be used,
-#[warn(unused_must_use)] on by default
-src/main.rs:10 io::stdin().read_line(&mut guess);
- ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+warning: unused result which must be used, #[warn(unused_must_use)] on by default
+ --> src/main.rs:10:5
+ |
+10 | io::stdin().read_line(&mut guess);
+ | ^
+
+ Finished debug [unoptimized + debuginfo] target(s) in 0.42 secs
```
Rust warns us that we haven’t used the `Result` value. This warning comes from
@@ -324,6 +327,7 @@ Anyway, that’s the tour. We can run what we have with `cargo run`:
```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.44 secs
Running `target/debug/guessing_game`
Guess the number!
Please input your guess.
@@ -365,7 +369,6 @@ numbers. A bare number like above is actually shorthand for `^0.3.0`,
meaning "anything compatible with 0.3.0".
If we wanted to use only `0.3.0` exactly, we could say `rand="=0.3.0"`
(note the two equal signs).
-And if we wanted to use the latest version we could use `rand="*"`.
We could also use a range of versions.
[Cargo’s documentation][cargodoc] contains more details.
@@ -377,11 +380,12 @@ Now, without changing any of our code, let’s build our project:
```bash
$ cargo build
Updating registry `https://github.com/rust-lang/crates.io-index`
- Downloading rand v0.3.8
- Downloading libc v0.1.6
- Compiling libc v0.1.6
- Compiling rand v0.3.8
+ Downloading rand v0.3.14
+ Downloading libc v0.2.17
+ Compiling libc v0.2.17
+ Compiling rand v0.3.14
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
+ Finished debug [unoptimized + debuginfo] target(s) in 5.88 secs
```
(You may see different versions, of course.)
@@ -403,22 +407,24 @@ If we run `cargo build` again, we’ll get different output:
```bash
$ cargo build
+ Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
```
-That’s right, no output! Cargo knows that our project has been built, and that
+That’s right, nothing was done! Cargo knows that our project has been built, and that
all of its dependencies are built, and so there’s no reason to do all that
stuff. With nothing to do, it simply exits. If we open up `src/main.rs` again,
-make a trivial change, and then save it again, we’ll only see one line:
+make a trivial change, and then save it again, we’ll only see two lines:
```bash
$ cargo build
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.45 secs
```
So, we told Cargo we wanted any `0.3.x` version of `rand`, and so it fetched the latest
-version at the time this was written, `v0.3.8`. But what happens when next
-week, version `v0.3.9` comes out, with an important bugfix? While getting
-bugfixes is important, what if `0.3.9` contains a regression that breaks our
+version at the time this was written, `v0.3.14`. But what happens when next
+week, version `v0.3.15` comes out, with an important bugfix? While getting
+bugfixes is important, what if `0.3.15` contains a regression that breaks our
code?
The answer to this problem is the `Cargo.lock` file you’ll now find in your
@@ -427,11 +433,11 @@ figures out all of the versions that fit your criteria, and then writes them
to the `Cargo.lock` file. When you build your project in the future, Cargo
will see that the `Cargo.lock` file exists, and then use that specific version
rather than do all the work of figuring out versions again. This lets you
-have a repeatable build automatically. In other words, we’ll stay at `0.3.8`
+have a repeatable build automatically. In other words, we’ll stay at `0.3.14`
until we explicitly upgrade, and so will anyone who we share our code with,
thanks to the lock file.
-What about when we _do_ want to use `v0.3.9`? Cargo has another command,
+What about when we _do_ want to use `v0.3.15`? Cargo has another command,
`update`, which says ‘ignore the lock, figure out all the latest versions that
fit what we’ve specified. If that works, write those versions out to the lock
file’. But, by default, Cargo will only look for versions larger than `0.3.0`
@@ -467,7 +473,7 @@ fn main() {
let mut guess = String::new();
io::stdin().read_line(&mut guess)
- .expect("failed to read line");
+ .expect("Failed to read line");
println!("You guessed: {}", guess);
}
@@ -514,6 +520,7 @@ Try running our new program a few times:
```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.55 secs
Running `target/debug/guessing_game`
Guess the number!
The secret number is: 7
@@ -521,6 +528,7 @@ Please input your guess.
4
You guessed: 4
$ cargo run
+ Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/guessing_game`
Guess the number!
The secret number is: 83
@@ -555,7 +563,7 @@ fn main() {
let mut guess = String::new();
io::stdin().read_line(&mut guess)
- .expect("failed to read line");
+ .expect("Failed to read line");
println!("You guessed: {}", guess);
@@ -612,7 +620,7 @@ match guess.cmp(&secret_number) {
}
```
-[ordering]: ../std/cmp/enum.Ordering.html
+[ordering]: ../../std/cmp/enum.Ordering.html
If it’s `Less`, we print `Too small!`, if it’s `Greater`, `Too big!`, and if
`Equal`, `You win!`. `match` is really useful, and is used often in Rust.
@@ -622,15 +630,20 @@ I did mention that this won’t quite compile yet, though. Let’s try it:
```bash
$ cargo build
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
-src/main.rs:28:21: 28:35 error: mismatched types:
- expected `&collections::string::String`,
- found `&_`
-(expected struct `collections::string::String`,
- found integral variable) [E0308]
-src/main.rs:28 match guess.cmp(&secret_number) {
- ^~~~~~~~~~~~~~
+error[E0308]: mismatched types
+ --> src/main.rs:23:21
+ |
+23 | match guess.cmp(&secret_number) {
+ | ^^^^^^^^^^^^^^ expected struct `std::string::String`, found integral variable
+ |
+ = note: expected type `&std::string::String`
+ = note: found type `&{integer}`
+
error: aborting due to previous error
-Could not compile `guessing_game`.
+
+error: Could not compile `guessing_game`.
+
+To learn more, run the command again with --verbose.
```
Whew! This is a big error. The core of it is that we have ‘mismatched types’.
@@ -665,7 +678,7 @@ fn main() {
let mut guess = String::new();
io::stdin().read_line(&mut guess)
- .expect("failed to read line");
+ .expect("Failed to read line");
let guess: u32 = guess.trim().parse()
.expect("Please type a number!");
@@ -713,7 +726,7 @@ exact type of number we want. Hence, `let guess: u32`. The colon (`:`) after
thirty-two bit integer. Rust has [a number of built-in number types][number],
but we’ve chosen `u32`. It’s a good default choice for a small positive number.
-[parse]: ../std/primitive.str.html#method.parse
+[parse]: ../../std/primitive.str.html#method.parse
[number]: primitive-types.html#numeric-types
Just like `read_line()`, our call to `parse()` could cause an error. What if
@@ -726,6 +739,7 @@ Let’s try our program out!
```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.57 secs
Running `target/guessing_game`
Guess the number!
The secret number is: 58
@@ -766,7 +780,7 @@ fn main() {
let mut guess = String::new();
io::stdin().read_line(&mut guess)
- .expect("failed to read line");
+ .expect("Failed to read line");
let guess: u32 = guess.trim().parse()
.expect("Please type a number!");
@@ -789,6 +803,7 @@ and quit. Observe:
```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.58 secs
Running `target/guessing_game`
Guess the number!
The secret number is: 59
@@ -832,7 +847,7 @@ fn main() {
let mut guess = String::new();
io::stdin().read_line(&mut guess)
- .expect("failed to read line");
+ .expect("Failed to read line");
let guess: u32 = guess.trim().parse()
.expect("Please type a number!");
@@ -877,7 +892,7 @@ fn main() {
let mut guess = String::new();
io::stdin().read_line(&mut guess)
- .expect("failed to read line");
+ .expect("Failed to read line");
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
@@ -923,6 +938,7 @@ Now we should be good! Let’s try:
```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.57 secs
Running `target/guessing_game`
Guess the number!
The secret number is: 61
@@ -965,7 +981,7 @@ fn main() {
let mut guess = String::new();
io::stdin().read_line(&mut guess)
- .expect("failed to read line");
+ .expect("Failed to read line");
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
diff --git a/trpl/if-let.md b/trpl-1st-edition/if-let.md
similarity index 86%
rename from trpl/if-let.md
rename to trpl-1st-edition/if-let.md
index 9afe5fa..9eeac3d 100644
--- a/trpl/if-let.md
+++ b/trpl-1st-edition/if-let.md
@@ -1,7 +1,8 @@
-% if let
+# if let
-`if let` allows you to combine `if` and `let` together to reduce the overhead
-of certain kinds of pattern matches.
+`if let` permits [patterns][patterns] matching within the condition of an [if][if] statement.
+This allows us to reduce the overhead of certain kinds of [pattern][patterns] matches
+and express them in a more convenient way.
For example, let’s say we have some sort of `Option`. We want to call a function
on it if it’s `Some`, but do nothing if it’s `None`. That looks like this:
@@ -80,3 +81,4 @@ while let Some(x) = v.pop() {
```
[patterns]: patterns.html
+[if]: if.html
diff --git a/trpl/if.md b/trpl-1st-edition/if.md
similarity index 99%
rename from trpl/if.md
rename to trpl-1st-edition/if.md
index 52d0dd8..d745037 100644
--- a/trpl/if.md
+++ b/trpl-1st-edition/if.md
@@ -1,4 +1,4 @@
-% if
+# if
Rust’s take on `if` is not particularly complex, but it’s much more like the
`if` you’ll find in a dynamically typed language than in a more traditional
diff --git a/trpl/iterators.md b/trpl-1st-edition/iterators.md
similarity index 95%
rename from trpl/iterators.md
rename to trpl-1st-edition/iterators.md
index c174d2d..548816a 100644
--- a/trpl/iterators.md
+++ b/trpl-1st-edition/iterators.md
@@ -1,4 +1,4 @@
-% Iterators
+# Iterators
Let's talk about loops.
@@ -14,10 +14,9 @@ Now that you know more Rust, we can talk in detail about how this works.
Ranges (the `0..10`) are 'iterators'. An iterator is something that we can
call the `.next()` method on repeatedly, and it gives us a sequence of things.
-(By the way, a range with two dots like `0..10` is inclusive on the left (so it
+A range with two dots like `0..10` is inclusive on the left (so it
starts at 0) and exclusive on the right (so it ends at 9). A mathematician
-would write "[0, 10)". To get a range that goes all the way up to 10 you can
-write `0...10`.)
+would write "[0, 10)".
Like this:
@@ -135,10 +134,10 @@ Here's the version that does compile:
let one_to_one_hundred = (1..101).collect::>();
```
-If you remember, the `::<>` syntax allows us to give a type hint,
-and so we tell it that we want a vector of integers. You don't always
-need to use the whole type, though. Using a `_` will let you provide
-a partial hint:
+If you remember, the [`::<>` syntax](generics.html#resolving-ambiguities)
+allows us to give a type hint that tells the compiler we want a vector of
+integers. You don't always need to use the whole type, though. Using a `_`
+will let you provide a partial hint:
```rust
let one_to_one_hundred = (1..101).collect::>();
@@ -341,4 +340,4 @@ can help you with. There are a number of really useful iterators, and you can
write your own as well. Iterators provide a safe, efficient way to manipulate
all kinds of lists. They're a little unusual at first, but if you play with
them, you'll get hooked. For a full list of the different iterators and
-consumers, check out the [iterator module documentation](../std/iter/index.html).
+consumers, check out the [iterator module documentation](../../std/iter/index.html).
diff --git a/trpl/lifetimes.md b/trpl-1st-edition/lifetimes.md
similarity index 68%
rename from trpl/lifetimes.md
rename to trpl-1st-edition/lifetimes.md
index f7d9c94..042d9af 100644
--- a/trpl/lifetimes.md
+++ b/trpl-1st-edition/lifetimes.md
@@ -1,4 +1,4 @@
-% Lifetimes
+# Lifetimes
This is the last of three sections presenting Rust’s ownership system. This is one of
Rust’s most distinct and compelling features, with which Rust developers should
@@ -50,29 +50,94 @@ complicated. For example, imagine this set of operations:
4. You decide to use the resource.
Uh oh! Your reference is pointing to an invalid resource. This is called a
-dangling pointer or ‘use after free’, when the resource is memory.
+dangling pointer or ‘use after free’, when the resource is memory. A small
+example of such a situation would be:
+
+```rust,compile_fail
+let r; // Introduce reference: `r`.
+{
+ let i = 1; // Introduce scoped value: `i`.
+ r = &i; // Store reference of `i` in `r`.
+} // `i` goes out of scope and is dropped.
+
+println!("{}", r); // `r` still refers to `i`.
+```
To fix this, we have to make sure that step four never happens after step
-three. The ownership system in Rust does this through a concept called
-lifetimes, which describe the scope that a reference is valid for.
+three. In the small example above the Rust compiler is able to report the issue
+as it can see the lifetimes of the various values in the function.
-When we have a function that takes an argument by reference, we can be
-implicit or explicit about the lifetime of the reference:
+When we have a function that takes arguments by reference the situation becomes
+more complex. Consider the following example:
-```rust
-// implicit
-fn foo(x: &i32) {
+```rust,compile_fail,E0106
+fn skip_prefix(line: &str, prefix: &str) -> &str {
+ // ...
+# line
}
-// explicit
-fn bar<'a>(x: &'a i32) {
+let line = "lang:en=Hello World!";
+let lang = "en";
+
+let v;
+{
+ let p = format!("lang:{}=", lang); // -+ `p` comes into scope.
+ v = skip_prefix(line, p.as_str()); // |
+} // -+ `p` goes out of scope.
+println!("{}", v);
+```
+
+Here we have a function `skip_prefix` which takes two `&str` references
+as parameters and returns a single `&str` reference. We call it
+by passing in references to `line` and `p`: Two variables with different
+lifetimes. Now the safety of the `println!`-line depends on whether the
+reference returned by `skip_prefix` function references the still living
+`line` or the already dropped `p` string.
+
+Because of the above ambiguity, Rust will refuse to compile the example
+code. To get it to compile we need to tell the compiler more about the
+lifetimes of the references. This can be done by making the lifetimes
+explicit in the function declaration:
+
+```rust
+fn skip_prefix<'a, 'b>(line: &'a str, prefix: &'b str) -> &'a str {
+ // ...
+# line
}
```
+Let's examine the changes without going too deep into the syntax for now -
+we'll get to that later. The first change was adding the `<'a, 'b>` after the
+method name. This introduces two lifetime parameters: `'a` and `'b`. Next, each
+reference in the function signature was associated with one of the lifetime
+parameters by adding the lifetime name after the `&`. This tells the compiler
+how the lifetimes between different references are related.
+
+As a result the compiler is now able to deduce that the return value of
+`skip_prefix` has the same lifetime as the `line` parameter, which makes the `v`
+reference safe to use even after the `p` goes out of scope in the original
+example.
+
+In addition to the compiler being able to validate the usage of `skip_prefix`
+return value, it can also ensure that the implementation follows the contract
+established by the function declaration. This is useful especially when you are
+implementing traits that are introduced [later in the book][traits].
+
+**Note** It's important to understand that lifetime annotations are
+_descriptive_, not _prescriptive_. This means that how long a reference is valid
+is determined by the code, not by the annotations. The annotations, however,
+give information about lifetimes to the compiler that uses them to check the
+validity of references. The compiler can do so without annotations in simple
+cases, but needs the programmer's support in complex scenarios.
+
+[traits]: traits.html
+
+# Syntax
+
The `'a` reads ‘the lifetime a’. Technically, every reference has some lifetime
associated with it, but the compiler lets you elide (i.e. omit, see
-["Lifetime Elision"][lifetime-elision] below) them in common cases.
-Before we get to that, though, let’s break the explicit example down:
+["Lifetime Elision"][lifetime-elision] below) them in common cases. Before we
+get to that, though, let’s look at a short example with explicit lifetimes:
[lifetime-elision]: #lifetime-elision
@@ -90,7 +155,8 @@ focus on the lifetimes aspect.
[generics]: generics.html
We use `<>` to declare our lifetimes. This says that `bar` has one lifetime,
-`'a`. If we had two reference parameters, it would look like this:
+`'a`. If we had two reference parameters with different lifetimes, it would
+look like this:
```rust,ignore
@@ -125,7 +191,7 @@ struct Foo<'a> {
}
fn main() {
- let y = &5; // this is the same as `let _y = 5; let y = &_y;`
+ let y = &5; // This is the same as `let _y = 5; let y = &_y;`.
let f = Foo { x: y };
println!("{}", f.x);
@@ -167,7 +233,7 @@ impl<'a> Foo<'a> {
}
fn main() {
- let y = &5; // this is the same as `let _y = 5; let y = &_y;`
+ let y = &5; // This is the same as `let _y = 5; let y = &_y;`.
let f = Foo { x: y };
println!("x is: {}", f.x());
@@ -208,11 +274,11 @@ valid for. For example:
```rust
fn main() {
- let y = &5; // -+ y goes into scope
+ let y = &5; // -+ `y` comes into scope.
// |
- // stuff // |
+ // Stuff... // |
// |
-} // -+ y goes out of scope
+} // -+ `y` goes out of scope.
```
Adding in our `Foo`:
@@ -223,11 +289,12 @@ struct Foo<'a> {
}
fn main() {
- let y = &5; // -+ y goes into scope
- let f = Foo { x: y }; // -+ f goes into scope
- // stuff // |
+ let y = &5; // -+ `y` comes into scope.
+ let f = Foo { x: y }; // -+ `f` comes into scope.
+ // |
+ // Stuff... // |
// |
-} // -+ f and y go out of scope
+} // -+ `f` and `y` go out of scope.
```
Our `f` lives within the scope of `y`, so everything works. What if it didn’t?
@@ -239,16 +306,16 @@ struct Foo<'a> {
}
fn main() {
- let x; // -+ x goes into scope
+ let x; // -+ `x` comes into scope.
// |
{ // |
- let y = &5; // ---+ y goes into scope
- let f = Foo { x: y }; // ---+ f goes into scope
- x = &f.x; // | | error here
- } // ---+ f and y go out of scope
+ let y = &5; // ---+ `y` comes into scope.
+ let f = Foo { x: y }; // ---+ `f` comes into scope.
+ x = &f.x; // | | This causes an error.
+ } // ---+ `f` and y go out of scope.
// |
println!("{}", x); // |
-} // -+ x goes out of scope
+} // -+ `x` goes out of scope.
```
Whew! As you can see here, the scopes of `f` and `y` are smaller than the scope
@@ -282,10 +349,10 @@ to it.
## Lifetime Elision
-Rust supports powerful local type inference in the bodies of functions but not in their item signatures.
-It's forbidden to allow reasoning about types based on the item signature alone.
+Rust supports powerful local type inference in the bodies of functions, but it
+deliberately does not perform any reasoning about types for item signatures.
However, for ergonomic reasons, a very restricted secondary inference algorithm called
-“lifetime elision” does apply when judging lifetimes. Lifetime elision is concerned solely to infer
+“lifetime elision” does apply when judging lifetimes. Lifetime elision is concerned solely with inferring
lifetime parameters using three easily memorizable and unambiguous rules. This means lifetime elision
acts as a shorthand for writing an item signature, while not hiding
away the actual types involved as full local inference would if applied to it.
diff --git a/trpl/loops.md b/trpl-1st-edition/loops.md
similarity index 82%
rename from trpl/loops.md
rename to trpl-1st-edition/loops.md
index e4cb861..20e6eee 100644
--- a/trpl/loops.md
+++ b/trpl-1st-edition/loops.md
@@ -1,4 +1,4 @@
-% Loops
+# Loops
Rust currently provides three approaches to performing some kind of iterative activity. They are: `loop`, `while` and `for`. Each approach has its own set of uses.
@@ -81,14 +81,14 @@ for var in expression {
```
The expression is an item that can be converted into an [iterator] using
-[`IntoIterator`]. The iterator gives back a series of elements. Each element is
-one iteration of the loop. That value is then bound to the name `var`, which is
+[`IntoIterator`]. The iterator gives back a series of elements, one element per
+iteration of the loop. That value is then bound to the name `var`, which is
valid for the loop body. Once the body is over, the next value is fetched from
the iterator, and we loop another time. When there are no more values, the `for`
loop is over.
[iterator]: iterators.html
-[`IntoIterator`]: ../std/iter/trait.IntoIterator.html
+[`IntoIterator`]: ../../std/iter/trait.IntoIterator.html
In our example, `0..10` is an expression that takes a start and an end position,
and gives an iterator over those values. The upper bound is exclusive, though,
@@ -100,7 +100,8 @@ developers.
### Enumerate
-When you need to keep track of how many times you already looped, you can use the `.enumerate()` function.
+When you need to keep track of how many times you have already looped, you can
+use the `.enumerate()` function.
#### On ranges:
@@ -193,17 +194,21 @@ for x in 0..10 {
You may also encounter situations where you have nested loops and need to
specify which one your `break` or `continue` statement is for. Like most
-other languages, by default a `break` or `continue` will apply to innermost
-loop. In a situation where you would like to `break` or `continue` for one
+other languages, Rust's `break` or `continue` apply to the innermost loop.
+In a situation where you would like to `break` or `continue` for one
of the outer loops, you can use labels to specify which loop the `break` or
- `continue` statement applies to. This will only print when both `x` and `y` are
- odd:
+`continue` statement applies to.
+
+In the example below, we `continue` to the next iteration of `outer` loop
+when `x` is even, while we `continue` to the next iteration of `inner`
+loop when y is even. So it will execute the `println!` when both `x` and
+`y` are odd.
```rust
'outer: for x in 0..10 {
'inner: for y in 0..10 {
- if x % 2 == 0 { continue 'outer; } // continues the loop over x
- if y % 2 == 0 { continue 'inner; } // continues the loop over y
+ if x % 2 == 0 { continue 'outer; } // Continues the loop over `x`.
+ if y % 2 == 0 { continue 'inner; } // Continues the loop over `y`.
println!("x: {}, y: {}", x, y);
}
}
diff --git a/trpl/macros.md b/trpl-1st-edition/macros.md
similarity index 94%
rename from trpl/macros.md
rename to trpl-1st-edition/macros.md
index 9f40829..c2b9960 100644
--- a/trpl/macros.md
+++ b/trpl-1st-edition/macros.md
@@ -1,4 +1,4 @@
-% Macros
+# Macros
By now you’ve learned about many of the tools Rust provides for abstracting and
reusing code. These units of code reuse have a rich semantic structure. For
@@ -58,6 +58,7 @@ We can implement this shorthand, using a macro: [^actual]
[^actual]: The actual definition of `vec!` in libcollections differs from the
one presented here, for reasons of efficiency and reusability.
+
```rust
macro_rules! vec {
@@ -101,7 +102,7 @@ trees, at compile time. The semicolon is optional on the last (here, only)
case. The "pattern" on the left-hand side of `=>` is known as a ‘matcher’.
These have [their own little grammar] within the language.
-[their own little grammar]: ../reference.html#macros
+[their own little grammar]: ../../reference/macros.html
The matcher `$x:expr` will match any Rust expression, binding that syntax tree
to the ‘metavariable’ `$x`. The identifier `expr` is a ‘fragment specifier’;
@@ -261,36 +262,34 @@ The metavariable `$x` is parsed as a single expression node, and keeps its
place in the syntax tree even after substitution.
Another common problem in macro systems is ‘variable capture’. Here’s a C
-macro, using [a GNU C extension] to emulate Rust’s expression blocks.
-
-[a GNU C extension]: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
+macro using a block with multiple statements.
```text
-#define LOG(msg) ({ \
+#define LOG(msg) do { \
int state = get_log_state(); \
if (state > 0) { \
printf("log(%d): %s\n", state, msg); \
} \
-})
+} while (0)
```
Here’s a simple use case that goes terribly wrong:
```text
const char *state = "reticulating splines";
-LOG(state)
+LOG(state);
```
This expands to
```text
const char *state = "reticulating splines";
-{
+do {
int state = get_log_state();
if (state > 0) {
printf("log(%d): %s\n", state, state);
}
-}
+} while (0);
```
The second variable named `state` shadows the first one. This is a problem
@@ -365,7 +364,7 @@ fn main() {
}
```
-[items]: ../reference.html#items
+[items]: ../../reference/items.html
# Recursive macros
@@ -492,7 +491,7 @@ be forced to choose between parsing `$i` and parsing `$e`. Changing the
invocation syntax to put a distinctive token in front can solve the problem. In
this case, you can write `$(I $i:ident)* E $e:expr`.
-[item]: ../reference.html#items
+[item]: ../../reference/items.html
# Scoping and macro import/export
@@ -533,33 +532,33 @@ An example:
```rust
macro_rules! m1 { () => (()) }
-// visible here: m1
+// Visible here: `m1`.
mod foo {
- // visible here: m1
+ // Visible here: `m1`.
#[macro_export]
macro_rules! m2 { () => (()) }
- // visible here: m1, m2
+ // Visible here: `m1`, `m2`.
}
-// visible here: m1
+// Visible here: `m1`.
macro_rules! m3 { () => (()) }
-// visible here: m1, m3
+// Visible here: `m1`, `m3`.
#[macro_use]
mod bar {
- // visible here: m1, m3
+ // Visible here: `m1`, `m3`.
macro_rules! m4 { () => (()) }
- // visible here: m1, m3, m4
+ // Visible here: `m1`, `m3`, `m4`.
}
-// visible here: m1, m3, m4
+// Visible here: `m1`, `m3`, `m4`.
# fn main() { }
```
@@ -567,7 +566,7 @@ When this library is loaded with `#[macro_use] extern crate`, only `m2` will
be imported.
The Rust Reference has a [listing of macro-related
-attributes](../reference.html#macro-related-attributes).
+attributes](../../reference/attributes.html#macro-related-attributes).
# The variable `$crate`
@@ -644,7 +643,7 @@ macro_rules! bct {
(1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
=> (bct!($($ps),*, 1, $p ; $($ds),*));
- // halt on empty data string
+ // Halt on empty data string:
( $($ps:tt),* ; )
=> (());
}
@@ -662,7 +661,7 @@ Here are some common macros you’ll see in Rust code.
This macro causes the current thread to panic. You can give it a message
to panic with:
-```rust,no_run
+```rust,should_panic
panic!("oh no!");
```
@@ -688,13 +687,13 @@ These two macros are used in tests. `assert!` takes a boolean. `assert_eq!`
takes two values and checks them for equality. `true` passes, `false` `panic!`s.
Like this:
-```rust,no_run
+```rust,should_panic
// A-ok!
assert!(true);
assert_eq!(5, 3 + 2);
-// nope :(
+// Nope :(
assert!(5 < 3);
assert_eq!(5, 3);
@@ -763,12 +762,3 @@ to typecheck, and don’t want to worry about writing out the body of the
function. One example of this situation is implementing a trait with multiple
required methods, where you want to tackle one at a time. Define the others
as `unimplemented!` until you’re ready to write them.
-
-# Procedural macros
-
-If Rust’s macro system can’t do what you need, you may want to write a
-[compiler plugin](compiler-plugins.html) instead. Compared to `macro_rules!`
-macros, this is significantly more work, the interfaces are much less stable,
-and bugs can be much harder to track down. In exchange you get the
-flexibility of running arbitrary Rust code within the compiler. Syntax
-extension plugins are sometimes called ‘procedural macros’ for this reason.
diff --git a/trpl/match.md b/trpl-1st-edition/match.md
similarity index 97%
rename from trpl/match.md
rename to trpl-1st-edition/match.md
index d01a200..b1e26a9 100644
--- a/trpl/match.md
+++ b/trpl-1st-edition/match.md
@@ -1,4 +1,4 @@
-% Match
+# Match
Often, a simple [`if`][if]/`else` isn’t enough, because you have more than two
possible options. Also, conditions can get quite complex. Rust
@@ -82,7 +82,7 @@ fn process_message(msg: Message) {
match msg {
Message::Quit => quit(),
Message::ChangeColor(r, g, b) => change_color(r, g, b),
- Message::Move { x: x, y: y } => move_cursor(x, y),
+ Message::Move { x, y: new_name_for_y } => move_cursor(x, new_name_for_y),
Message::Write(s) => println!("{}", s),
};
}
diff --git a/trpl/method-syntax.md b/trpl-1st-edition/method-syntax.md
similarity index 99%
rename from trpl/method-syntax.md
rename to trpl-1st-edition/method-syntax.md
index b253266..0404a5c 100644
--- a/trpl/method-syntax.md
+++ b/trpl-1st-edition/method-syntax.md
@@ -1,4 +1,4 @@
-% Method Syntax
+# Method Syntax
Functions are great, but if you want to call a bunch of them on some data, it
can be awkward. Consider this code:
diff --git a/trpl/mutability.md b/trpl-1st-edition/mutability.md
similarity index 94%
rename from trpl/mutability.md
rename to trpl-1st-edition/mutability.md
index a0a49d5..4d53a5a 100644
--- a/trpl/mutability.md
+++ b/trpl-1st-edition/mutability.md
@@ -1,4 +1,4 @@
-% Mutability
+# Mutability
Mutability, the ability to change something, works a bit differently in Rust
than in other languages. The first aspect of mutability is its non-default
@@ -6,7 +6,7 @@ status:
```rust,ignore
let x = 5;
-x = 6; // error!
+x = 6; // Error!
```
We can introduce mutability with the `mut` keyword:
@@ -14,7 +14,7 @@ We can introduce mutability with the `mut` keyword:
```rust
let mut x = 5;
-x = 6; // no problem!
+x = 6; // No problem!
```
This is a mutable [variable binding][vb]. When a binding is mutable, it means
@@ -72,7 +72,7 @@ let x = Arc::new(5);
let y = x.clone();
```
-[arc]: ../std/sync/struct.Arc.html
+[arc]: ../../std/sync/struct.Arc.html
When we call `clone()`, the `Arc` needs to update the reference count. Yet
we’ve not used any `mut`s here, `x` is an immutable binding, and we didn’t take
@@ -107,7 +107,7 @@ let x = RefCell::new(42);
let y = x.borrow_mut();
```
-[stdcell]: ../std/cell/index.html
+[stdcell]: ../../std/cell/index.html
RefCell hands out `&mut` references to what’s inside of it with the
`borrow_mut()` method. Isn’t that dangerous? What if we do:
@@ -136,7 +136,7 @@ some fields mutable and some immutable:
```rust,ignore
struct Point {
x: i32,
- mut y: i32, // nope
+ mut y: i32, // Nope.
}
```
@@ -154,7 +154,7 @@ a.x = 10;
let b = Point { x: 5, y: 6};
-b.x = 10; // error: cannot assign to immutable field `b.x`
+b.x = 10; // Error: cannot assign to immutable field `b.x`.
```
[struct]: structs.html
@@ -176,6 +176,6 @@ point.y.set(7);
println!("y: {:?}", point.y);
```
-[cell]: ../std/cell/struct.Cell.html
+[cell]: ../../std/cell/struct.Cell.html
This will print `y: Cell { value: 7 }`. We’ve successfully updated `y`.
diff --git a/trpl/operators-and-overloading.md b/trpl-1st-edition/operators-and-overloading.md
similarity index 95%
rename from trpl/operators-and-overloading.md
rename to trpl-1st-edition/operators-and-overloading.md
index 424e2cd..ed202f3 100644
--- a/trpl/operators-and-overloading.md
+++ b/trpl-1st-edition/operators-and-overloading.md
@@ -1,4 +1,4 @@
-% Operators and Overloading
+# Operators and Overloading
Rust allows for a limited form of operator overloading. There are certain
operators that are able to be overloaded. To support a particular operator
@@ -41,7 +41,7 @@ There are a number of operators that can be overloaded this way, and all of
their associated traits live in the [`std::ops`][stdops] module. Check out its
documentation for the full list.
-[stdops]: ../std/ops/index.html
+[stdops]: ../../std/ops/index.html
Implementing these traits follows a pattern. Let’s look at [`Add`][add] in more
detail:
@@ -56,7 +56,7 @@ pub trait Add {
# }
```
-[add]: ../std/ops/trait.Add.html
+[add]: ../../std/ops/trait.Add.html
There’s three types in total involved here: the type you `impl Add` for, `RHS`,
which defaults to `Self`, and `Output`. For an expression `let z = x + y`, `x`
@@ -69,7 +69,7 @@ impl Add for Point {
type Output = f64;
fn add(self, rhs: i32) -> f64 {
- // add an i32 to a Point and get an f64
+ // Add an i32 to a Point and get an f64.
# 1.0
}
}
diff --git a/trpl/ownership.md b/trpl-1st-edition/ownership.md
similarity index 96%
rename from trpl/ownership.md
rename to trpl-1st-edition/ownership.md
index 23ca21b..21ebd63 100644
--- a/trpl/ownership.md
+++ b/trpl-1st-edition/ownership.md
@@ -1,4 +1,4 @@
-% Ownership
+# Ownership
This is the first of three sections presenting Rust’s ownership system. This is one of
Rust’s most distinct and compelling features, with which Rust developers should
@@ -57,13 +57,13 @@ of scope at the end of `foo()`, Rust will clean up everything related to the
vector, even the heap-allocated memory. This happens deterministically, at the
end of the scope.
-We'll cover [vectors] in detail later in this chapter; we only use them
+We covered [vectors] in the previous chapter; we use them
here as an example of a type that allocates space on the heap at runtime. They
behave like [arrays], except their size may change by `push()`ing more
elements onto them.
Vectors have a [generic type][generics] `Vec`, so in this example `v` will have type
-`Vec`. We'll cover generics in detail later in this chapter.
+`Vec`. We'll cover [generics] in detail in a later chapter.
[arrays]: primitive-types.html#arrays
[vectors]: vectors.html
@@ -107,7 +107,7 @@ try to use something after we’ve passed it as an argument:
```rust,ignore
fn take(v: Vec) {
- // what happens here isn’t important.
+ // What happens here isn’t important.
}
let v = vec![1, 2, 3];
@@ -264,9 +264,9 @@ Of course, if we had to hand ownership back with every function we wrote:
```rust
fn foo(v: Vec) -> Vec {
- // do stuff with v
+ // Do stuff with `v`.
- // hand back ownership
+ // Hand back ownership.
v
}
```
@@ -275,9 +275,9 @@ This would get very tedious. It gets worse the more things we want to take owner
```rust
fn foo(v1: Vec, v2: Vec) -> (Vec, Vec, i32) {
- // do stuff with v1 and v2
+ // Do stuff with `v1` and `v2`.
- // hand back ownership, and the result of our function
+ // Hand back ownership, and the result of our function.
(v1, v2, 42)
}
diff --git a/trpl/patterns.md b/trpl-1st-edition/patterns.md
similarity index 93%
rename from trpl/patterns.md
rename to trpl-1st-edition/patterns.md
index 910b137..1983927 100644
--- a/trpl/patterns.md
+++ b/trpl-1st-edition/patterns.md
@@ -1,4 +1,4 @@
-% Patterns
+# Patterns
Patterns are quite common in Rust. We use them in [variable
bindings][bindings], [match expressions][match], and other places, too. Let’s go
@@ -23,6 +23,33 @@ match x {
This prints `one`.
+It's possible to create a binding for the value in the any case:
+
+```rust
+let x = 1;
+
+match x {
+ y => println!("x: {} y: {}", x, y),
+}
+```
+
+This prints:
+
+```text
+x: 1 y: 1
+```
+
+Note it is an error to have both a catch-all `_` and a catch-all binding in the same match block:
+
+```rust
+let x = 1;
+
+match x {
+ y => println!("x: {} y: {}", x, y),
+ _ => println!("anything"), // this causes an error as it is unreachable
+}
+```
+
There’s one pitfall with patterns: like anything that introduces a new binding,
they introduce shadowing. For example:
@@ -163,7 +190,7 @@ ignore parts of a larger structure:
```rust
fn coordinate() -> (i32, i32, i32) {
- // generate and return some sort of triple tuple
+ // Generate and return some sort of triple tuple.
# (1, 2, 3)
}
@@ -182,7 +209,7 @@ let tuple: (u32, String) = (5, String::from("five"));
// Here, tuple is moved, because the String moved:
let (x, _s) = tuple;
-// The next line would give "error: use of partially moved value: `tuple`"
+// The next line would give "error: use of partially moved value: `tuple`".
// println!("Tuple is: {:?}", tuple);
// However,
diff --git a/trpl/primitive-types.md b/trpl-1st-edition/primitive-types.md
similarity index 89%
rename from trpl/primitive-types.md
rename to trpl-1st-edition/primitive-types.md
index ea0bdf2..93220a2 100644
--- a/trpl/primitive-types.md
+++ b/trpl-1st-edition/primitive-types.md
@@ -1,4 +1,4 @@
-% Primitive Types
+# Primitive Types
The Rust language has a number of types that are considered ‘primitive’. This
means that they’re built-in to the language. Rust is structured in such a way
@@ -22,7 +22,7 @@ A common use of booleans is in [`if` conditionals][if].
You can find more documentation for `bool`s [in the standard library
documentation][bool].
-[bool]: ../std/primitive.bool.html
+[bool]: ../../std/primitive.bool.html
# `char`
@@ -40,7 +40,7 @@ but four.
You can find more documentation for `char`s [in the standard library
documentation][char].
-[char]: ../std/primitive.char.html
+[char]: ../../std/primitive.char.html
# Numeric types
@@ -54,26 +54,26 @@ bigger numbers.
If a number literal has nothing to cause its type to be inferred, it defaults:
```rust
-let x = 42; // x has type i32
+let x = 42; // `x` has type `i32`.
-let y = 1.0; // y has type f64
+let y = 1.0; // `y` has type `f64`.
```
Here’s a list of the different numeric types, with links to their documentation
in the standard library:
-* [i8](../std/primitive.i8.html)
-* [i16](../std/primitive.i16.html)
-* [i32](../std/primitive.i32.html)
-* [i64](../std/primitive.i64.html)
-* [u8](../std/primitive.u8.html)
-* [u16](../std/primitive.u16.html)
-* [u32](../std/primitive.u32.html)
-* [u64](../std/primitive.u64.html)
-* [isize](../std/primitive.isize.html)
-* [usize](../std/primitive.usize.html)
-* [f32](../std/primitive.f32.html)
-* [f64](../std/primitive.f64.html)
+* [i8](../../std/primitive.i8.html)
+* [i16](../../std/primitive.i16.html)
+* [i32](../../std/primitive.i32.html)
+* [i64](../../std/primitive.i64.html)
+* [u8](../../std/primitive.u8.html)
+* [u16](../../std/primitive.u16.html)
+* [u32](../../std/primitive.u32.html)
+* [u64](../../std/primitive.u64.html)
+* [isize](../../std/primitive.isize.html)
+* [usize](../../std/primitive.usize.html)
+* [f32](../../std/primitive.f32.html)
+* [f64](../../std/primitive.f64.html)
Let’s go over them by category:
@@ -155,7 +155,7 @@ languages.
You can find more documentation for `array`s [in the standard library
documentation][array].
-[array]: ../std/primitive.array.html
+[array]: ../../std/primitive.array.html
# Slices
@@ -177,8 +177,8 @@ length of the slice:
```rust
let a = [0, 1, 2, 3, 4];
-let complete = &a[..]; // A slice containing all of the elements in a
-let middle = &a[1..4]; // A slice of a: only the elements 1, 2, and 3
+let complete = &a[..]; // A slice containing all of the elements in `a`.
+let middle = &a[1..4]; // A slice of `a`: only the elements `1`, `2`, and `3`.
```
Slices have type `&[T]`. We’ll talk about that `T` when we cover
@@ -189,7 +189,7 @@ Slices have type `&[T]`. We’ll talk about that `T` when we cover
You can find more documentation for slices [in the standard library
documentation][slice].
-[slice]: ../std/primitive.slice.html
+[slice]: ../../std/primitive.slice.html
# `str`
@@ -205,7 +205,7 @@ reference, like `&str`. We'll elaborate further when we cover
You can find more documentation for `str` [in the standard library
documentation][str].
-[str]: ../std/primitive.str.html
+[str]: ../../std/primitive.str.html
# Tuples
@@ -264,8 +264,8 @@ You can disambiguate a single-element tuple from a value in parentheses with a
comma:
```rust
-(0,); // single-element tuple
-(0); // zero in parentheses
+(0,); // A single-element tuple.
+(0); // A zero in parentheses.
```
## Tuple Indexing
@@ -289,7 +289,7 @@ Like array indexing, it starts at zero, but unlike array indexing, it uses a
You can find more documentation for tuples [in the standard library
documentation][tuple].
-[tuple]: ../std/primitive.tuple.html
+[tuple]: ../../std/primitive.tuple.html
# Functions
diff --git a/trpl-1st-edition/procedural-macros.md b/trpl-1st-edition/procedural-macros.md
new file mode 100644
index 0000000..c290279
--- /dev/null
+++ b/trpl-1st-edition/procedural-macros.md
@@ -0,0 +1,286 @@
+# Procedural Macros (and custom Derive)
+
+As you've seen throughout the rest of the book, Rust provides a mechanism
+called "derive" that lets you implement traits easily. For example,
+
+```rust
+#[derive(Debug)]
+struct Point {
+ x: i32,
+ y: i32,
+}
+```
+
+is a lot simpler than
+
+```rust
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+use std::fmt;
+
+impl fmt::Debug for Point {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "Point {{ x: {}, y: {} }}", self.x, self.y)
+ }
+}
+```
+
+Rust includes several traits that you can derive, but it also lets you define
+your own. We can accomplish this task through a feature of Rust called
+"procedural macros." Eventually, procedural macros will allow for all sorts of
+advanced metaprogramming in Rust, but today, they're only for custom derive.
+
+Let's build a very simple trait, and derive it with custom derive.
+
+## Hello World
+
+So the first thing we need to do is start a new crate for our project.
+
+```bash
+$ cargo new --bin hello-world
+```
+
+All we want is to be able to call `hello_world()` on a derived type. Something
+like this:
+
+```rust,ignore
+#[derive(HelloWorld)]
+struct Pancakes;
+
+fn main() {
+ Pancakes::hello_world();
+}
+```
+
+With some kind of nice output, like `Hello, World! My name is Pancakes.`.
+
+Let's go ahead and write up what we think our macro will look like from a user
+perspective. In `src/main.rs` we write:
+
+```rust,ignore
+#[macro_use]
+extern crate hello_world_derive;
+
+trait HelloWorld {
+ fn hello_world();
+}
+
+#[derive(HelloWorld)]
+struct FrenchToast;
+
+#[derive(HelloWorld)]
+struct Waffles;
+
+fn main() {
+ FrenchToast::hello_world();
+ Waffles::hello_world();
+}
+```
+
+Great. So now we just need to actually write the procedural macro. At the
+moment, procedural macros need to be in their own crate. Eventually, this
+restriction may be lifted, but for now, it's required. As such, there's a
+convention; for a crate named `foo`, a custom derive procedural macro is called
+`foo-derive`. Let's start a new crate called `hello-world-derive` inside our
+`hello-world` project.
+
+```bash
+$ cargo new hello-world-derive
+```
+
+To make sure that our `hello-world` crate is able to find this new crate we've
+created, we'll add it to our toml:
+
+```toml
+[dependencies]
+hello-world-derive = { path = "hello-world-derive" }
+```
+
+As for the source of our `hello-world-derive` crate, here's an example:
+
+```rust,ignore
+extern crate proc_macro;
+extern crate syn;
+#[macro_use]
+extern crate quote;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(HelloWorld)]
+pub fn hello_world(input: TokenStream) -> TokenStream {
+ // Construct a string representation of the type definition
+ let s = input.to_string();
+
+ // Parse the string representation
+ let ast = syn::parse_derive_input(&s).unwrap();
+
+ // Build the impl
+ let gen = impl_hello_world(&ast);
+
+ // Return the generated impl
+ gen.parse().unwrap()
+}
+```
+
+So there is a lot going on here. We have introduced two new crates: [`syn`] and
+[`quote`]. As you may have noticed, `input: TokenSteam` is immediately converted
+to a `String`. This `String` is a string representation of the Rust code for which
+we are deriving `HelloWorld`. At the moment, the only thing you can do with a
+`TokenStream` is convert it to a string. A richer API will exist in the future.
+
+So what we really need is to be able to _parse_ Rust code into something
+usable. This is where `syn` comes to play. `syn` is a crate for parsing Rust
+code. The other crate we've introduced is `quote`. It's essentially the dual of
+`syn` as it will make generating Rust code really easy. We could write this
+stuff on our own, but it's much simpler to use these libraries. Writing a full
+parser for Rust code is no simple task.
+
+[`syn`]: https://crates.io/crates/syn
+[`quote`]: https://crates.io/crates/quote
+
+The comments seem to give us a pretty good idea of our overall strategy. We
+are going to take a `String` of the Rust code for the type we are deriving, parse
+it using `syn`, construct the implementation of `hello_world` (using `quote`),
+then pass it back to Rust compiler.
+
+One last note: you'll see some `unwrap()`s there. If you want to provide an
+error for a procedural macro, then you should `panic!` with the error message.
+In this case, we're keeping it as simple as possible.
+
+Great, so let's write `impl_hello_world(&ast)`.
+
+```rust,ignore
+fn impl_hello_world(ast: &syn::MacroInput) -> quote::Tokens {
+ let name = &ast.ident;
+ quote! {
+ impl HelloWorld for #name {
+ fn hello_world() {
+ println!("Hello, World! My name is {}", stringify!(#name));
+ }
+ }
+ }
+}
+```
+
+So this is where quotes comes in. The `ast` argument is a struct that gives us
+a representation of our type (which can be either a `struct` or an `enum`).
+Check out the [docs](https://docs.rs/syn/0.10.5/syn/struct.MacroInput.html),
+there is some useful information there. We are able to get the name of the
+type using `ast.ident`. The `quote!` macro lets us write up the Rust code
+that we wish to return and convert it into `Tokens`. `quote!` lets us use some
+really cool templating mechanics; we simply write `#name` and `quote!` will
+replace it with the variable named `name`. You can even do some repetition
+similar to regular macros work. You should check out the
+[docs](https://docs.rs/quote) for a good introduction.
+
+So I think that's it. Oh, well, we do need to add dependencies for `syn` and
+`quote` in the `cargo.toml` for `hello-world-derive`.
+
+```toml
+[dependencies]
+syn = "0.10.5"
+quote = "0.3.10"
+```
+
+That should be it. Let's try to compile `hello-world`.
+
+```bash
+error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type
+ --> hello-world-derive/src/lib.rs:8:3
+ |
+8 | #[proc_macro_derive(HelloWorld)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+```
+
+Oh, so it appears that we need to declare that our `hello-world-derive` crate is
+a `proc-macro` crate type. How do we do this? Like this:
+
+```toml
+[lib]
+proc-macro = true
+```
+
+Ok so now, let's compile `hello-world`. Executing `cargo run` now yields:
+
+```bash
+Hello, World! My name is FrenchToast
+Hello, World! My name is Waffles
+```
+
+We've done it!
+
+## Custom Attributes
+
+In some cases it might make sense to allow users some kind of configuration.
+For example, the user might want to overwrite the name that is printed in the `hello_world()` method.
+
+This can be achieved with custom attributes:
+
+```rust,ignore
+#[derive(HelloWorld)]
+#[HelloWorldName = "the best Pancakes"]
+struct Pancakes;
+
+fn main() {
+ Pancakes::hello_world();
+}
+```
+
+If we try to compile this though, the compiler will respond with an error:
+
+```bash
+error: The attribute `HelloWorldName` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
+```
+
+The compiler needs to know that we're handling this attribute and to not respond with an error.
+This is done in the `hello-world-derive` crate by adding `attributes` to the `proc_macro_derive` attribute:
+
+```rust,ignore
+#[proc_macro_derive(HelloWorld, attributes(HelloWorldName))]
+pub fn hello_world(input: TokenStream) -> TokenStream
+```
+
+Multiple attributes can be specified that way.
+
+## Raising Errors
+
+Let's assume that we do not want to accept enums as input to our custom derive method.
+
+This condition can be easily checked with the help of `syn`.
+But how do we tell the user, that we do not accept enums?
+The idiomatic way to report errors in procedural macros is to panic:
+
+```rust,ignore
+fn impl_hello_world(ast: &syn::MacroInput) -> quote::Tokens {
+ let name = &ast.ident;
+ // Check if derive(HelloWorld) was specified for a struct
+ if let syn::Body::Struct(_) = ast.body {
+ // Yes, this is a struct
+ quote! {
+ impl HelloWorld for #name {
+ fn hello_world() {
+ println!("Hello, World! My name is {}", stringify!(#name));
+ }
+ }
+ }
+ } else {
+ //Nope. This is an Enum. We cannot handle these!
+ panic!("#[derive(HelloWorld)] is only defined for structs, not for enums!");
+ }
+}
+```
+
+If a user now tries to derive `HelloWorld` from an enum they will be greeted with following, hopefully helpful, error:
+
+```bash
+error: custom derive attribute panicked
+ --> src/main.rs
+ |
+ | #[derive(HelloWorld)]
+ | ^^^^^^^^^^
+ |
+ = help: message: #[derive(HelloWorld)] is only defined for structs, not for enums!
+```
diff --git a/trpl/raw-pointers.md b/trpl-1st-edition/raw-pointers.md
similarity index 97%
rename from trpl/raw-pointers.md
rename to trpl-1st-edition/raw-pointers.md
index ae100ae..7702427 100644
--- a/trpl/raw-pointers.md
+++ b/trpl-1st-edition/raw-pointers.md
@@ -1,4 +1,4 @@
-% Raw Pointers
+# Raw Pointers
Rust has a number of different smart pointer types in its standard library, but
there are two types that are extra-special. Much of Rust’s safety comes from
@@ -72,7 +72,7 @@ println!("raw points at {}", points_at);
For more operations on raw pointers, see [their API documentation][rawapi].
[unsafe]: unsafe.html
-[rawapi]: ../std/primitive.pointer.html
+[rawapi]: ../../std/primitive.pointer.html
# FFI
@@ -101,11 +101,11 @@ programmer *must* guarantee this.
The recommended method for the conversion is:
```rust
-// explicit cast
+// Explicit cast:
let i: u32 = 1;
let p_imm: *const u32 = &i as *const u32;
-// implicit coercion
+// Implicit coercion:
let mut m: u32 = 2;
let p_mut: *mut u32 = &mut m;
diff --git a/trpl/references-and-borrowing.md b/trpl-1st-edition/references-and-borrowing.md
similarity index 92%
rename from trpl/references-and-borrowing.md
rename to trpl-1st-edition/references-and-borrowing.md
index 57bfbce..f01aa45 100644
--- a/trpl/references-and-borrowing.md
+++ b/trpl-1st-edition/references-and-borrowing.md
@@ -1,4 +1,4 @@
-% References and Borrowing
+# References and Borrowing
This is the second of three sections presenting Rust’s ownership system. This is one of
Rust’s most distinct and compelling features, with which Rust developers should
@@ -46,9 +46,9 @@ like this:
```rust
fn foo(v1: Vec, v2: Vec) -> (Vec, Vec, i32) {
- // do stuff with v1 and v2
+ // Do stuff with `v1` and `v2`.
- // hand back ownership, and the result of our function
+ // Hand back ownership, and the result of our function.
(v1, v2, 42)
}
@@ -63,9 +63,9 @@ the first step:
```rust
fn foo(v1: &Vec, v2: &Vec) -> i32 {
- // do stuff with v1 and v2
+ // Do stuff with `v1` and `v2`.
- // return the answer
+ // Return the answer.
42
}
@@ -74,7 +74,7 @@ let v2 = vec![1, 2, 3];
let answer = foo(&v1, &v2);
-// we can use v1 and v2 here!
+// We can use `v1` and `v2` here!
```
A more concrete example:
@@ -86,12 +86,12 @@ fn main() {
return v.iter().fold(0, |a, &b| a + b);
}
// Borrow two vectors and sum them.
- // This kind of borrowing does not allow mutation to the borrowed.
+ // This kind of borrowing does not allow mutation through the borrowed reference.
fn foo(v1: &Vec, v2: &Vec) -> i32 {
- // do stuff with v1 and v2
+ // Do stuff with `v1` and `v2`.
let s1 = sum_vec(v1);
let s2 = sum_vec(v2);
- // return the answer
+ // Return the answer.
s1 + s2
}
@@ -152,7 +152,7 @@ the thing `y` points at. You’ll notice that `x` had to be marked `mut` as well
If it wasn’t, we couldn’t take a mutable borrow to an immutable value.
You'll also notice we added an asterisk (`*`) in front of `y`, making it `*y`,
-this is because `y` is a `&mut` reference. You'll need to use astrisks to
+this is because `y` is a `&mut` reference. You'll need to use asterisks to
access the contents of a reference as well.
Otherwise, `&mut` references are like references. There _is_ a large
@@ -240,7 +240,7 @@ fn main() {
In other words, the mutable borrow is held through the rest of our example. What
we want is for the mutable borrow by `y` to end so that the resource can be
-returned to the owner, `x`. `x` can then provide a immutable borrow to `println!`.
+returned to the owner, `x`. `x` can then provide an immutable borrow to `println!`.
In Rust, borrowing is tied to the scope that the borrow is valid for. And our
scopes look like this:
@@ -248,12 +248,12 @@ scopes look like this:
fn main() {
let mut x = 5;
- let y = &mut x; // -+ &mut borrow of x starts here
+ let y = &mut x; // -+ &mut borrow of `x` starts here.
// |
*y += 1; // |
// |
- println!("{}", x); // -+ - try to borrow x here
-} // -+ &mut borrow of x ends here
+ println!("{}", x); // -+ - Try to borrow `x` here.
+} // -+ &mut borrow of `x` ends here.
```
@@ -265,11 +265,11 @@ So when we add the curly braces:
let mut x = 5;
{
- let y = &mut x; // -+ &mut borrow starts here
+ let y = &mut x; // -+ &mut borrow starts here.
*y += 1; // |
-} // -+ ... and ends here
+} // -+ ... and ends here.
-println!("{}", x); // <- try to borrow x here
+println!("{}", x); // <- Try to borrow `x` here.
```
There’s no problem. Our mutable borrow goes out of scope before we create an
diff --git a/trpl/release-channels.md b/trpl-1st-edition/release-channels.md
similarity index 99%
rename from trpl/release-channels.md
rename to trpl-1st-edition/release-channels.md
index 1e203c6..af89ca8 100644
--- a/trpl/release-channels.md
+++ b/trpl-1st-edition/release-channels.md
@@ -1,4 +1,4 @@
-% Release Channels
+# Release Channels
The Rust project uses a concept called ‘release channels’ to manage releases.
It’s important to understand this process to choose which version of Rust
diff --git a/trpl/strings.md b/trpl-1st-edition/strings.md
similarity index 91%
rename from trpl/strings.md
rename to trpl-1st-edition/strings.md
index 135778c..537e5f9 100644
--- a/trpl/strings.md
+++ b/trpl-1st-edition/strings.md
@@ -1,4 +1,4 @@
-% Strings
+# Strings
Strings are an important concept for any programmer to master. Rust’s string
handling system is a bit different from other languages, due to its systems
@@ -83,10 +83,10 @@ converted using `&*`.
```rust,no_run
use std::net::TcpStream;
-TcpStream::connect("192.168.0.1:3000"); // &str parameter
+TcpStream::connect("192.168.0.1:3000"); // Parameter is of type &str.
let addr_string = "192.168.0.1:3000".to_string();
-TcpStream::connect(&*addr_string); // convert addr_string to &str
+TcpStream::connect(&*addr_string); // Convert `addr_string` to &str.
```
Viewing a `String` as a `&str` is cheap, but converting the `&str` to a
@@ -138,14 +138,14 @@ You can get something similar to an index like this:
```rust
# let hachiko = "忠犬ハチ公";
-let dog = hachiko.chars().nth(1); // kinda like hachiko[1]
+let dog = hachiko.chars().nth(1); // Kinda like `hachiko[1]`.
```
This emphasizes that we have to walk from the beginning of the list of `chars`.
## Slicing
-You can get a slice of a string with slicing syntax:
+You can get a slice of a string with the slicing syntax:
```rust
let dog = "hachiko";
@@ -163,8 +163,8 @@ let hachi = &dog[0..2];
with this error:
```text
-thread 'main' panicked at 'index 0 and/or 2 in `忠犬ハチ公` do not lie on
-character boundary'
+thread 'main' panicked at 'byte index 2 is not a char boundary; it is inside '忠'
+(bytes 0..3) of `忠犬ハチ公`'
```
## Concatenation
@@ -192,4 +192,4 @@ feature called ‘[`Deref` coercions][dc]’.
[ut]: unsized-types.html
[dc]: deref-coercions.html
-[connect]: ../std/net/struct.TcpStream.html#method.connect
+[connect]: ../../std/net/struct.TcpStream.html#method.connect
diff --git a/trpl/structs.md b/trpl-1st-edition/structs.md
similarity index 87%
rename from trpl/structs.md
rename to trpl-1st-edition/structs.md
index 328db25..3efa4f0 100644
--- a/trpl/structs.md
+++ b/trpl-1st-edition/structs.md
@@ -1,4 +1,4 @@
-% Structs
+# Structs
`struct`s are a way of creating more complex data types. For example, if we were
doing calculations involving coordinates in 2D space, we would need both an `x`
@@ -61,7 +61,7 @@ write something like this:
```rust,ignore
struct Point {
- mut x: i32,
+ mut x: i32, // This causes an error.
y: i32,
}
```
@@ -82,13 +82,13 @@ fn main() {
point.x = 5;
- let point = point; // now immutable
+ let point = point; // `point` is now immutable.
- point.y = 6; // this causes an error
+ point.y = 6; // This causes an error.
}
```
-Your structure can still contain `&mut` pointers, which will let
+Your structure can still contain `&mut` references, which will let
you do some kinds of mutation:
```rust
@@ -117,6 +117,28 @@ fn main() {
}
```
+Initialization of a data structure (struct, enum, union) can be simplified when
+fields of the data structure are initialized with variables of the same
+names as the fields.
+
+```
+#[derive(Debug)]
+struct Person<'a> {
+ name: &'a str,
+ age: u8
+}
+
+fn main() {
+ // Create struct with field init shorthand
+ let name = "Peter";
+ let age = 27;
+ let peter = Person { name, age };
+
+ // Debug-print struct
+ println!("{:?}", peter);
+}
+```
+
# Update syntax
A `struct` can include `..` to indicate that you want to use a copy of some
@@ -233,13 +255,14 @@ rather than positions.
You can define a `struct` with no members at all:
-```rust
-struct Electron {} // use empty braces...
-struct Proton; // ...or just a semicolon
+```rust,compile_fail,E0423
+struct Electron {} // Use empty braces...
+struct Proton; // ...or just a semicolon.
-// whether you declared the struct with braces or not, do the same when creating one
+// Use the same notation when creating an instance.
let x = Electron {};
let y = Proton;
+let z = Electron; // Error
```
Such a `struct` is called ‘unit-like’ because it resembles the empty
diff --git a/trpl/syntax-and-semantics.md b/trpl-1st-edition/syntax-and-semantics.md
similarity index 93%
rename from trpl/syntax-and-semantics.md
rename to trpl-1st-edition/syntax-and-semantics.md
index e9ec26d..aa4c125 100644
--- a/trpl/syntax-and-semantics.md
+++ b/trpl-1st-edition/syntax-and-semantics.md
@@ -1,4 +1,4 @@
-% Syntax and Semantics
+# Syntax and Semantics
This chapter breaks Rust down into small chunks, one for each concept.
diff --git a/trpl/syntax-index.md b/trpl-1st-edition/syntax-index.md
similarity index 95%
rename from trpl/syntax-index.md
rename to trpl-1st-edition/syntax-index.md
index 0259db2..c7b19a9 100644
--- a/trpl/syntax-index.md
+++ b/trpl-1st-edition/syntax-index.md
@@ -1,4 +1,4 @@
-% Syntax Index
+# Syntax Index
## Keywords
@@ -45,7 +45,7 @@
* `%` (`expr % expr`): arithmetic remainder. Overloadable (`Rem`).
* `%=` (`var %= expr`): arithmetic remainder & assignment. Overloadable (`RemAssign`).
* `&` (`expr & expr`): bitwise and. Overloadable (`BitAnd`).
-* `&` (`&expr`): borrow. See [References and Borrowing].
+* `&` (`&expr`, `&mut expr`): borrow. See [References and Borrowing].
* `&` (`&type`, `&mut type`, `&'a type`, `&'a mut type`): borrowed pointer type. See [References and Borrowing].
* `&=` (`var &= expr`): bitwise and & assignment. Overloadable (`BitAndAssign`).
* `&&` (`expr && expr`): logical and.
@@ -61,7 +61,6 @@
* `-` (`- expr`): arithmetic negation. Overloadable (`Neg`).
* `-=` (`var -= expr`): arithmetic subtraction & assignment. Overloadable (`SubAssign`).
* `->` (`fn(…) -> type`, `|…| -> type`): function and closure return type. See [Functions], [Closures].
-* `-> !` (`fn(…) -> !`, `|…| -> !`): diverging function or closure. See [Diverging Functions].
* `.` (`expr.ident`): member access. See [Structs], [Method Syntax].
* `..` (`..`, `expr..`, `..expr`, `expr..expr`): right-exclusive range literal.
* `..` (`..expr`): struct literal update syntax. See [Structs (Update syntax)].
@@ -95,6 +94,7 @@
* `|=` (`var |= expr`): bitwise or & assignment. Overloadable (`BitOrAssign`).
* `||` (`expr || expr`): logical or.
* `_`: "ignored" pattern binding (see [Patterns (Ignoring bindings)]). Also used to make integer-literals readable (see [Reference (Integer literals)]).
+* `?` (`expr?`): Error propagation. Returns early when `Err(_)` is encountered, unwraps otherwise. Similar to the [`try!` macro].
## Other Syntax
@@ -125,7 +125,7 @@
* `path<…>` (*e.g.* `Vec`): specifies parameters to generic type *in a type*. See [Generics].
-* `path::<…>`, `method::<…>` (*e.g.* `"42".parse::()`): specifies parameters to generic type, function, or method *in an expression*.
+* `path::<…>`, `method::<…>` (*e.g.* `"42".parse::()`): specifies parameters to generic type, function, or method *in an expression*. See [Generics § Resolving ambiguities](generics.html#resolving-ambiguities).
* `fn ident<…> …`: define generic function. See [Generics].
* `struct ident<…> …`: define generic structure. See [Generics].
* `enum ident<…> …`: define generic enumeration. See [Generics].
@@ -159,6 +159,10 @@
* `/*!…*/`: inner block doc comment. See [Comments].
* `/**…*/`: outer block doc comment. See [Comments].
+
+
+* `!`: always empty Never type. See [Diverging Functions].
+
* `()`: empty tuple (*a.k.a.* unit), both literal and type.
@@ -207,6 +211,7 @@
[Functions]: functions.html
[Generics]: generics.html
[Iterators]: iterators.html
+[`try!` macro]: error-handling.html#the-try-macro
[Lifetimes]: lifetimes.html
[Loops (`for`)]: loops.html#for
[Loops (`loop`)]: loops.html#loop
@@ -230,10 +235,10 @@
[Primitive Types (Tuple Indexing)]: primitive-types.html#tuple-indexing
[Primitive Types (Tuples)]: primitive-types.html#tuples
[Raw Pointers]: raw-pointers.html
-[Reference (Byte String Literals)]: ../reference.html#byte-string-literals
-[Reference (Integer literals)]: ../reference.html#integer-literals
-[Reference (Raw Byte String Literals)]: ../reference.html#raw-byte-string-literals
-[Reference (Raw String Literals)]: ../reference.html#raw-string-literals
+[Reference (Byte String Literals)]: ../../reference/tokens.html/#byte-string-literals
+[Reference (Integer literals)]: ../../reference/tokens.html#integer-literals
+[Reference (Raw Byte String Literals)]: ../../reference/tokens.html#raw-byte-string-literals
+[Reference (Raw String Literals)]: ../../reference/tokens.html#raw-string-literals
[References and Borrowing]: references-and-borrowing.html
[Strings]: strings.html
[Structs (Update syntax)]: structs.html#update-syntax
diff --git a/trpl/testing.md b/trpl-1st-edition/testing.md
similarity index 65%
rename from trpl/testing.md
rename to trpl-1st-edition/testing.md
index 8672914..b4f580f 100644
--- a/trpl/testing.md
+++ b/trpl-1st-edition/testing.md
@@ -1,4 +1,4 @@
-% Testing
+# Testing
> Program testing can be a very effective way to show the presence of bugs, but
> it is hopelessly inadequate for showing their absence.
@@ -23,8 +23,26 @@ $ cd adder
Cargo will automatically generate a simple test when you make a new project.
Here's the contents of `src/lib.rs`:
-```rust
-# fn main() {}
+```rust,ignore
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn it_works() {
+ }
+}
+```
+
+For now, let's remove the `mod` bit, and focus on just the function:
+
+```rust,ignore
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
#[test]
fn it_works() {
}
@@ -36,8 +54,9 @@ currently has no body. That's good enough to pass! We can run the tests with
```bash
$ cargo test
- Compiling adder v0.0.1 (file:///home/you/projects/adder)
- Running target/adder-91b3e234d4ed382a
+ Compiling adder v0.1.0 (file:///home/you/projects/adder)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.15 secs
+ Running target/debug/deps/adder-941f01916ca4a642
running 1 test
test it_works ... ok
@@ -62,7 +81,9 @@ test it_works ... ok
Note the `it_works`. This comes from the name of our function:
```rust
+# fn main() {
fn it_works() {
+}
# }
```
@@ -75,8 +96,11 @@ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
So why does our do-nothing test pass? Any test which doesn't `panic!` passes,
and any test that does `panic!` fails. Let's make our test fail:
-```rust
-# fn main() {}
+```rust,ignore
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
#[test]
fn it_works() {
assert!(false);
@@ -89,8 +113,9 @@ run our tests again:
```bash
$ cargo test
- Compiling adder v0.0.1 (file:///home/you/projects/adder)
- Running target/adder-91b3e234d4ed382a
+ Compiling adder v0.1.0 (file:///home/you/projects/adder)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.17 secs
+ Running target/debug/deps/adder-941f01916ca4a642
running 1 test
test it_works ... FAILED
@@ -98,8 +123,8 @@ test it_works ... FAILED
failures:
---- it_works stdout ----
- thread 'it_works' panicked at 'assertion failed: false', /home/steve/tmp/adder/src/lib.rs:3
-
+ thread 'it_works' panicked at 'assertion failed: false', src/lib.rs:5
+note: Run with `RUST_BACKTRACE=1` for a backtrace.
failures:
@@ -107,7 +132,7 @@ failures:
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
-thread 'main' panicked at 'Some tests failed', /home/steve/src/rust/src/libtest/lib.rs:247
+error: test failed
```
Rust indicates that our test failed:
@@ -122,7 +147,7 @@ And that's reflected in the summary line:
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
```
-We also get a non-zero status code. We can use `$?` on OS X and Linux:
+We also get a non-zero status code. We can use `$?` on macOS and Linux:
```bash
$ echo $?
@@ -146,8 +171,11 @@ This is useful if you want to integrate `cargo test` into other tooling.
We can invert our test's failure with another attribute: `should_panic`:
-```rust
-# fn main() {}
+```rust,ignore
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
#[test]
#[should_panic]
fn it_works() {
@@ -159,8 +187,9 @@ This test will now succeed if we `panic!` and fail if we complete. Let's try it:
```bash
$ cargo test
- Compiling adder v0.0.1 (file:///home/you/projects/adder)
- Running target/adder-91b3e234d4ed382a
+ Compiling adder v0.1.0 (file:///home/you/projects/adder)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.17 secs
+ Running target/debug/deps/adder-941f01916ca4a642
running 1 test
test it_works ... ok
@@ -177,8 +206,11 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
Rust provides another macro, `assert_eq!`, that compares two arguments for
equality:
-```rust
-# fn main() {}
+```rust,ignore
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
#[test]
#[should_panic]
fn it_works() {
@@ -191,8 +223,9 @@ passes:
```bash
$ cargo test
- Compiling adder v0.0.1 (file:///home/you/projects/adder)
- Running target/adder-91b3e234d4ed382a
+ Compiling adder v0.1.0 (file:///home/you/projects/adder)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.21 secs
+ Running target/debug/deps/adder-941f01916ca4a642
running 1 test
test it_works ... ok
@@ -212,8 +245,11 @@ parameter can be added to the `should_panic` attribute. The test harness will
make sure that the failure message contains the provided text. A safer version
of the example above would be:
-```rust
-# fn main() {}
+```rust,ignore
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
#[test]
#[should_panic(expected = "assertion failed")]
fn it_works() {
@@ -224,7 +260,10 @@ fn it_works() {
That's all there is to the basics! Let's write one 'real' test:
```rust,ignore
-# fn main() {}
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
pub fn add_two(a: i32) -> i32 {
a + 2
}
@@ -243,8 +282,15 @@ some known arguments and compare it to the expected output.
Sometimes a few specific tests can be very time-consuming to execute. These
can be disabled by default by using the `ignore` attribute:
-```rust
-# fn main() {}
+```rust,ignore
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
+pub fn add_two(a: i32) -> i32 {
+ a + 2
+}
+
#[test]
fn it_works() {
assert_eq!(4, add_two(2));
@@ -253,7 +299,7 @@ fn it_works() {
#[test]
#[ignore]
fn expensive_test() {
- // code that takes an hour to run
+ // Code that takes an hour to run...
}
```
@@ -262,8 +308,9 @@ not:
```bash
$ cargo test
- Compiling adder v0.0.1 (file:///home/you/projects/adder)
- Running target/adder-91b3e234d4ed382a
+ Compiling adder v0.1.0 (file:///home/you/projects/adder)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.20 secs
+ Running target/debug/deps/adder-941f01916ca4a642
running 2 tests
test expensive_test ... ignored
@@ -282,7 +329,8 @@ The expensive tests can be run explicitly using `cargo test -- --ignored`:
```bash
$ cargo test -- --ignored
- Running target/adder-91b3e234d4ed382a
+ Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
+ Running target/debug/deps/adder-941f01916ca4a642
running 1 test
test expensive_test ... ok
@@ -302,11 +350,17 @@ which is why the command is `cargo test -- --ignored`.
# The `tests` module
There is one way in which our existing example is not idiomatic: it's
-missing the `tests` module. The idiomatic way of writing our example
-looks like this:
+missing the `tests` module. You might have noticed this test module was
+present in the code that was initially generated with `cargo new` but
+was missing from our last example. Let's explain what this does.
+
+The idiomatic way of writing our example looks like this:
```rust,ignore
-# fn main() {}
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
pub fn add_two(a: i32) -> i32 {
a + 2
}
@@ -330,12 +384,15 @@ currently trying to run the tests. This can save compile time, and also ensures
that our tests are entirely left out of a normal build.
The second change is the `use` declaration. Because we're in an inner module,
-we need to bring our test function into scope. This can be annoying if you have
+we need to bring the tested function into scope. This can be annoying if you have
a large module, and so this is a common use of globs. Let's change our
`src/lib.rs` to make use of it:
```rust,ignore
-# fn main() {}
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
pub fn add_two(a: i32) -> i32 {
a + 2
}
@@ -356,8 +413,8 @@ Note the different `use` line. Now we run our tests:
```bash
$ cargo test
Updating registry `https://github.com/rust-lang/crates.io-index`
- Compiling adder v0.0.1 (file:///home/you/projects/adder)
- Running target/adder-91b3e234d4ed382a
+ Compiling adder v0.1.0 (file:///home/you/projects/adder)
+ Running target/debug/deps/adder-91b3e234d4ed382a
running 1 test
test tests::it_works ... ok
@@ -380,14 +437,19 @@ the `tests` directory.
# The `tests` directory
-Each file in `tests/*.rs` directory is treated as individual crate.
-So, to write an integration test, let's make a `tests` directory, and
-put a `tests/integration_test.rs` file inside, with this as its contents:
+Each file in `tests/*.rs` directory is treated as an individual crate.
+To write an integration test, let's make a `tests` directory and
+put a `tests/integration_test.rs` file inside with this as its contents:
```rust,ignore
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
+# // Sadly, this code will not work in play.rust-lang.org, because we have no
+# // crate adder to import. You'll need to try this part on your own machine.
extern crate adder;
-# fn main() {}
#[test]
fn it_works() {
assert_eq!(4, adder::add_two(2));
@@ -404,15 +466,15 @@ Let's run them:
```bash
$ cargo test
- Compiling adder v0.0.1 (file:///home/you/projects/adder)
- Running target/adder-91b3e234d4ed382a
+ Compiling adder v0.1.0 (file:///home/you/projects/adder)
+ Running target/debug/deps/adder-91b3e234d4ed382a
running 1 test
test tests::it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
- Running target/lib-c18e7d3494509e74
+ Running target/debug/integration_test-68064b69521c828a
running 1 test
test it_works ... ok
@@ -437,6 +499,10 @@ be imported in every test with `mod common;`
That's all there is to the `tests` directory. The `tests` module isn't needed
here, since the whole thing is focused on tests.
+Note, when building integration tests, cargo will not pass the `test` attribute
+to the compiler. It means that all parts in `cfg(test)` won't be included in
+the build used in your integration tests.
+
Let's finally check out that third section: documentation tests.
# Documentation tests
@@ -448,7 +514,10 @@ running examples in your documentation (**note:** this only works in library
crates, not binary crates). Here's a fleshed-out `src/lib.rs` with examples:
```rust,ignore
-# fn main() {}
+# // The next line exists to trick play.rust-lang.org into running our code as a
+# // test:
+# // fn main
+#
//! The `adder` crate provides functions that add numbers to other numbers.
//!
//! # Examples
@@ -490,15 +559,15 @@ Let's run the tests again:
```bash
$ cargo test
- Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
- Running target/adder-91b3e234d4ed382a
+ Compiling adder v0.1.0. (file:///home/you/projects/adder)
+ Running target/debug/deps/adder-91b3e234d4ed382a
running 1 test
test tests::it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
- Running target/lib-c18e7d3494509e74
+ Running target/debug/integration_test-68064b69521c828a
running 1 test
test it_works ... ok
@@ -521,3 +590,44 @@ you add more examples.
We haven’t covered all of the details with writing documentation tests. For more,
please see the [Documentation chapter](documentation.html).
+
+# Testing and concurrency
+
+It is important to note that tests are run concurrently using threads. For this
+reason, care should be taken to ensure your tests do not depend on each-other,
+or on any shared state. "Shared state" can also include the environment, such
+as the current working directory, or environment variables.
+
+If this is an issue it is possible to control this concurrency, either by
+setting the environment variable `RUST_TEST_THREADS`, or by passing the argument
+`--test-threads` to the tests:
+
+```bash
+$ RUST_TEST_THREADS=1 cargo test # Run tests with no concurrency
+...
+$ cargo test -- --test-threads=1 # Same as above
+...
+```
+
+# Test output
+
+By default Rust's test library captures and discards output to standard
+out/error, e.g. output from `println!()`. This too can be controlled using the
+environment or a switch:
+
+
+```bash
+$ RUST_TEST_NOCAPTURE=1 cargo test # Preserve stdout/stderr
+...
+$ cargo test -- --nocapture # Same as above
+...
+```
+
+However a better method avoiding capture is to use logging rather than raw
+output. Rust has a [standard logging API][log], which provides a frontend to
+multiple logging implementations. This can be used in conjunction with the
+default [env_logger] to output any debugging information in a manner that can be
+controlled at runtime.
+
+[log]: https://crates.io/crates/log
+[env_logger]: https://crates.io/crates/env_logger
diff --git a/trpl/the-stack-and-the-heap.md b/trpl-1st-edition/the-stack-and-the-heap.md
similarity index 98%
rename from trpl/the-stack-and-the-heap.md
rename to trpl-1st-edition/the-stack-and-the-heap.md
index aee4529..2e7441a 100644
--- a/trpl/the-stack-and-the-heap.md
+++ b/trpl-1st-edition/the-stack-and-the-heap.md
@@ -1,4 +1,4 @@
-% The Stack and the Heap
+# The Stack and the Heap
As a systems language, Rust operates at a low level. If you’re coming from a
high-level language, there are some aspects of systems programming that you may
@@ -86,7 +86,7 @@ to a large number, representing how much RAM your computer has. For example, if
you have a gigabyte of RAM, your addresses go from `0` to `1,073,741,823`. That
number comes from 230, the number of bytes in a gigabyte. [^gigabyte]
-[^gigabyte]: ‘Gigabyte’ can mean two things: 10^9, or 2^30. The SI standard resolved this by stating that ‘gigabyte’ is 10^9, and ‘gibibyte’ is 2^30. However, very few people use this terminology, and rely on context to differentiate. We follow in that tradition here.
+[^gigabyte]: ‘Gigabyte’ can mean two things: 109, or 230. The IEC standard resolved this by stating that ‘gigabyte’ is 109, and ‘gibibyte’ is 230. However, very few people use this terminology, and rely on context to differentiate. We follow in that tradition here.
This memory is kind of like a giant array: addresses start at zero and go
up to the final number. So here’s a diagram of our first stack frame:
@@ -215,7 +215,7 @@ fn main() {
}
```
-[box]: ../std/boxed/index.html
+[box]: ../../std/boxed/index.html
Here’s what happens in memory when `main()` is called:
diff --git a/trpl/trait-objects.md b/trpl-1st-edition/trait-objects.md
similarity index 93%
rename from trpl/trait-objects.md
rename to trpl-1st-edition/trait-objects.md
index b1aee57..4a4b2cb 100644
--- a/trpl/trait-objects.md
+++ b/trpl-1st-edition/trait-objects.md
@@ -1,4 +1,4 @@
-% Trait Objects
+# Trait Objects
When code involves polymorphism, there needs to be a mechanism to determine
which specific version is actually run. This is called ‘dispatch’. There are
@@ -195,7 +195,7 @@ pub struct TraitObject {
# }
```
-[stdraw]: ../std/raw/struct.TraitObject.html
+[stdraw]: ../../std/raw/struct.TraitObject.html
That is, a trait object like `&Foo` consists of a ‘data’ pointer and a ‘vtable’
pointer.
@@ -221,8 +221,8 @@ struct FooVtable {
// u8:
fn call_method_on_u8(x: *const ()) -> String {
- // the compiler guarantees that this function is only called
- // with `x` pointing to a u8
+ // The compiler guarantees that this function is only called
+ // with `x` pointing to a u8.
let byte: &u8 = unsafe { &*(x as *const u8) };
byte.method()
@@ -233,7 +233,7 @@ static Foo_for_u8_vtable: FooVtable = FooVtable {
size: 1,
align: 1,
- // cast to a function pointer
+ // Cast to a function pointer:
method: call_method_on_u8 as fn(*const ()) -> String,
};
@@ -241,8 +241,8 @@ static Foo_for_u8_vtable: FooVtable = FooVtable {
// String:
fn call_method_on_String(x: *const ()) -> String {
- // the compiler guarantees that this function is only called
- // with `x` pointing to a String
+ // The compiler guarantees that this function is only called
+ // with `x` pointing to a String.
let string: &String = unsafe { &*(x as *const String) };
string.method()
@@ -250,7 +250,7 @@ fn call_method_on_String(x: *const ()) -> String {
static Foo_for_String_vtable: FooVtable = FooVtable {
destructor: /* compiler magic */,
- // values for a 64-bit computer, halve them for 32-bit ones
+ // Values for a 64-bit computer, halve them for 32-bit ones.
size: 24,
align: 8,
@@ -263,10 +263,7 @@ any resources of the vtable’s type: for `u8` it is trivial, but for `String` i
will free the memory. This is necessary for owning trait objects like
`Box`, which need to clean-up both the `Box` allocation as well as the
internal type when they go out of scope. The `size` and `align` fields store
-the size of the erased type, and its alignment requirements; these are
-essentially unused at the moment since the information is embedded in the
-destructor, but will be used in the future, as trait objects are progressively
-made more flexible.
+the size of the erased type, and its alignment requirements.
Suppose we’ve got some values that implement `Foo`. The explicit form of
construction and use of `Foo` trait objects might look a bit like (ignoring the
@@ -278,17 +275,17 @@ let x: u8 = 1;
// let b: &Foo = &a;
let b = TraitObject {
- // store the data
+ // Store the data:
data: &a,
- // store the methods
+ // Store the methods:
vtable: &Foo_for_String_vtable
};
// let y: &Foo = x;
let y = TraitObject {
- // store the data
+ // Store the data:
data: &x,
- // store the methods
+ // Store the methods:
vtable: &Foo_for_u8_vtable
};
diff --git a/trpl/traits.md b/trpl-1st-edition/traits.md
similarity index 83%
rename from trpl/traits.md
rename to trpl-1st-edition/traits.md
index e685cb1..91a4bbb 100644
--- a/trpl/traits.md
+++ b/trpl-1st-edition/traits.md
@@ -1,4 +1,4 @@
-% Traits
+# Traits
A trait is a language feature that tells the Rust compiler about
functionality a type must provide.
@@ -47,6 +47,34 @@ As you can see, the `trait` block looks very similar to the `impl` block,
but we don’t define a body, only a type signature. When we `impl` a trait,
we use `impl Trait for Item`, rather than only `impl Item`.
+`Self` may be used in a type annotation to refer to an instance of the type
+implementing this trait passed as a parameter. `Self`, `&Self` or `&mut Self`
+may be used depending on the level of ownership required.
+
+```rust
+struct Circle {
+ x: f64,
+ y: f64,
+ radius: f64,
+}
+
+trait HasArea {
+ fn area(&self) -> f64;
+
+ fn is_larger(&self, &Self) -> bool;
+}
+
+impl HasArea for Circle {
+ fn area(&self) -> f64 {
+ std::f64::consts::PI * (self.radius * self.radius)
+ }
+
+ fn is_larger(&self, other: &Self) -> bool {
+ self.area() > other.area()
+ }
+}
+```
+
## Trait bounds on generic functions
Traits are useful because they allow a type to make certain promises about its
@@ -202,7 +230,7 @@ impl Rectangle { ... }
Now, a rectangle can be defined in terms of any type that can be compared for
equality.
-[PartialEq]: ../core/cmp/trait.PartialEq.html
+[PartialEq]: ../../core/cmp/trait.PartialEq.html
Here we defined a new struct `Rectangle` that accepts numbers of any
precision—really, objects of pretty much any type—as long as they can be
@@ -215,28 +243,22 @@ to know more about [operator traits][operators-and-overloading].
# Rules for implementing traits
So far, we’ve only added trait implementations to structs, but you can
-implement a trait for any type. So technically, we _could_ implement `HasArea`
-for `i32`:
+implement a trait for any type such as `f32`:
```rust
-trait HasArea {
- fn area(&self) -> f64;
+trait ApproxEqual {
+ fn approx_equal(&self, other: &Self) -> bool;
}
-
-impl HasArea for i32 {
- fn area(&self) -> f64 {
- println!("this is silly");
-
- *self as f64
+impl ApproxEqual for f32 {
+ fn approx_equal(&self, other: &Self) -> bool {
+ // Appropriate for `self` and `other` being close to 1.0.
+ (self - other).abs() <= ::std::f32::EPSILON
}
}
-5.area();
+println!("{}", 1.0.approx_equal(&1.00000001));
```
-It is considered poor style to implement methods on such primitive types, even
-though it is possible.
-
This may seem like the Wild West, but there are two restrictions around
implementing traits that prevent this from getting out of hand. The first is
that if the trait isn’t defined in your scope, it doesn’t apply. Here’s an
@@ -244,13 +266,13 @@ example: the standard library provides a [`Write`][write] trait which adds
extra functionality to `File`s, for doing file I/O. By default, a `File`
won’t have its methods:
-[write]: ../std/io/trait.Write.html
+[write]: ../../std/io/trait.Write.html
```rust,ignore
-let mut f = std::fs::File::open("foo.txt").expect("Couldn’t open foo.txt");
-let buf = b"whatever"; // byte string literal. buf: &[u8; 8]
+let mut f = std::fs::File::create("foo.txt").expect("Couldn’t create foo.txt");
+let buf = b"whatever"; // buf: &[u8; 8], a byte string literal.
let result = f.write(buf);
-# result.unwrap(); // ignore the error
+# result.unwrap(); // Ignore the error.
```
Here’s the error:
@@ -263,13 +285,13 @@ let result = f.write(buf);
We need to `use` the `Write` trait first:
-```rust,ignore
+```rust,no_run
use std::io::Write;
-let mut f = std::fs::File::open("foo.txt").expect("Couldn’t open foo.txt");
+let mut f = std::fs::File::create("foo.txt").expect("Couldn’t create foo.txt");
let buf = b"whatever";
let result = f.write(buf);
-# result.unwrap(); // ignore the error
+# result.unwrap(); // Ignore the error.
```
This will compile without error.
@@ -391,14 +413,14 @@ impl ConvertTo for i32 {
fn convert(&self) -> i64 { *self as i64 }
}
-// can be called with T == i32
-fn normal>(x: &T) -> i64 {
+// Can be called with T == i32.
+fn convert_t_to_i64>(x: T) -> i64 {
x.convert()
}
-// can be called with T == i64
-fn inverse(x: i32) -> T
- // this is using ConvertTo as if it were "ConvertTo"
+// Can be called with T == i64.
+fn convert_i32_to_t(x: i32) -> T
+ // This is using ConvertTo as if it were "ConvertTo".
where i32: ConvertTo {
x.convert()
}
@@ -448,15 +470,15 @@ impl Foo for OverrideDefault {
fn is_invalid(&self) -> bool {
println!("Called OverrideDefault.is_invalid!");
- true // overrides the expected value of is_invalid()
+ true // Overrides the expected value of `is_invalid()`.
}
}
let default = UseDefault;
-assert!(!default.is_invalid()); // prints "Called UseDefault.is_valid."
+assert!(!default.is_invalid()); // Prints "Called UseDefault.is_valid."
let over = OverrideDefault;
-assert!(over.is_invalid()); // prints "Called OverrideDefault.is_invalid!"
+assert!(over.is_invalid()); // Prints "Called OverrideDefault.is_invalid!"
```
# Inheritance
@@ -518,12 +540,12 @@ fn main() {
However, deriving is limited to a certain set of traits:
-- [`Clone`](../core/clone/trait.Clone.html)
-- [`Copy`](../core/marker/trait.Copy.html)
-- [`Debug`](../core/fmt/trait.Debug.html)
-- [`Default`](../core/default/trait.Default.html)
-- [`Eq`](../core/cmp/trait.Eq.html)
-- [`Hash`](../core/hash/trait.Hash.html)
-- [`Ord`](../core/cmp/trait.Ord.html)
-- [`PartialEq`](../core/cmp/trait.PartialEq.html)
-- [`PartialOrd`](../core/cmp/trait.PartialOrd.html)
+- [`Clone`](../../core/clone/trait.Clone.html)
+- [`Copy`](../../core/marker/trait.Copy.html)
+- [`Debug`](../../core/fmt/trait.Debug.html)
+- [`Default`](../../core/default/trait.Default.html)
+- [`Eq`](../../core/cmp/trait.Eq.html)
+- [`Hash`](../../core/hash/trait.Hash.html)
+- [`Ord`](../../core/cmp/trait.Ord.html)
+- [`PartialEq`](../../core/cmp/trait.PartialEq.html)
+- [`PartialOrd`](../../core/cmp/trait.PartialOrd.html)
diff --git a/trpl/type-aliases.md b/trpl-1st-edition/type-aliases.md
similarity index 96%
rename from trpl/type-aliases.md
rename to trpl-1st-edition/type-aliases.md
index def2e31..f70e7a3 100644
--- a/trpl/type-aliases.md
+++ b/trpl-1st-edition/type-aliases.md
@@ -1,4 +1,4 @@
-% `type` Aliases
+# Type Aliases
The `type` keyword lets you declare an alias of another type:
@@ -75,4 +75,4 @@ This creates a specialized version of the `Result` type, which always has a
in the standard library to create custom errors for each subsection. For
example, [io::Result][ioresult].
-[ioresult]: ../std/io/type.Result.html
+[ioresult]: ../../std/io/type.Result.html
diff --git a/trpl/ufcs.md b/trpl-1st-edition/ufcs.md
similarity index 98%
rename from trpl/ufcs.md
rename to trpl-1st-edition/ufcs.md
index 7725970..016ecc7 100644
--- a/trpl/ufcs.md
+++ b/trpl-1st-edition/ufcs.md
@@ -1,4 +1,4 @@
-% Universal Function Call Syntax
+# Universal Function Call Syntax
Sometimes, functions can have the same names. Consider this code:
diff --git a/trpl/unsafe.md b/trpl-1st-edition/unsafe.md
similarity index 97%
rename from trpl/unsafe.md
rename to trpl-1st-edition/unsafe.md
index 9cab586..0331c95 100644
--- a/trpl/unsafe.md
+++ b/trpl-1st-edition/unsafe.md
@@ -1,4 +1,4 @@
-% Unsafe
+# Unsafe
Rust’s main draw is its powerful static guarantees about behavior. But safety
checks are conservative by nature: there are some programs that are actually
@@ -12,7 +12,7 @@ four contexts. The first one is to mark a function as unsafe:
```rust
unsafe fn danger_will_robinson() {
- // scary stuff
+ // Scary stuff...
}
```
@@ -23,7 +23,7 @@ The second use of `unsafe` is an unsafe block:
```rust
unsafe {
- // scary stuff
+ // Scary stuff...
}
```
@@ -139,4 +139,4 @@ I’ll repeat again: even though you _can_ do arbitrary things in unsafe blocks
and functions doesn’t mean you should. The compiler will act as though you’re
upholding its invariants, so be careful!
-[intrinsics]: intrinsics.html
+[intrinsics]: ../../unstable-book/language-features/intrinsics.html
diff --git a/trpl/unsized-types.md b/trpl-1st-edition/unsized-types.md
similarity index 99%
rename from trpl/unsized-types.md
rename to trpl-1st-edition/unsized-types.md
index a23470d..2d09092 100644
--- a/trpl/unsized-types.md
+++ b/trpl-1st-edition/unsized-types.md
@@ -1,4 +1,4 @@
-% Unsized Types
+# Unsized Types
Most types have a particular size, in bytes, that is knowable at compile time.
For example, an `i32` is thirty-two bits big, or four bytes. However, there are
diff --git a/trpl/using-rust-without-the-standard-library.md b/trpl-1st-edition/using-rust-without-the-standard-library.md
similarity index 75%
rename from trpl/using-rust-without-the-standard-library.md
rename to trpl-1st-edition/using-rust-without-the-standard-library.md
index 69958dd..c1dcfea 100644
--- a/trpl/using-rust-without-the-standard-library.md
+++ b/trpl-1st-edition/using-rust-without-the-standard-library.md
@@ -1,4 +1,4 @@
-% Using Rust Without the Standard Library
+# Using Rust Without the Standard Library
Rust’s standard library provides a lot of useful functionality, but assumes
support for various features of its host system: threads, networking, heap
@@ -9,11 +9,11 @@ don’t want to use the standard library via an attribute: `#![no_std]`.
> Note: This feature is technically stable, but there are some caveats. For
> one, you can build a `#![no_std]` _library_ on stable, but not a _binary_.
> For details on binaries without the standard library, see [the nightly
-> chapter on `#![no_std]`](no-stdlib.html)
+> chapter on 'lang items'][unstable book lang items]
To use `#![no_std]`, add it to your crate root:
-```rust
+```rust,ignore
#![no_std]
fn plus_one(x: i32) -> i32 {
@@ -22,14 +22,14 @@ fn plus_one(x: i32) -> i32 {
```
Much of the functionality that’s exposed in the standard library is also
-available via the [`core` crate](../core/index.html). When we’re using the
+available via the [`core` crate](../../core/index.html). When we’re using the
standard library, Rust automatically brings `std` into scope, allowing you to
use its features without an explicit import. By the same token, when using
`#![no_std]`, Rust will bring `core` into scope for you, as well as [its
-prelude](../core/prelude/v1/index.html). This means that a lot of code will Just
+prelude](../../core/prelude/v1/index.html). This means that a lot of code will Just
Work:
-```rust
+```rust,ignore
#![no_std]
fn may_fail(failure: bool) -> Result<(), &'static str> {
@@ -40,3 +40,5 @@ fn may_fail(failure: bool) -> Result<(), &'static str> {
}
}
```
+
+[unstable book lang items]: ../../unstable-book/language-features/lang-items.html#using-libc
diff --git a/trpl/variable-bindings.md b/trpl-1st-edition/variable-bindings.md
similarity index 92%
rename from trpl/variable-bindings.md
rename to trpl-1st-edition/variable-bindings.md
index 30e922d..65e172e 100644
--- a/trpl/variable-bindings.md
+++ b/trpl-1st-edition/variable-bindings.md
@@ -1,4 +1,4 @@
-% Variable Bindings
+# Variable Bindings
Virtually every non-'Hello World’ Rust program uses *variable bindings*. They
bind some value to a name, so it can be used later. `let` is
@@ -47,7 +47,7 @@ let x: i32 = 5;
```
If I asked you to read this out loud to the rest of the class, you’d say “`x`
-is a binding with the type `i32` and the value `five`.”
+is a binding with the type `i32` and the value `5`.”
In this case we chose to represent `x` as a 32-bit signed integer. Rust has
many different primitive integer types. They begin with `i` for signed integers
@@ -102,7 +102,7 @@ mutation, then the solution is quite easy: add `mut`.
There are other good reasons to avoid mutable state when possible, but they’re
out of the scope of this guide. In general, you can often avoid explicit
mutation, and so it is preferable in Rust. That said, sometimes, mutation is
-what you need, so it’s not verboten.
+what you need, so it’s not forbidden.
# Initializing bindings
@@ -161,7 +161,7 @@ Could not compile `hello_world`.
Rust will not let us use a value that has not been initialized.
-Let take a minute to talk about this stuff we've added to `println!`.
+Let us take a minute to talk about this stuff we've added to `println!`.
If you include two curly braces (`{}`, some call them moustaches...) in your
string to print, Rust will interpret this as a request to interpolate some sort
@@ -176,12 +176,12 @@ more detailed manner, there are a [wide number of options available][format].
For now, we'll stick to the default: integers aren't very complicated to
print.
-[format]: ../std/fmt/index.html
+[format]: ../../std/fmt/index.html
# Scope and shadowing
Let’s get back to bindings. Variable bindings have a scope - they are
-constrained to live in a block they were defined in. A block is a collection
+constrained to live in the block they were defined in. A block is a collection
of statements enclosed by `{` and `}`. Function definitions are also blocks!
In the following example we define two variable bindings, `x` and `y`, which
live in different blocks. `x` can be accessed from inside the `fn main() {}`
@@ -194,7 +194,7 @@ fn main() {
let y: i32 = 3;
println!("The value of x is {} and value of y is {}", x, y);
}
- println!("The value of x is {} and value of y is {}", x, y); // This won't work
+ println!("The value of x is {} and value of y is {}", x, y); // This won't work.
}
```
@@ -207,7 +207,7 @@ Instead we get this error:
$ cargo build
Compiling hello v0.1.0 (file:///home/you/projects/hello_world)
main.rs:7:62: 7:63 error: unresolved name `y`. Did you mean `x`? [E0425]
-main.rs:7 println!("The value of x is {} and value of y is {}", x, y); // This won't work
+main.rs:7 println!("The value of x is {} and value of y is {}", x, y); // This won't work.
^
note: in expansion of format_args!
:2:25: 2:56 note: expansion site
@@ -229,13 +229,13 @@ scope will override the previous binding.
```rust
let x: i32 = 8;
{
- println!("{}", x); // Prints "8"
+ println!("{}", x); // Prints "8".
let x = 12;
- println!("{}", x); // Prints "12"
+ println!("{}", x); // Prints "12".
}
-println!("{}", x); // Prints "8"
+println!("{}", x); // Prints "8".
let x = 42;
-println!("{}", x); // Prints "42"
+println!("{}", x); // Prints "42".
```
Shadowing and mutable bindings may appear as two sides of the same coin, but
@@ -249,8 +249,8 @@ by any means.
```rust
let mut x: i32 = 1;
x = 7;
-let x = x; // x is now immutable and is bound to 7
+let x = x; // `x` is now immutable and is bound to `7`.
let y = 4;
-let y = "I can also be bound to text!"; // y is now of a different type
+let y = "I can also be bound to text!"; // `y` is now of a different type.
```
diff --git a/trpl/vectors.md b/trpl-1st-edition/vectors.md
similarity index 93%
rename from trpl/vectors.md
rename to trpl-1st-edition/vectors.md
index cb6781c..138a152 100644
--- a/trpl/vectors.md
+++ b/trpl-1st-edition/vectors.md
@@ -1,4 +1,4 @@
-% Vectors
+# Vectors
A ‘vector’ is a dynamic or ‘growable’ array, implemented as the standard
library type [`Vec`][vec]. The `T` means that we can have vectors
@@ -17,7 +17,7 @@ situation, this is just convention.)
There’s an alternate form of `vec!` for repeating an initial value:
```rust
-let v = vec![0; 10]; // ten zeroes
+let v = vec![0; 10]; // A vector of ten zeroes.
```
Vectors store their contents as contiguous arrays of `T` on the heap. This means
@@ -46,10 +46,10 @@ let v = vec![1, 2, 3, 4, 5];
let i: usize = 0;
let j: i32 = 0;
-// works
+// Works:
v[i];
-// doesn’t
+// Doesn’t:
v[j];
```
@@ -148,9 +148,9 @@ for i in &v {
Vectors have many more useful methods, which you can read about in [their
API documentation][vec].
-[vec]: ../std/vec/index.html
-[box]: ../std/boxed/index.html
+[vec]: ../../std/vec/index.html
+[box]: ../../std/boxed/index.html
[generic]: generics.html
[panic]: concurrency.html#panics
-[get]: ../std/vec/struct.Vec.html#method.get
-[get_mut]: ../std/vec/struct.Vec.html#method.get_mut
+[get]: ../../std/vec/struct.Vec.html#method.get
+[get_mut]: ../../std/vec/struct.Vec.html#method.get_mut
diff --git a/trpl-2nd-edition/SUMMARY.md b/trpl-2nd-edition/SUMMARY.md
new file mode 100644
index 0000000..a8f0158
--- /dev/null
+++ b/trpl-2nd-edition/SUMMARY.md
@@ -0,0 +1,123 @@
+# The Rust Programming Language
+
+## Getting started
+
+- [Introduction](ch01-00-introduction.md)
+ - [Installation](ch01-01-installation.md)
+ - [Hello, World!](ch01-02-hello-world.md)
+
+- [Guessing Game Tutorial](ch02-00-guessing-game-tutorial.md)
+
+- [Common Programming Concepts](ch03-00-common-programming-concepts.md)
+ - [Variables and Mutability](ch03-01-variables-and-mutability.md)
+ - [Data Types](ch03-02-data-types.md)
+ - [How Functions Work](ch03-03-how-functions-work.md)
+ - [Comments](ch03-04-comments.md)
+ - [Control Flow](ch03-05-control-flow.md)
+
+- [Understanding Ownership](ch04-00-understanding-ownership.md)
+ - [What is Ownership?](ch04-01-what-is-ownership.md)
+ - [References & Borrowing](ch04-02-references-and-borrowing.md)
+ - [Slices](ch04-03-slices.md)
+
+- [Structs](ch05-00-structs.md)
+ - [Method Syntax](ch05-01-method-syntax.md)
+
+- [Enums and Pattern Matching](ch06-00-enums.md)
+ - [Defining an Enum](ch06-01-defining-an-enum.md)
+ - [The `match` Control Flow Operator](ch06-02-match.md)
+ - [Concise Control Flow with `if let`](ch06-03-if-let.md)
+
+## Basic Rust Literacy
+
+- [Modules](ch07-00-modules.md)
+ - [`mod` and the Filesystem](ch07-01-mod-and-the-filesystem.md)
+ - [Controlling Visibility with `pub`](ch07-02-controlling-visibility-with-pub.md)
+ - [Importing Names with `use`](ch07-03-importing-names-with-use.md)
+
+- [Common Collections](ch08-00-common-collections.md)
+ - [Vectors](ch08-01-vectors.md)
+ - [Strings](ch08-02-strings.md)
+ - [Hash Maps](ch08-03-hash-maps.md)
+
+- [Error Handling](ch09-00-error-handling.md)
+ - [Unrecoverable Errors with `panic!`](ch09-01-unrecoverable-errors-with-panic.md)
+ - [Recoverable Errors with `Result`](ch09-02-recoverable-errors-with-result.md)
+ - [To `panic!` or Not To `panic!`](ch09-03-to-panic-or-not-to-panic.md)
+
+- [Generic Types, Traits, and Lifetimes](ch10-00-generics.md)
+ - [Generic Data Types](ch10-01-syntax.md)
+ - [Traits: Defining Shared Behavior](ch10-02-traits.md)
+ - [Validating References with Lifetimes](ch10-03-lifetime-syntax.md)
+
+- [Testing](ch11-00-testing.md)
+ - [Writing tests](ch11-01-writing-tests.md)
+ - [Running tests](ch11-02-running-tests.md)
+ - [Test Organization](ch11-03-test-organization.md)
+
+- [An I/O Project](ch12-00-an-io-project.md)
+ - [Accepting Command Line Arguments](ch12-01-accepting-command-line-arguments.md)
+ - [Reading a File](ch12-02-reading-a-file.md)
+ - [Improving Error Handling and Modularity](ch12-03-improving-error-handling-and-modularity.md)
+ - [Testing the Library's Functionality](ch12-04-testing-the-librarys-functionality.md)
+ - [Working with Environment Variables](ch12-05-working-with-environment-variables.md)
+ - [Writing to `stderr` instead of `stdout`](ch12-06-writing-to-stderr-instead-of-stdout.md)
+
+## Thinking in Rust
+
+- [Functional Language Features in Rust](ch13-00-functional-features.md)
+ - [Closures](ch13-01-closures.md)
+ - [Iterators](ch13-02-iterators.md)
+ - [Improving our I/O Project](ch13-03-improving-our-io-project.md)
+ - [Performance](ch13-04-performance.md)
+
+- [More about Cargo and Crates.io](ch14-00-more-about-cargo.md)
+ - [Release Profiles](ch14-01-release-profiles.md)
+ - [Publishing a Crate to Crates.io](ch14-02-publishing-to-crates-io.md)
+ - [Cargo Workspaces](ch14-03-cargo-workspaces.md)
+ - [Installing Binaries from Crates.io with `cargo install`](ch14-04-installing-binaries.md)
+ - [Extending Cargo with Custom Commands](ch14-05-extending-cargo.md)
+
+- [Smart Pointers](ch15-00-smart-pointers.md)
+ - [`Box` Points to Data on the Heap and Has a Known Size](ch15-01-box.md)
+ - [The `Deref` Trait Allows Access to the Data Through a Reference](ch15-02-deref.md)
+ - [The `Drop` Trait Runs Code on Cleanup](ch15-03-drop.md)
+ - [`Rc`, the Reference Counted Smart Pointer](ch15-04-rc.md)
+ - [`RefCell` and the Interior Mutability Pattern](ch15-05-interior-mutability.md)
+ - [Creating Reference Cycles and Leaking Memory is Safe](ch15-06-reference-cycles.md)
+
+- [Fearless Concurrency](ch16-00-concurrency.md)
+ - [Threads](ch16-01-threads.md)
+ - [Message Passing](ch16-02-message-passing.md)
+ - [Shared State](ch16-03-shared-state.md)
+ - [Extensible Concurrency: `Sync` and `Send`](ch16-04-extensible-concurrency-sync-and-send.md)
+
+- [Is Rust an Object-Oriented Programming Language?](ch17-00-oop.md)
+ - [What Does Object-Oriented Mean?](ch17-01-what-is-oo.md)
+ - [Trait Objects for Using Values of Different Types](ch17-02-trait-objects.md)
+ - [Object-Oriented Design Pattern Implementations](ch17-03-oo-design-patterns.md)
+
+## Advanced Topics
+
+- [Patterns Match the Structure of Values](ch18-00-patterns.md)
+ - [All the Places Patterns May be Used](ch18-01-all-the-places-for-patterns.md)
+ - [Refutability: Whether a Pattern Might Fail to Match](ch18-02-refutability.md)
+ - [All the Pattern Syntax](ch18-03-pattern-syntax.md)
+
+- [Advanced Features](ch19-00-advanced-features.md)
+ - [Unsafe Rust](ch19-01-unsafe-rust.md)
+ - [Advanced Lifetimes](ch19-02-advanced-lifetimes.md)
+ - [Advanced Traits](ch19-03-advanced-traits.md)
+ - [Advanced Types](ch19-04-advanced-types.md)
+ - [Advanced Functions & Closures](ch19-05-advanced-functions-and-closures.md)
+
+- [Final project: a web server](ch20-00-final-project-a-web-server.md)
+
+- [Appendix](appendix-00.md)
+ - [A - Keywords](appendix-01-keywords.md)
+ - [B - Operators](appendix-02-operators.md)
+ - [C - Derivable Traits]()
+ - [D - Nightly Rust]()
+ - [E - Macros]()
+ - [F - Translations]()
+ - [G - Newest Features](appendix-07-newest-features.md)
diff --git a/trpl-2nd-edition/appendix-00.md b/trpl-2nd-edition/appendix-00.md
new file mode 100644
index 0000000..83a7e91
--- /dev/null
+++ b/trpl-2nd-edition/appendix-00.md
@@ -0,0 +1,4 @@
+# Appendix
+
+The following sections contain reference material you may find useful in your
+Rust journey.
diff --git a/trpl-2nd-edition/appendix-01-keywords.md b/trpl-2nd-edition/appendix-01-keywords.md
new file mode 100644
index 0000000..f578103
--- /dev/null
+++ b/trpl-2nd-edition/appendix-01-keywords.md
@@ -0,0 +1,70 @@
+## Appendix A: Keywords
+
+The following keywords are reserved by the Rust language and may not be used as
+identifiers such as names of functions, variables, parameters, struct fields,
+modules, crates, constants, macros, static values, attributes, types, traits,
+or lifetimes.
+
+### Keywords Currently in Use
+
+* `as` - primitive casting, disambiguating the specific trait containing an
+ item, or renaming items in `use` and `extern crate` statements
+* `break` - exit a loop immediately
+* `const` - constant items and constant raw pointers
+* `continue` - continue to the next loop iteration
+* `crate` - external crate linkage or a macro variable representing the crate
+ in which the macro is defined
+* `else` - fallback for `if` and `if let` control flow constructs
+* `enum` - defining an enumeration
+* `extern` - external crate, function, and variable linkage
+* `false` - boolean false literal
+* `fn` - function definition and function pointer type
+* `for` - iterator loop, part of trait impl syntax, and higher-ranked lifetime
+ syntax
+* `if` - conditional branching
+* `impl` - inherent and trait implementation block
+* `in` - part of `for` loop syntax
+* `let` - variable binding
+* `loop` - unconditional, infinite loop
+* `match` - pattern matching
+* `mod` - module declaration
+* `move` - makes a closure take ownership of all its captures
+* `mut` - denotes mutability in references, raw pointers, and pattern bindings
+* `pub` - denotes public visibility in struct fields, `impl` blocks, and modules
+* `ref` - by-reference binding
+* `return` - return from function
+* `Self` - type alias for the type implementing a trait
+* `self` - method subject or current module
+* `static` - global variable or lifetime lasting the entire program execution
+* `struct` - structure definition
+* `super` - parent module of the current module
+* `trait` - trait definition
+* `true` - boolean true literal
+* `type` - type alias and associated type definition
+* `unsafe` - denotes unsafe code, functions, traits, and implementations
+* `use` - import symbols into scope
+* `where` - type constraint clauses
+* `while` - conditional loop
+
+### Keywords Reserved for Future Use
+
+These keywords do not have any functionality, but are reserved by Rust for
+potential future use.
+
+* `abstract`
+* `alignof`
+* `become`
+* `box`
+* `do`
+* `final`
+* `macro`
+* `offsetof`
+* `override`
+* `priv`
+* `proc`
+* `pure`
+* `sizeof`
+* `typeof`
+* `unsized`
+* `virtual`
+* `yield`
diff --git a/trpl-2nd-edition/appendix-02-operators.md b/trpl-2nd-edition/appendix-02-operators.md
new file mode 100644
index 0000000..afc0a19
--- /dev/null
+++ b/trpl-2nd-edition/appendix-02-operators.md
@@ -0,0 +1,195 @@
+## Appendix B: Operators
+
+### Unary operator expressions
+
+Rust defines the following unary operators. They are all written as prefix
+operators, before the expression they apply to.
+
+* `-`
+ : Negation. Signed integer types and floating-point types support negation. It
+ is an error to apply negation to unsigned types; for example, the compiler
+ rejects `-1u32`.
+* `*`
+ : Dereference. When applied to a pointer, it denotes the pointed-to location.
+ For pointers to mutable locations, the resulting value can be assigned to.
+ On non-pointer types, it calls the `deref` method of the `std::ops::Deref`
+ trait, or the `deref_mut` method of the `std::ops::DerefMut` trait (if
+ implemented by the type and required for an outer expression that will or
+ could mutate the dereference), and produces the result of dereferencing the
+ `&` or `&mut` borrowed pointer returned from the overload method.
+* `!`
+ : Logical negation. On the boolean type, this flips between `true` and
+ `false`. On integer types, this inverts the individual bits in the
+ two's complement representation of the value.
+* `&` and `&mut`
+ : Borrowing. When applied to a value, these operators produce a
+ reference (pointer) to that value. The value is also placed into
+ a borrowed state for the duration of the reference. For a shared
+ borrow (`&`), this implies that the value may not be mutated, but
+ it may be read or shared again. For a mutable borrow (`&mut`), the
+ value may not be accessed in any way until the borrow expires.
+
+### Binary operator expressions
+
+Binary operators expressions are given in order of operator precedence.
+
+#### Arithmetic operators
+
+Binary arithmetic expressions are syntactic sugar for calls to built-in traits,
+defined in the `std::ops` module of the `std` library. This means arithmetic
+operators can be overridden for user-defined types. The default meaning of the
+operators on standard types is given here.
+
+* `+`
+ : Addition and array/string concatenation.
+ Calls the `add` method on the `std::ops::Add` trait.
+* `-`
+ : Subtraction.
+ Calls the `sub` method on the `std::ops::Sub` trait.
+* `*`
+ : Multiplication.
+ Calls the `mul` method on the `std::ops::Mul` trait.
+* `/`
+ : Quotient.
+ Calls the `div` method on the `std::ops::Div` trait.
+* `%`
+ : Remainder.
+ Calls the `rem` method on the `std::ops::Rem` trait.
+
+Note that Rust does not have a built-in operator for exponential (power)
+calculation; see the `pow` method on the numeric types.
+
+#### Bitwise operators
+
+Like the arithmetic operators, bitwise operators are syntactic sugar for calls
+to methods of built-in traits. This means bitwise operators can be overridden
+for user-defined types. The default meaning of the operators on standard types
+is given here. Bitwise `&`, `|` and `^` applied to boolean arguments are
+equivalent to logical `&&`, `||` and `!=` evaluated in non-lazy fashion.
+
+* `&`
+ : Bitwise AND.
+ Calls the `bitand` method of the `std::ops::BitAnd` trait.
+* `|`
+ : Bitwise inclusive OR.
+ Calls the `bitor` method of the `std::ops::BitOr` trait.
+* `^`
+ : Bitwise exclusive OR.
+ Calls the `bitxor` method of the `std::ops::BitXor` trait.
+* `<<`
+ : Left shift.
+ Calls the `shl` method of the `std::ops::Shl` trait.
+* `>>`
+ : Right shift (arithmetic).
+ Calls the `shr` method of the `std::ops::Shr` trait.
+
+#### Lazy boolean operators
+
+The operators `||` and `&&` may be applied to operands of boolean type. The
+`||` operator denotes logical 'or', and the `&&` operator denotes logical
+'and'. They differ from `|` and `&` in that the right-hand operand is only
+evaluated when the left-hand operand does not already determine the result of
+the expression. That is, `||` only evaluates its right-hand operand when the
+left-hand operand evaluates to `false`, and `&&` only when it evaluates to
+`true`.
+
+#### Comparison operators
+
+Comparison operators are, like the arithmetic operators and bitwise operators,
+syntactic sugar for calls to built-in traits. This means that comparison
+operators can be overridden for user-defined types. The default meaning of the
+operators on standard types is given here.
+
+* `==`
+ : Equal to.
+ Calls the `eq` method on the `std::cmp::PartialEq` trait.
+* `!=`
+ : Unequal to.
+ Calls the `ne` method on the `std::cmp::PartialEq` trait.
+* `<`
+ : Less than.
+ Calls the `lt` method on the `std::cmp::PartialOrd` trait.
+* `>`
+ : Greater than.
+ Calls the `gt` method on the `std::cmp::PartialOrd` trait.
+* `<=`
+ : Less than or equal.
+ Calls the `le` method on the `std::cmp::PartialOrd` trait.
+* `>=`
+ : Greater than or equal.
+ Calls the `ge` method on the `std::cmp::PartialOrd` trait.
+
+#### Type cast expressions
+
+A type cast expression is denoted with the binary operator `as`.
+
+Executing an `as` expression casts the value on the left-hand side to the type
+on the right-hand side.
+
+An example of an `as` expression:
+
+```rust
+# fn sum(values: &[f64]) -> f64 { 0.0 }
+# fn len(values: &[f64]) -> i32 { 0 }
+
+fn average(values: &[f64]) -> f64 {
+ let sum: f64 = sum(values);
+ let size: f64 = len(values) as f64;
+ sum / size
+}
+```
+
+Some of the conversions which can be done through the `as` operator
+can also be done implicitly at various points in the program, such as
+argument passing and assignment to a `let` binding with an explicit
+type. 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.
+
+#### Assignment expressions
+
+An *assignment expression* consists of a pattern followed by an equals
+sign (`=`) and an expression.
+
+Evaluating an assignment expression either copies or
+moves its right-hand operand to its left-hand
+operand.
+
+```
+# let mut x = 0;
+# let y = 0;
+x = y;
+```
+
+#### Compound assignment expressions
+
+The `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `<<`, and `>>` operators may be
+composed with the `=` operator. The expression `lval OP= val` is equivalent to
+`lval = lval OP val`. For example, `x = x + 1` may be written as `x += 1`.
+
+Any such expression always has the `unit` type.
+
+#### Operator precedence
+
+The precedence of Rust binary operators is ordered as follows, going from
+strong to weak:
+
+```text
+as :
+* / %
++ -
+<< >>
+&
+^
+|
+== != < > <= >=
+&&
+||
+.. ...
+<-
+=
+```
+
+Operators at the same precedence level are evaluated left-to-right. Unary
+operators have the same precedence level and are stronger than any of the
+binary operators.
diff --git a/trpl-2nd-edition/appendix-06-translation.md b/trpl-2nd-edition/appendix-06-translation.md
new file mode 100644
index 0000000..0c38ba1
--- /dev/null
+++ b/trpl-2nd-edition/appendix-06-translation.md
@@ -0,0 +1,11 @@
+## Appendix F: Translations of the Book
+
+For resources in languages other than English. Most are still in progress; see
+[the Translations label][label] to help or let us know about a new translation!
+
+[label]: https://github.com/rust-lang/book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations
+
+- [Português](https://coreh.github.io/rust-book-pt-br/)
+- [Tiếng việt](https://rust-vietnam.github.io/book/)
+- [简体中文](http://www.broadview.com.cn/article/144), [alternate](https://github.com/KaiserY/trpl-zh-cn)
+- [українська мова](https://github.com/pavloslav/rust-book-uk-ua)
diff --git a/trpl-2nd-edition/appendix-07-newest-features.md b/trpl-2nd-edition/appendix-07-newest-features.md
new file mode 100644
index 0000000..e388617
--- /dev/null
+++ b/trpl-2nd-edition/appendix-07-newest-features.md
@@ -0,0 +1,35 @@
+# Appendix G - Newest Features
+
+This appendix documents features that have been added to stable Rust since the
+main part of the book was completed.
+
+
+## Field init shorthand
+
+We can initialize a data structure (struct, enum, union) with named
+fields, by writing `fieldname` as a shorthand for `fieldname: fieldname`.
+This allows a compact syntax for initialization, with less duplication:
+
+```rust
+#[derive(Debug)]
+struct Person {
+ name: String,
+ age: u8,
+}
+
+fn main() {
+ let name = String::from("Peter");
+ let age = 27;
+
+ // Using full syntax:
+ let peter = Person { name: name, age: age };
+
+ let name = String::from("Portia");
+ let age = 27;
+
+ // Using field init shorthand:
+ let portia = Person { name, age };
+
+ println!("{:?}", portia);
+}
+```
diff --git a/trpl-2nd-edition/ch01-00-introduction.md b/trpl-2nd-edition/ch01-00-introduction.md
new file mode 100644
index 0000000..c201c8b
--- /dev/null
+++ b/trpl-2nd-edition/ch01-00-introduction.md
@@ -0,0 +1,35 @@
+# Introduction
+
+Welcome to “The Rust Programming Language,” an introductory book about Rust.
+Rust is a programming language that’s focused on safety, speed, and
+concurrency. Its design lets you create programs that have the performance and
+control of a low-level language, but with the powerful abstractions of a
+high-level language. These properties make Rust suitable for programmers who
+have experience in languages like C and are looking for a safer alternative, as
+well as those from languages like Python who are looking for ways to write code
+that performs better without sacrificing expressiveness.
+
+Rust performs the majority of its safety checks and memory management decisions
+at compile time, so that your program's runtime performance isn't impacted. This
+makes it useful in a number of use cases that other languages aren’t good at:
+programs with predictable space and time requirements, embedding in other
+languages, and writing low-level code, like device drivers and operating
+systems. It's also great for web applications: it powers the Rust package
+registry site, [crates.io]! We're excited to see what *you* create with Rust.
+
+[crates.io]: https://crates.io/
+
+This book is written for a reader who already knows how to program in at least
+one programming language. After reading this book, you should be comfortable
+writing Rust programs. We’ll be learning Rust through small, focused examples
+that build on each other to demonstrate how to use various features of Rust as
+well as how they work behind the scenes.
+
+## Contributing to the book
+
+This book is open source. If you find an error, please don’t hesitate to file an
+issue or send a pull request [on GitHub]. Please see [CONTRIBUTING.md] for
+more details.
+
+[on GitHub]: https://github.com/rust-lang/book
+[CONTRIBUTING.md]: https://github.com/rust-lang/book/blob/master/CONTRIBUTING.md
diff --git a/trpl-2nd-edition/ch01-01-installation.md b/trpl-2nd-edition/ch01-01-installation.md
new file mode 100644
index 0000000..6a6f272
--- /dev/null
+++ b/trpl-2nd-edition/ch01-01-installation.md
@@ -0,0 +1,107 @@
+## Installation
+
+The first step to using Rust is to install it. You’ll need an internet
+connection to run the commands in this chapter, as we’ll be downloading Rust
+from the internet.
+
+We’ll be showing off a number of commands using a terminal, and those lines all
+start with `$`. You don't need to type in the `$` character; they are there to indicate
+the start of each command. You’ll see many tutorials and examples around the web
+that follow this convention: `$` for commands run as a regular user, and `#`
+for commands you should be running as an administrator. Lines that don't start
+with `$` are typically showing the output of the previous command.
+
+### Installing on Linux or Mac
+
+If you're on Linux or a Mac, all you need to do is open a terminal and type
+this:
+
+```text
+$ curl https://sh.rustup.rs -sSf | sh
+```
+
+This will download a script and start the installation. You may be prompted for
+your password. If it all goes well, you’ll see this appear:
+
+```text
+Rust is installed now. Great!
+```
+
+Of course, if you disapprove of the `curl | sh` pattern, you can download, inspect
+and run the script however you like.
+
+### Installing on Windows
+
+On Windows, go to [https://rustup.rs](https://rustup.rs/) and
+follow the instructions to download rustup-init.exe. Run that and follow the
+rest of the instructions it gives you.
+
+The rest of the Windows-specific commands in the book will assume that you are
+using `cmd` as your shell. If you use a different shell, you may be able to run
+the same commands that Linux and Mac users do. If neither work, consult the
+documentation for the shell you are using.
+
+### Custom installations
+
+If you have reasons for preferring not to use rustup.rs, please see [the Rust
+installation page](https://www.rust-lang.org/install.html) for other options.
+
+### Updating
+
+Once you have Rust installed, updating to the latest version is easy.
+From your shell, run the update script:
+
+```text
+$ rustup update
+```
+
+### Uninstalling
+
+Uninstalling Rust is as easy as installing it. From your shell, run
+the uninstall script:
+
+```text
+$ rustup self uninstall
+```
+
+### Troubleshooting
+
+If you've got Rust installed, you can open up a shell, and type this:
+
+```text
+$ rustc --version
+```
+
+You should see the version number, commit hash, and commit date in a format
+similar to this for the latest stable version at the time you install:
+
+```text
+rustc x.y.z (abcabcabc yyyy-mm-dd)
+```
+
+If you see this, Rust has been installed successfully!
+Congrats!
+
+If you don't and you're on Windows, check that Rust is in your `%PATH%` system
+variable.
+
+If it still isn't working, there are a number of places where you can get help.
+The easiest is [the #rust IRC channel on irc.mozilla.org][irc],
+which you can access through [Mibbit][mibbit]. Go to that address, and you'll
+be chatting with other Rustaceans (a silly nickname we call ourselves) who can
+help you out. Other great resources include [the Users forum][users] and
+[Stack Overflow][stackoverflow].
+
+[irc]: irc://irc.mozilla.org/#rust
+[mibbit]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
+[users]: https://users.rust-lang.org/
+[stackoverflow]: http://stackoverflow.com/questions/tagged/rust
+
+### Local documentation
+
+The installer also includes a copy of the documentation locally, so you can
+read it offline. Run `rustup doc` to open the local documentation in your
+browser.
+
+Any time there's a type or function provided by the standard library and you're
+not sure what it does, use the API documentation to find out!
diff --git a/trpl-2nd-edition/ch01-02-hello-world.md b/trpl-2nd-edition/ch01-02-hello-world.md
new file mode 100644
index 0000000..6cfdfc2
--- /dev/null
+++ b/trpl-2nd-edition/ch01-02-hello-world.md
@@ -0,0 +1,404 @@
+## Hello, World!
+
+Now that you have Rust installed, let’s write your first Rust program. It's
+traditional when learning a new language to write a little program to print the
+text “Hello, world!” to the screen, and in this section, we'll follow that
+tradition.
+
+> Note: This book assumes basic familiarity with the command line. Rust itself
+> makes no specific demands about your editing, tooling, or where your code
+> lives, so if you prefer an IDE to the command line, feel free to use your
+> favorite IDE.
+
+### Creating a Project Directory
+
+First, make a directory to put your Rust code in. Rust doesn't care where your code
+lives, but for this book, we'd suggest making a *projects* directory in your
+home directory and keeping all your projects there. Open a terminal and enter
+the following commands to make a directory for this particular project:
+
+Linux and Mac:
+
+```text
+$ mkdir ~/projects
+$ cd ~/projects
+$ mkdir hello_world
+$ cd hello_world
+```
+
+Windows:
+
+```cmd
+> mkdir %USERPROFILE%\projects
+> cd %USERPROFILE%\projects
+> mkdir hello_world
+> cd hello_world
+```
+
+### Writing and Running a Rust Program
+
+Next, make a new source file and call it *main.rs*. Rust files always end with
+the *.rs* extension. If you’re using more than one word in your filename, use
+an underscore to separate them. For example, you'd use *hello_world.rs* rather
+than *helloworld.rs*.
+
+Now open the *main.rs* file you just created, and type the following code:
+
+Filename: main.rs
+
+```rust
+fn main() {
+ println!("Hello, world!");
+}
+```
+
+Save the file, and go back to your terminal window. On Linux or OSX, enter the
+following commands:
+
+```text
+$ rustc main.rs
+$ ./main
+Hello, world!
+```
+
+On Windows, run `.\main.exe` instead of `./main`. Regardless of your
+operating system, you should see the string `Hello, world!` print to the
+terminal. If you did, then congratulations! You've officially written a Rust
+program. That makes you a Rust programmer! Welcome.
+
+### Anatomy of a Rust Program
+
+Now, let’s go over what just happened in your "Hello, world!" program in
+detail. Here's the first piece of the puzzle:
+
+```rust
+fn main() {
+
+}
+```
+
+These lines define a *function* in Rust. The `main` function is special: it's
+the first thing that is run for every executable Rust program. The first line
+says, “I’m declaring a function named `main` that has no parameters and returns
+nothing.” If there were parameters, their names would go inside the
+parentheses, `(` and `)`.
+
+Also note that the function body is wrapped in curly braces, `{` and `}`. Rust
+requires these around all function bodies. It's considered good style to put
+the opening curly brace on the same line as the function declaration, with one
+space in between.
+
+Inside the `main` function:
+
+```rust
+ println!("Hello, world!");
+```
+
+This line does all of the work in this little program: it prints text to the
+screen. There are a number of details to notice here. The first is that Rust
+style is to indent with four spaces, not a tab.
+
+The second important part is `println!`. This is calling a Rust *macro*,
+which is how metaprogramming is done in Rust. If it were calling a function
+instead, it would look like this: `println` (without the `!`). We'll discuss
+Rust macros in more detail in Appendix E, but for now you just need to know
+that when you see a `!` that means that you’re calling a macro instead of a
+normal function.
+
+Next is `"Hello, world!"` which is a *string*. We pass this string as an
+argument to `println!`, which prints the string to the screen. Easy enough!
+
+The line ends with a semicolon (`;`). The `;` indicates that this expression is
+over, and the next one is ready to begin. Most lines of Rust code end with a
+`;`.
+
+### Compiling and Running Are Separate Steps
+
+In "Writing and Running a Rust Program", we showed you how to run a newly
+created program. We'll break that process down and examine each step now.
+
+Before running a Rust program, you have to compile it. You can use the Rust
+compiler by entering the `rustc` command and passing it the name of your source
+file, like this:
+
+```text
+$ rustc main.rs
+```
+
+If you come from a C or C++ background, you'll notice that this is similar to
+`gcc` or `clang`. After compiling successfully, Rust should output a binary
+executable, which you can see on Linux or OSX by entering the `ls` command in
+your shell as follows:
+
+```text
+$ ls
+main main.rs
+```
+
+On Windows, you'd enter:
+
+```cmd
+> dir /B %= the /B option says to only show the file names =%
+main.exe
+main.rs
+```
+
+This shows we have two files: the source code, with the *.rs* extension, and the
+executable (*main.exe* on Windows, *main* everywhere else). All that's left to
+do from here is run the *main* or *main.exe* file, like this:
+
+```text
+$ ./main # or .\main.exe on Windows
+```
+
+If *main.rs* were your "Hello, world!" program, this would print `Hello,
+world!` to your terminal.
+
+If you come from a dynamic language like Ruby, Python, or JavaScript, you may
+not be used to compiling and running a program being separate steps. Rust is an
+*ahead-of-time compiled* language, which means that you can compile a program,
+give it to someone else, and they can run it even without having Rust
+installed. If you give someone a `.rb`, `.py`, or `.js` file, on the other
+hand, they need to have a Ruby, Python, or JavaScript implementation installed
+(respectively), but you only need one command to both compile and run your
+program. Everything is a tradeoff in language design.
+
+Just compiling with `rustc` is fine for simple programs, but as your project
+grows, you'll want to be able to manage all of the options your project has
+and make it easy to share your code with other people and projects. Next, we'll
+introduce you to a tool called Cargo, which will help you write real-world Rust
+programs.
+
+## Hello, Cargo!
+
+Cargo is Rust’s build system and package manager, and Rustaceans use Cargo to
+manage their Rust projects because it makes a lot of tasks easier. For example,
+Cargo takes care of building your code, downloading the libraries your code
+depends on, and building those libraries. We call libraries your code needs
+*dependencies*.
+
+The simplest Rust programs, like the one we've written so far, don’t have any
+dependencies, so right now, you'd only be using the part of Cargo that can take
+care of building your code. As you write more complex Rust programs, you’ll
+want to add dependencies, and if you start off using Cargo, that will be a lot
+easier to do.
+
+As the vast, vast majority of Rust projects use Cargo, we will assume that
+you’re using it for the rest of the book. Cargo comes installed with Rust
+itself, if you used the official installers as covered in the Installation
+chapter. If you installed Rust through some other means, you can check if you
+have Cargo installed by typing the following into your terminal:
+
+```text
+$ cargo --version
+```
+
+If you see a version number, great! If you see an error like `command not
+found`, then you should look at the documentation for your method of
+installation to determine how to install Cargo separately.
+
+### Creating a Project with Cargo
+
+Let's create a new project using Cargo and look at how it differs from our
+project in `hello_world`. Go back to your projects directory (or wherever you
+decided to put your code):
+
+Linux and Mac:
+
+```text
+$ cd ~/projects
+```
+
+Windows:
+
+```cmd
+> cd %USERPROFILE%\projects
+```
+
+And then on any operating system run:
+
+```text
+$ cargo new hello_cargo --bin
+$ cd hello_cargo
+```
+
+We passed the `--bin` argument to `cargo new` because our goal is to make an
+executable application, as opposed to a library. Executables are binary
+executable files often called just *binaries*. We've given `hello_cargo`
+as the name for our project, and Cargo creates its files in a directory
+of the same name that we can then go into.
+
+If we list the files in the *hello_cargo* directory, we can see that Cargo has
+generated two files and one directory for us: a *Cargo.toml* and a *src*
+directory with a *main.rs* file inside. It has also initialized a new git
+repository in the *hello_cargo* directory for us, along with a *.gitignore*
+file; you can change this to use a different version control system, or no
+version control system, by using the `--vcs` flag.
+
+Open up *Cargo.toml* in your text editor of choice. It should look something
+like this:
+
+Filename: Cargo.toml
+
+```toml
+[package]
+name = "hello_cargo"
+version = "0.1.0"
+authors = ["Your Name "]
+
+[dependencies]
+```
+
+This file is in the [*TOML*][toml] (Tom's Obvious, Minimal
+Language) format. TOML is similar to INI but has some extra goodies and is used
+as Cargo’s configuration format.
+
+[toml]: https://github.com/toml-lang/toml
+
+The first line, `[package]`, is a section heading that indicates that the
+following statements are configuring a package. As we add more information to
+this file, we’ll add other sections.
+
+The next three lines set the three bits of configuration that Cargo needs to
+see in order to know that it should compile your program: its name, what
+version it is, and who wrote it. Cargo gets your name and email information
+from your environment. If it’s not correct, go ahead and fix that and save the
+file.
+
+The last line, `[dependencies]`, is the start of a section for you to list any
+*crates* (which is what we call packages of Rust code) that your project will
+depend on so that Cargo knows to download and compile those too. We won't need
+any other crates for this project, but we will in the guessing game tutorial in
+the next chapter.
+
+Now let's look at *src/main.rs*:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ println!("Hello, world!");
+}
+```
+
+Cargo has generated a "Hello World!" for you, just like the one we wrote
+earlier! So that part is the same. The differences between our previous project
+and the project generated by Cargo that we've seen so far are:
+
+- Our code goes in the *src* directory
+- The top level contains a *Cargo.toml* configuration file
+
+Cargo expects your source files to live inside the *src* directory so that the
+top-level project directory is just for READMEs, license information,
+configuration files, and anything else not related to your code. In this way,
+using Cargo helps you keep your projects nice and tidy. There's a place for
+everything, and everything is in its place.
+
+If you started a project that doesn't use Cargo, as we did with our project in
+the *hello_world* directory, you can convert it to a project that does use
+Cargo by moving your code into the *src* directory and creating an appropriate
+*Cargo.toml*.
+
+### Building and Running a Cargo Project
+
+Now let's look at what's different about building and running your Hello World
+program through Cargo! To do so, enter the following commands:
+
+```text
+$ cargo build
+ Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
+```
+
+This should have created an executable file which you can run with this command:
+
+```text
+$ ./target/debug/hello_cargo # or .\target\debug\hello_cargo.exe on Windows
+Hello, world!
+```
+
+Bam! If all goes well, `Hello, world!` should print to the terminal once more.
+
+Running `cargo build` for the first time also causes Cargo to create a new file
+at the top level called *Cargo.lock*, which looks like this:
+
+Filename: Cargo.lock
+
+```toml
+[root]
+name = "hello_cargo"
+version = "0.1.0"
+```
+
+Cargo uses the *Cargo.lock* to keep track of dependencies in your application.
+This project doesn't have dependencies, so the file is a bit sparse.
+Realistically, you won't ever need to touch this file yourself; just let Cargo
+handle it.
+
+We just built a project with `cargo build` and ran it with
+`./target/debug/hello_cargo`, but we can also use `cargo run` to compile
+and then run:
+
+```text
+$ cargo run
+ Running `target/debug/hello_cargo`
+Hello, world!
+```
+
+Notice that this time, we didn't see the output telling us that Cargo was
+compiling `hello_cargo`. Cargo figured out that the files haven’t changed, so
+it just ran the binary. If you had modified your source code, Cargo would have
+rebuilt the project before running it, and you would have seen something like
+this:
+
+```text
+$ cargo run
+ Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
+ Running `target/debug/hello_cargo`
+Hello, world!
+```
+
+So a few more differences we've now seen:
+
+- Instead of using `rustc`, build a project using `cargo build` (or build and
+ run it in one step with `cargo run`)
+- Instead of the result of the build being put in the same directory as our
+ code, Cargo will put it in the *target/debug* directory.
+
+The other advantage of using Cargo is that the commands are the same no matter
+what operating system you're on, so at this point we will no longer be
+providing specific instructions for Linux and Mac versus Windows.
+
+### Building for Release
+
+When your project is finally ready for release, you can use `cargo build
+--release` to compile your project with optimizations. This will create an
+executable in *target/release* instead of *target/debug*. These optimizations
+make your Rust code run faster, but turning them on makes your program take
+longer to compile. This is why there are two different profiles: one for
+development when you want to be able to rebuild quickly and often, and one for
+building the final program you’ll give to a user that won't be rebuilt and
+that we want to run as fast as possible. If you're benchmarking the running
+time of your code, be sure to run `cargo build --release` and benchmark with
+the executable in *target/release*.
+
+### Cargo as Convention
+
+With simple projects, Cargo doesn't provide a whole lot of value over just
+using `rustc`, but it will prove its worth as you continue. With complex
+projects composed of multiple crates, it’s much easier to let Cargo coordinate
+the build. With Cargo, you can just run `cargo build`, and it should work the
+right way. Even though this project is simple, it now uses much of the real
+tooling you’ll use for the rest of your Rust career. In fact, you can get
+started with virtually all Rust projects you want to work
+on with the following commands:
+
+```text
+$ git clone someurl.com/someproject
+$ cd someproject
+$ cargo build
+```
+
+> Note: If you want to look at Cargo in more detail, check out the official
+[Cargo guide], which covers all of its features.
+
+[Cargo guide]: http://doc.crates.io/guide.html
diff --git a/trpl-2nd-edition/ch02-00-guessing-game-tutorial.md b/trpl-2nd-edition/ch02-00-guessing-game-tutorial.md
new file mode 100644
index 0000000..51bfcee
--- /dev/null
+++ b/trpl-2nd-edition/ch02-00-guessing-game-tutorial.md
@@ -0,0 +1,1064 @@
+# Guessing Game
+
+Let’s jump into Rust by working through a hands-on project together! This
+chapter introduces you to a few common Rust concepts by showing you how to use
+them in a real program. You’ll learn about `let`, `match`, methods, associated
+functions, using external crates, and more! The following chapters will explore
+these ideas in more detail. In this chapter, you’ll practice the fundamentals.
+
+We’ll implement a classic beginner programming problem: a guessing game. Here’s
+how it works: the program will generate a random integer between 1 and 100. It
+will then prompt the player to enter a guess. After entering a guess, it will
+indicate whether the guess is too low or too high. If the guess is correct, the
+game will print congratulations and exit.
+
+## Setting Up a New Project
+
+To set up a new project, go to the *projects* directory that you created in
+Chapter 1, and make a new project using Cargo, like so:
+
+```text
+$ cargo new guessing_game --bin
+$ cd guessing_game
+```
+
+The first command, `cargo new`, takes the name of the project (`guessing_game`)
+as the first argument. The `--bin` flag tells Cargo to make a binary project,
+similar to the one in Chapter 1. The second command changes to the new
+project’s directory.
+
+Look at the generated *Cargo.toml* file:
+
+Filename: Cargo.toml
+
+```toml
+[package]
+name = "guessing_game"
+version = "0.1.0"
+authors = ["Your Name "]
+
+[dependencies]
+```
+
+If the author information that Cargo obtained from your environment is not
+correct, fix that in the file and save it again.
+
+As you saw in Chapter 1, `cargo new` generates a “Hello, world!” program for
+you. Check out the *src/main.rs* file:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ println!("Hello, world!");
+}
+```
+
+Now let’s compile this “Hello, world!” program and run it in the same step
+using the `cargo run` command:
+
+```text
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Running `target/debug/guessing_game`
+Hello, world!
+```
+
+The `run` command comes in handy when you need to rapidly iterate on a project,
+and this game is such a project: we want to quickly test each iteration
+before moving on to the next one.
+
+Reopen the *src/main.rs* file. You’ll be writing all the code in this file.
+
+## Processing a Guess
+
+The first part of the program will ask for user input, process that input, and
+check that the input is in the expected form. To start, we’ll allow the player
+to input a guess. Enter the code in Listing 2-1 into *src/main.rs*.
+
+Filename: src/main.rs
+
+```rust,ignore
+use std::io;
+
+fn main() {
+ println!("Guess the number!");
+
+ println!("Please input your guess.");
+
+ let mut guess = String::new();
+
+ io::stdin().read_line(&mut guess)
+ .expect("Failed to read line");
+
+ println!("You guessed: {}", guess);
+}
+```
+
+Listing 2-1: Code to get a guess from the user and print it out
+
+This code contains a lot of information, so let’s go over it bit by bit. To
+obtain user input and then print the result as output, we need to bring the
+`io` (input/output) library into scope. The `io` library comes from the
+standard library (which is known as `std`):
+
+```rust,ignore
+use std::io;
+```
+
+By default, Rust brings only a few types into the scope of every program in
+[the *prelude*][prelude]. If a type you want to use isn’t in the
+prelude, you have to bring that type into scope explicitly with a `use`
+statement. Using the `std::io` library provides you with a number of useful
+`io`-related features, including the functionality to accept user input.
+
+[prelude]: ../../std/prelude/index.html
+
+As you saw in Chapter 1, the `main` function is the entry point into the
+program:
+
+```rust,ignore
+fn main() {
+```
+
+The `fn` syntax declares a new function, the `()` indicate there are no
+parameters, and `{` starts the body of the function.
+
+As you also learned in Chapter 1, `println!` is a macro that prints a string to
+the screen:
+
+```rust,ignore
+println!("Guess the number!");
+
+println!("Please input your guess.");
+```
+
+This code is just printing a prompt stating what the game is and requesting
+input from the user.
+
+### Storing Values with Variables
+
+Next, we’ll create a place to store the user input, like this:
+
+```rust,ignore
+let mut guess = String::new();
+```
+
+Now the program is getting interesting! There’s a lot going on in this little
+line. Notice that this is a `let` statement, which is used to create
+*variables*. Here’s another example:
+
+```rust,ignore
+let foo = bar;
+```
+
+This line will create a new variable named `foo` and bind it to the value
+`bar`. In Rust, variables are immutable by default. The following example shows
+how to use `mut` before the variable name to make a variable mutable:
+
+```rust
+let foo = 5; // immutable
+let mut bar = 5; // mutable
+```
+
+> Note: The `//` syntax starts a comment that continues until the end of the
+> line. Rust ignores everything in comments.
+
+Now you know that `let mut guess` will introduce a mutable variable named
+`guess`. On the other side of the equal sign (`=`) is the value that `guess` is
+bound to, which is the result of calling `String::new`, a function that returns
+a new instance of a `String`. [`String`][string] is a string
+type provided by the standard library that is a growable, UTF-8 encoded bit of
+text.
+
+[string]: ../../std/string/struct.String.html
+
+The `::` syntax in the `::new` line indicates that `new` is an *associated
+function* of the `String` type. An associated function is implemented on a type,
+in this case `String`, rather than on a particular instance of a `String`. Some
+languages call this a *static method*.
+
+This `new` function creates a new, empty `String`. You’ll find a `new` function
+on many types, because it’s a common name for a function that makes a new value
+of some kind.
+
+To summarize, the `let mut guess = String::new();` line has created a mutable
+variable that is currently bound to a new, empty instance of a `String`. Whew!
+
+Recall that we included the input/output functionality from the standard
+library with `use std::io;` on the first line of the program. Now we’ll call an
+associated function, `stdin`, on `io`:
+
+```rust,ignore
+io::stdin().read_line(&mut guess)
+ .expect("Failed to read line");
+```
+
+If we didn’t have the `use std::io` line at the beginning of the program, we
+could have written this function call as `std::io::stdin`. The `stdin` function
+returns an instance of [`std::io::Stdin`][iostdin], which is a
+type that represents a handle to the standard input for your terminal.
+
+[iostdin]: ../../std/io/struct.Stdin.html
+
+The next part of the code, `.read_line(&mut guess)`, calls the
+[`read_line`][read_line] method on the standard input handle to
+get input from the user. We’re also passing one argument to `read_line`: `&mut
+guess`.
+
+[read_line]: ../../std/io/struct.Stdin.html#method.read_line
+
+The job of `read_line` is to take whatever the user types into standard input
+and place that into a string, so it takes that string as an argument. The
+string argument needs to be mutable so the method can change the string’s
+content by adding the user input.
+
+The `&` indicates that this argument is a *reference*, which gives you a way to
+let multiple parts of your code access one piece of data without needing to
+copy that data into memory multiple times. References are a complex feature,
+and one of Rust’s major advantages is how safe and easy it is to use
+references. You don’t need to know a lot of those details to finish this
+program: Chapter 4 will explain references more thoroughly. For now, all you
+need to know is that like variables, references are immutable by default.
+Hence, we need to write `&mut guess` rather than `&guess` to make it mutable.
+
+We’re not quite done with this line of code. Although it’s a single line of
+text, it’s only the first part of the single logical line of code. The second
+part is this method:
+
+```rust,ignore
+.expect("Failed to read line");
+```
+
+When you call a method with the `.foo()` syntax, it’s often wise to introduce a
+newline and other whitespace to help break up long lines. We could have
+written this code as:
+
+```rust,ignore
+io::stdin().read_line(&mut guess).expect("Failed to read line");
+```
+
+However, one long line is difficult to read, so it’s best to divide it, two
+lines for two method calls. Now let’s discuss what this line does.
+
+### Handling Potential Failure with the `Result` Type
+
+As mentioned earlier, `read_line` puts what the user types into the string we’re
+passing it, but it also returns a value—in this case, an
+[`io::Result`][ioresult]. Rust has a number of types named
+`Result` in its standard library: a generic [`Result`][result] as
+well as specific versions for submodules, such as `io::Result`.
+
+[ioresult]: ../../std/io/type.Result.html
+[result]: ../../std/result/enum.Result.html
+
+The `Result` types are [*enumerations*][enums], often referred
+to as *enums*. An enumeration is a type that can have a fixed set of values,
+and those values are called the enum’s *variants*. Chapter 6 will cover enums
+in more detail.
+
+[enums]: ch06-00-enums.html
+
+For `Result`, the variants are `Ok` or `Err`. `Ok` indicates the operation was
+successful, and inside the `Ok` variant is the successfully generated value.
+`Err` means the operation failed, and `Err` contains information about how or
+why the operation failed.
+
+The purpose of these `Result` types is to encode error handling information.
+Values of the `Result` type, like any type, have methods defined on them. An
+instance of `io::Result` has an [`expect` method][expect] that
+you can call. If this instance of `io::Result` is an `Err` value, `expect` will
+cause the program to crash and display the message that you passed as an
+argument to `expect`. If the `read_line` method returns an `Err`, it would
+likely be the result of an error coming from the underlying operating system.
+If this instance of `io::Result` is an `Ok` value, `expect` will take the
+return value that `Ok` is holding and return just that value to you so you
+could use it. In this case, that value is the number of bytes in what the user
+entered into standard input.
+
+[expect]: ../../std/result/enum.Result.html#method.expect
+
+If we don’t call `expect`, the program will compile, but we’ll get a warning:
+
+```text
+$ cargo build
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+src/main.rs:10:5: 10:39 warning: unused result which must be used,
+#[warn(unused_must_use)] on by default
+src/main.rs:10 io::stdin().read_line(&mut guess);
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+```
+
+Rust warns that we haven’t used the `Result` value returned from `read_line`,
+indicating that the program hasn’t handled a possible error. The right way to
+suppress the warning is to actually write error handling, but since we just
+want to crash this program when a problem occurs, we can use `expect`. You’ll
+learn about recovering from errors in Chapter 9.
+
+### Printing Values with `println!` Placeholders
+
+Aside from the closing curly brace, there’s only one more line to discuss in
+the code added so far, which is the following:
+
+```rust,ignore
+println!("You guessed: {}", guess);
+```
+
+This line prints out the string we saved the user’s input in. The set of `{}`
+is a placeholder that holds a value in place. You can print more than one value
+using `{}`: the first set of `{}` holds the first value listed after the format
+string, the second set holds the second value, and so on. Printing out multiple
+values in one call to `println!` would look like this:
+
+```rust
+let x = 5;
+let y = 10;
+
+println!("x = {} and y = {}", x, y);
+```
+
+This code would print out `x = 5 and y = 10`.
+
+### Testing the First Part
+
+Let’s test the first part of the guessing game. You can run it using `cargo run`:
+
+```text
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Running `target/debug/guessing_game`
+Guess the number!
+Please input your guess.
+6
+You guessed: 6
+```
+
+At this point, the first part of the game is done: we’re getting input from the
+keyboard and then printing it.
+
+## Generating a Secret Number
+
+Next, we need to generate a secret number that the user will try to guess. The
+secret number should be different every time so the game is fun to play more
+than once. Let’s use a random number between 1 and 100 so the game isn’t too
+difficult. Rust doesn’t yet include random number functionality in its standard
+library. However, the Rust team does provide a [`rand` crate][randcrate].
+
+[randcrate]: https://crates.io/crates/rand
+
+### Using a Crate to Get More Functionality
+
+Remember that a *crate* is a package of Rust code. The project we’ve been
+building is a *binary crate*, which is an executable. The `rand` crate is a
+*library crate*, which contains code intended to be used in other programs.
+
+Cargo’s use of external crates is where it really shines. Before we can write
+code that uses `rand`, we need to modify the *Cargo.toml* file to include the
+`rand` crate as a dependency. Open that file now and add the following line to
+the bottom beneath the `[dependencies]` section header that Cargo created for
+you:
+
+Filename: Cargo.toml
+
+```toml
+[dependencies]
+
+rand = "0.3.14"
+```
+
+In the *Cargo.toml* file, everything that follows a header is part of a section
+that continues until another section starts. The `[dependencies]` section is
+where you tell Cargo which external crates your project depends on and which
+versions of those crates you require. In this case, we’ll specify the `rand`
+crate with the semantic version specifier `0.3.14`. Cargo understands [Semantic
+Versioning][semver] (sometimes called *SemVer*), which is a
+standard for writing version numbers. The number `0.3.14` is actually shorthand
+for `^0.3.14`, which means “any version that has a public API compatible with
+version 0.3.14.”
+
+[semver]: http://semver.org
+
+Now, without changing any of the code, let’s build the project, as shown in
+Listing 2-2:
+
+```text
+$ cargo build
+ Updating registry `https://github.com/rust-lang/crates.io-index`
+ Downloading rand v0.3.14
+ Downloading libc v0.2.14
+ Compiling libc v0.2.14
+ Compiling rand v0.3.14
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+```
+
+Listing 2-2: The output from running `cargo build` after
+adding the rand crate as a dependency
+
+You may see different version numbers (but they will all be compatible with
+the code, thanks to SemVer!), and the lines may be in a different order.
+
+Now that we have an external dependency, Cargo fetches the latest versions of
+everything from the *registry*, which is a copy of data from
+[Crates.io][cratesio]. Crates.io is where people in the Rust ecosystem post
+their open source Rust projects for others to use.
+
+[cratesio]: https://crates.io
+
+After updating the registry, Cargo checks the `[dependencies]` section and
+downloads any you don’t have yet. In this case, although we only listed `rand`
+as a dependency, Cargo also grabbed a copy of `libc`, because `rand` depends on
+`libc` to work. After downloading them, Rust compiles them and then compiles
+the project with the dependencies available.
+
+If you immediately run `cargo build` again without making any changes, you won’t
+get any output. Cargo knows it has already downloaded and compiled the
+dependencies, and you haven't changed anything about them in your *Cargo.toml*
+file. Cargo also knows that you haven't changed anything about your code, so it
+doesn't recompile that either. With nothing to do, it simply exits. If you open
+up the *src/main.rs* file, make a trivial change, then save it and build again,
+you’ll only see one line of output:
+
+```text
+$ cargo build
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+```
+
+This line shows Cargo only updates the build with your tiny change to the
+*src/main.rs* file. Your dependencies haven't changed, so Cargo knows it can
+reuse what it has already downloaded and compiled for those. It just rebuilds
+your part of the code.
+
+#### The *Cargo.lock* File Ensures Reproducible Builds
+
+Cargo has a mechanism that ensures you can rebuild the same artifact every time
+you or anyone else builds your code: Cargo will use only the versions of the
+dependencies you specified until you indicate otherwise. For example, what
+happens if next week version `v0.3.15` of the `rand` crate comes out and
+contains an important bug fix but also contains a regression that will break
+your code?
+
+The answer to this problem is the *Cargo.lock* file, which was created the
+first time you ran `cargo build` and is now in your *guessing_game* directory.
+When you build a project for the first time, Cargo figures out all the
+versions of the dependencies that fit the criteria and then writes them to
+the *Cargo.lock* file. When you build your project in the future, Cargo will
+see that the *Cargo.lock* file exists and use the versions specified there
+rather than doing all the work of figuring out versions again. This lets you
+have a reproducible build automatically. In other words, your project will
+remain at `0.3.14` until you explicitly upgrade, thanks to the *Cargo.lock*
+file.
+
+#### Updating a Crate to Get a New Version
+
+When you *do* want to update a crate, Cargo provides another command, `update`,
+which will:
+
+1. Ignore the *Cargo.lock* file and figure out all the latest versions that fit
+your specifications in *Cargo.toml*.
+1. If that works, Cargo will write those versions to the *Cargo.lock* file.
+
+But by default, Cargo will only look for versions larger than `0.3.0` and
+smaller than `0.4.0`. If the `rand` crate has released two new versions,
+`0.3.15` and `0.4.0`, you would see the following if you ran `cargo update`:
+
+```text
+$ cargo update
+ Updating registry `https://github.com/rust-lang/crates.io-index`
+ Updating rand v0.3.14 -> v0.3.15
+```
+
+At this point, you would also notice a change in your *Cargo.lock* file noting
+that the version of the `rand` crate you are now using is `0.3.15`.
+
+If you wanted to use `rand` version `0.4.0` or any version in the `0.4.x`
+series, you’d have to update the *Cargo.toml* file to look like this instead:
+
+```toml
+[dependencies]
+
+rand = "0.4.0"
+```
+
+The next time you run `cargo build`, Cargo will update the registry of crates
+available and reevaluate your `rand` requirements according to the new version
+you specified.
+
+There’s a lot more to say about [Cargo][doccargo] and [its
+ecosystem][doccratesio] that Chapter 14 will discuss, but for
+now, that’s all you need to know. Cargo makes it very easy to reuse libraries,
+so Rustaceans are able to write smaller projects that are assembled from a
+number of packages.
+
+[doccargo]: http://doc.crates.io
+[doccratesio]: http://doc.crates.io/crates-io.html
+
+### Generating a Random Number
+
+Let’s start *using* `rand`. The next step is to update *src/main.rs*, as shown
+in Listing 2-3:
+
+Filename: src/main.rs
+
+```rust,ignore
+extern crate rand;
+
+use std::io;
+use rand::Rng;
+
+fn main() {
+ println!("Guess the number!");
+
+ let secret_number = rand::thread_rng().gen_range(1, 101);
+
+ println!("The secret number is: {}", secret_number);
+
+ println!("Please input your guess.");
+
+ let mut guess = String::new();
+
+ io::stdin().read_line(&mut guess)
+ .expect("Failed to read line");
+
+ println!("You guessed: {}", guess);
+}
+```
+
+Listing 2-3: Code changes needed in order to generate a
+random number
+
+We’re adding a `extern crate rand;` line to the top that lets Rust know we’ll be
+using that external dependency. This also does the equivalent of calling `use
+rand`, so now we can call anything in the `rand` crate by prefixing it with
+`rand::`.
+
+Next, we’re adding another `use` line: `use rand::Rng`. `Rng` is a trait that
+defines methods that random number generators implement, and this trait must be
+in scope for us to use those methods. Chapter 10 will cover traits in detail.
+
+Also, we’re adding two more lines in the middle. The `rand::thread_rng` function
+will give us the particular random number generator that we’re going to use:
+one that is local to the current thread of execution and seeded by the
+operating system. Next, we call the `gen_range` method on the random number
+generator. This method is defined by the `Rng` trait that we brought into
+scope with the `use rand::Rng` statement. The `gen_range` method takes two
+numbers as arguments and generates a random number between them. It’s inclusive
+on the lower bound but exclusive on the upper bound, so we need to specify `1`
+and `101` to request a number between 1 and 100.
+
+Knowing which traits to use and which functions and methods to call from a
+crate isn’t something that you’ll just *know*. Instructions for using a crate
+are in each crate’s documentation. Another neat feature of Cargo is that you
+can run the `cargo doc --open` command that will build documentation provided
+by all of your dependencies locally and open it in your browser. If you’re
+interested in other functionality in the `rand` crate, for example, run `cargo
+doc --open` and click `rand` in the sidebar on the left.
+
+The second line that we added to the code prints the secret number. This is
+useful while we’re developing the program to be able to test it, but we’ll
+delete it from the final version. It’s not much of a game if the program prints
+the answer as soon as it starts!
+
+Try running the program a few times:
+
+```text
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Running `target/debug/guessing_game`
+Guess the number!
+The secret number is: 7
+Please input your guess.
+4
+You guessed: 4
+$ cargo run
+ Running `target/debug/guessing_game`
+Guess the number!
+The secret number is: 83
+Please input your guess.
+5
+You guessed: 5
+```
+
+You should get different random numbers, and they should all be numbers between
+1 and 100. Great job!
+
+## Comparing the Guess to the Secret Number
+
+Now that we have user input and a random number, we can compare them. That
+step is shown in Listing 2-4:
+
+Filename: src/main.rs
+
+```rust,ignore
+extern crate rand;
+
+use std::io;
+use std::cmp::Ordering;
+use rand::Rng;
+
+fn main() {
+ println!("Guess the number!");
+
+ let secret_number = rand::thread_rng().gen_range(1, 101);
+
+ println!("The secret number is: {}", secret_number);
+
+ println!("Please input your guess.");
+
+ let mut guess = String::new();
+
+ io::stdin().read_line(&mut guess)
+ .expect("Failed to read line");
+
+ println!("You guessed: {}", guess);
+
+ match guess.cmp(&secret_number) {
+ Ordering::Less => println!("Too small!"),
+ Ordering::Greater => println!("Too big!"),
+ Ordering::Equal => println!("You win!"),
+ }
+}
+```
+
+Listing 2-4: Handling the possible return values of
+comparing two numbers
+
+The first new bit here is another `use`, bringing a type called
+`std::cmp::Ordering` into scope from the standard library. `Ordering` is
+another enum, like `Result`, but the variants for `Ordering` are `Less`,
+`Greater`, and `Equal`. These are the three outcomes that are possible when you
+compare two values.
+
+Then we add five new lines at the bottom that use the `Ordering` type:
+
+```rust,ignore
+match guess.cmp(&secret_number) {
+ Ordering::Less => println!("Too small!"),
+ Ordering::Greater => println!("Too big!"),
+ Ordering::Equal => println!("You win!"),
+}
+```
+
+The `cmp` method compares two values and can be called on anything that can be
+compared. It takes a reference to whatever you want to compare with: here it’s
+comparing the `guess` to the `secret_number`. `cmp` returns a variant of the
+`Ordering` enum we brought into scope with the `use` statement. We use a
+[`match`][match] expression to decide what to do next based on
+which variant of `Ordering` was returned from the call to `cmp` with the values
+in `guess` and `secret_number`.
+
+[match]: ch06-02-match.html
+
+A `match` expression is made up of *arms*. An arm consists of a *pattern* and
+the code that should be run if the value given to the beginning of the `match`
+expression fits that arm’s pattern. Rust takes the value given to `match` and
+looks through each arm’s pattern in turn. The `match` construct and patterns
+are powerful features in Rust that let you express a variety of situations your
+code might encounter and helps ensure that you handle them all. These features
+will be covered in detail in Chapter 6 and Chapter 18, respectively.
+
+Let’s walk through an example of what would happen with the `match` expression
+used here. Say that the user has guessed 50, and the randomly generated secret
+number this time is 38. When the code compares 50 to 38, the `cmp` method will
+return `Ordering::Greater`, because 50 is greater than 38. `Ordering::Greater`
+is the value that the `match` expression gets. It looks at the first arm’s
+pattern, `Ordering::Less`, but the value `Ordering::Greater` does not match
+`Ordering::Less`, so it ignores the code in that arm and moves to the next arm.
+The next arm’s pattern, `Ordering::Greater`, *does* match
+`Ordering::Greater`! The associated code in that arm will execute and print
+`Too big!` to the screen. The `match` expression ends because it has no need to
+look at the last arm in this particular scenario.
+
+However, the code in Listing 2-4 won’t compile yet. Let’s try it:
+
+```text
+$ cargo build
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+error[E0308]: mismatched types
+ --> src/main.rs:23:21
+ |
+23 | match guess.cmp(&secret_number) {
+ | ^^^^^^^^^^^^^^ expected struct `std::string::String`, found integral variable
+ |
+ = note: expected type `&std::string::String`
+ = note: found type `&{integer}`
+
+error: aborting due to previous error
+Could not compile `guessing_game`.
+```
+
+The core of the error states that there are *mismatched types*. Rust has a
+strong, static type system. However, it also has type inference. When we wrote
+`let guess = String::new()`, Rust was able to infer that `guess` should be a
+`String` and didn’t make us write the type. The `secret_number`, on the other
+hand, is a number type. A few number types can have a value between 1 and 100:
+`i32`, a 32-bit number; `u32`, an unsigned 32-bit number; `i64`, a 64-bit
+number; as well as others. Rust defaults to an `i32`, which is the type of
+`secret_number` unless we add type information elsewhere that would cause Rust
+to infer a different numerical type. The reason for the error is that Rust will
+not compare a string and a number type.
+
+Ultimately, we want to convert the `String` the program reads as input into a
+real number type so we can compare it to the guess numerically. We can do
+that by adding the following two lines to the `main` function body:
+
+Filename: src/main.rs
+
+```rust,ignore
+extern crate rand;
+
+use std::io;
+use std::cmp::Ordering;
+use rand::Rng;
+
+fn main() {
+ println!("Guess the number!");
+
+ let secret_number = rand::thread_rng().gen_range(1, 101);
+
+ println!("The secret number is: {}", secret_number);
+
+ println!("Please input your guess.");
+
+ let mut guess = String::new();
+
+ io::stdin().read_line(&mut guess)
+ .expect("Failed to read line");
+
+ let guess: u32 = guess.trim().parse()
+ .expect("Please type a number!");
+
+ println!("You guessed: {}", guess);
+
+ match guess.cmp(&secret_number) {
+ Ordering::Less => println!("Too small!"),
+ Ordering::Greater => println!("Too big!"),
+ Ordering::Equal => println!("You win!"),
+ }
+}
+```
+
+The two new lines are:
+
+```rust,ignore
+let guess: u32 = guess.trim().parse()
+ .expect("Please type a number!");
+```
+
+We create a variable named `guess`. But wait, doesn’t the program
+already have a variable named `guess`? It does, but Rust allows us to
+*shadow* the previous value of `guess` with a new one. This feature is often
+used in similar situations in which you want to convert a value from one type
+to another type. Shadowing lets us reuse the `guess` variable name rather than
+forcing us to create two unique variables, like `guess_str` and `guess` for
+example. (Chapter 3 covers shadowing in more detail.)
+
+We bind `guess` to the expression `guess.trim().parse()`. The `guess` in the
+expression refers to the original `guess` that was a `String` with the input in
+it. The `trim` method on a `String` instance will eliminate any whitespace at
+the beginning and end. `u32` can only contain numerical characters, but the
+user must press the Return key to satisfy `read_line`. When the user presses
+Return, a newline character is added to the string. For example, if the user
+types 5 and presses return, `guess` looks like this: `5\n`. The `\n` represents
+“newline,” the return key. The `trim` method eliminates `\n`, resulting in just
+`5`.
+
+The [`parse` method on strings][parse] parses a string into some
+kind of number. Because this method can parse a variety of number types, we
+need to tell Rust the exact number type we want by using `let guess: u32`. The
+colon (`:`) after `guess` tells Rust we’ll annotate the variable’s type. Rust
+has a few built-in number types; the `u32` seen here is an unsigned, 32-bit
+integer. It’s a good default choice for a small positive number. You’ll learn
+about other number types in Chapter 3. Additionally, the `u32` annotation in
+this example program and the comparison with `secret_number` means that Rust
+will infer that `secret_number` should be a `u32` as well. So now the
+comparison will be between two values of the same type!
+
+[parse]: ../../std/primitive.str.html#method.parse
+
+The call to `parse` could easily cause an error. If, for example, the string
+contained `A👍%`, there would be no way to convert that to a number. Because it
+might fail, the `parse` method returns a `Result` type, much like the
+`read_line` method does as discussed earlier in “Handling Potential Failure
+with the Result Type”. We’ll treat this `Result` the same way by
+using the `expect` method again. If `parse` returns an `Err` `Result` variant
+because it couldn’t create a number from the string, the `expect` call will
+crash the game and print the message we give it. If `parse` can successfully
+convert the string to a number, it will return the `Ok` variant of `Result`,
+and `expect` will return the number that we want from the `Ok` value.
+
+Let’s run the program now!
+
+```text
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Running `target/guessing_game`
+Guess the number!
+The secret number is: 58
+Please input your guess.
+ 76
+You guessed: 76
+Too big!
+```
+
+Nice! Even though spaces were added before the guess, the program still figured
+out that the user guessed 76. Run the program a few times to verify the
+different behavior with different kinds of input: guess the number correctly,
+guess a number that is too high, and guess a number that is too low.
+
+We have most of the game working now, but the user can make only one guess.
+Let’s change that by adding a loop!
+
+## Allowing Multiple Guesses with Looping
+
+The `loop` keyword gives us an infinite loop. Add that now to give users more
+chances at guessing the number:
+
+Filename: src/main.rs
+
+```rust,ignore
+extern crate rand;
+
+use std::io;
+use std::cmp::Ordering;
+use rand::Rng;
+
+fn main() {
+ println!("Guess the number!");
+
+ let secret_number = rand::thread_rng().gen_range(1, 101);
+
+ println!("The secret number is: {}", secret_number);
+
+ loop {
+ println!("Please input your guess.");
+
+ let mut guess = String::new();
+
+ io::stdin().read_line(&mut guess)
+ .expect("Failed to read line");
+
+ let guess: u32 = guess.trim().parse()
+ .expect("Please type a number!");
+
+ println!("You guessed: {}", guess);
+
+ match guess.cmp(&secret_number) {
+ Ordering::Less => println!("Too small!"),
+ Ordering::Greater => println!("Too big!"),
+ Ordering::Equal => println!("You win!"),
+ }
+ }
+}
+```
+
+As you can see, we’ve moved everything into a loop from the guess input prompt
+onward. Be sure to indent those lines another four spaces each, and run the
+program again. Notice that there is a new problem because the program is doing
+exactly what we told it to do: ask for another guess forever! It doesn’t seem
+like the user can quit!
+
+The user could always halt the program by using the keyboard shortcut `Ctrl-C`.
+But there’s another way to escape this insatiable monster that we mentioned in
+the `parse` discussion in “Comparing the Guess to the Secret Number”: if the user
+enters a non-number answer, the program will crash. The user can take advantage
+of that in order to quit, as shown here:
+
+```text
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Running `target/guessing_game`
+Guess the number!
+The secret number is: 59
+Please input your guess.
+45
+You guessed: 45
+Too small!
+Please input your guess.
+60
+You guessed: 60
+Too big!
+Please input your guess.
+59
+You guessed: 59
+You win!
+Please input your guess.
+quit
+thread 'main' panicked at 'Please type a number!: ParseIntError { kind: InvalidDigit }', src/libcore/result.rs:785
+note: Run with `RUST_BACKTRACE=1` for a backtrace.
+error: Process didn't exit successfully: `target/debug/guess` (exit code: 101)
+```
+
+Typing `quit` actually quits the game, but so will any other non-number input.
+However, this is suboptimal to say the least. We want the game to automatically
+stop when the correct number is guessed.
+
+### Quitting After a Correct Guess
+
+Let’s program the game to quit when the user wins by adding a `break`:
+
+Filename: src/main.rs
+
+```rust,ignore
+extern crate rand;
+
+use std::io;
+use std::cmp::Ordering;
+use rand::Rng;
+
+fn main() {
+ println!("Guess the number!");
+
+ let secret_number = rand::thread_rng().gen_range(1, 101);
+
+ println!("The secret number is: {}", secret_number);
+
+ loop {
+ println!("Please input your guess.");
+
+ let mut guess = String::new();
+
+ io::stdin().read_line(&mut guess)
+ .expect("Failed to read line");
+
+ let guess: u32 = guess.trim().parse()
+ .expect("Please type a number!");
+
+ println!("You guessed: {}", guess);
+
+ match guess.cmp(&secret_number) {
+ Ordering::Less => println!("Too small!"),
+ Ordering::Greater => println!("Too big!"),
+ Ordering::Equal => {
+ println!("You win!");
+ break;
+ }
+ }
+ }
+}
+```
+
+By adding the `break` line after `You win!`, the program will exit the loop
+when the user guesses the secret number correctly. Exiting the loop also means
+exiting the program, because the loop is the last part of `main`.
+
+### Handling Invalid Input
+
+To further refine the game’s behavior, rather than crashing the program when
+the user inputs a non-number, let’s make the game ignore a non-number so the
+user can continue guessing. We can do that by altering the line where `guess` is
+converted from a `String` to a `u32`:
+
+```rust,ignore
+let guess: u32 = match guess.trim().parse() {
+ Ok(num) => num,
+ Err(_) => continue,
+};
+```
+
+Switching from an `expect` call to a `match` expression is how you generally
+move from crash on error to actually handling the error. Remember that `parse`
+returns a `Result` type, and `Result` is an enum that has the variants `Ok` or
+`Err`. We’re using a `match` expression here, like we did with the `Ordering`
+result of the `cmp` method.
+
+If `parse` is able to successfully turn the string into a number, it will return
+an `Ok` value that contains the resulting number. That `Ok` value will match the
+first arm’s pattern, and the `match` expression will just return the `num` value
+that `parse` produced and put inside the `Ok` value. That number will end up
+right where we want it in the new `guess` variable we’re creating.
+
+If `parse` is *not* able to turn the string into a number, it will return an
+`Err` value that contains more information about the error. The `Err` value
+does not match the `Ok(num)` pattern in the first `match` arm, but it does match
+the `Err(_)` pattern in the second arm. The `_` is a catchall value; in this
+example, we’re saying we want to match all `Err` values, no matter what
+information they have inside them. So the program will execute the second arm’s
+code, `continue`, which means to go to the next iteration of the `loop` and ask
+for another guess. So effectively, the program ignores all errors that `parse`
+might encounter!
+
+Now everything in the program should work as expected. Let’s try it by running
+`cargo run`:
+
+```text
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Running `target/guessing_game`
+Guess the number!
+The secret number is: 61
+Please input your guess.
+10
+You guessed: 10
+Too small!
+Please input your guess.
+99
+You guessed: 99
+Too big!
+Please input your guess.
+foo
+Please input your guess.
+61
+You guessed: 61
+You win!
+```
+
+Awesome! With one tiny final tweak, we will finish the guessing game: recall
+that the program is still printing out the secret number. That worked well for
+testing, but it ruins the game. Let’s delete the `println!` that outputs the
+secret number. Listing 2-5 shows the final code:
+
+Filename: src/main.rs
+
+```rust,ignore
+extern crate rand;
+
+use std::io;
+use std::cmp::Ordering;
+use rand::Rng;
+
+fn main() {
+ println!("Guess the number!");
+
+ let secret_number = rand::thread_rng().gen_range(1, 101);
+
+ loop {
+ println!("Please input your guess.");
+
+ let mut guess = String::new();
+
+ io::stdin().read_line(&mut guess)
+ .expect("Failed to read line");
+
+ let guess: u32 = match guess.trim().parse() {
+ Ok(num) => num,
+ Err(_) => continue,
+ };
+
+ println!("You guessed: {}", guess);
+
+ match guess.cmp(&secret_number) {
+ Ordering::Less => println!("Too small!"),
+ Ordering::Greater => println!("Too big!"),
+ Ordering::Equal => {
+ println!("You win!");
+ break;
+ }
+ }
+ }
+}
+```
+
+Listing 2-5: Complete code of the guessing game
+
+## Summary
+
+At this point, you’ve successfully built the guessing game! Congratulations!
+
+This project was a hands-on way to introduce you to many new Rust concepts:
+`let`, `match`, methods, associated functions, using external crates, and more.
+In the next few chapters, you’ll learn about these concepts in more detail.
+Chapter 3 covers concepts that most programming languages have, such as
+variables, data types, and functions, and shows how to use them in Rust.
+Chapter 4 explores ownership, which is a Rust feature that is most different
+from other languages. Chapter 5 discusses structs and method syntax, and
+Chapter 6 endeavors to explain enums.
diff --git a/trpl-2nd-edition/ch03-00-common-programming-concepts.md b/trpl-2nd-edition/ch03-00-common-programming-concepts.md
new file mode 100644
index 0000000..c64f329
--- /dev/null
+++ b/trpl-2nd-edition/ch03-00-common-programming-concepts.md
@@ -0,0 +1,20 @@
+# Common Programming Concepts
+
+This chapter covers concepts that appear in almost every programming language
+and how they work in Rust. Many programming languages have much in common at
+their core. None of the concepts presented in this chapter are unique to Rust,
+but we’ll discuss them in the context of Rust and explain their conventions.
+
+Specifically, you’ll learn about variables, basic types, functions, comments,
+and control flow. These foundations will be in every Rust program, and learning
+them early will give you a strong core to start from.
+
+> ### Keywords
+>
+> The Rust language has a set of *keywords* that have been reserved for use by
+> the language only, much like other languages do. Keep in mind that you cannot
+> use these words as names of variables or functions. Most of the keywords have
+> special meanings, and you’ll be using them to do various tasks in your Rust
+> programs; a few have no current functionality associated with them but have
+> been reserved for functionality that might be added to Rust in the future. You
+> can find a list of the keywords in Appendix A.
diff --git a/trpl-2nd-edition/ch03-01-variables-and-mutability.md b/trpl-2nd-edition/ch03-01-variables-and-mutability.md
new file mode 100644
index 0000000..86c3ed0
--- /dev/null
+++ b/trpl-2nd-edition/ch03-01-variables-and-mutability.md
@@ -0,0 +1,224 @@
+## Variables and Mutability
+
+As mentioned in Chapter 2, by default variables are *immutable*. This is one of
+many nudges in Rust that encourages you to write your code in a way that takes
+advantage of the safety and easy concurrency that Rust offers. However, you
+still have the option to make your variables mutable. Let’s explore how and why
+Rust encourages you to favor immutability, and why you might want to opt out.
+
+When a variable is immutable, that means once a value is bound to a name, you
+can’t change that value. To illustrate, let’s generate a new project called
+*variables* in your *projects* directory by using `cargo new --bin variables`.
+
+Then, in your new *variables* directory, open *src/main.rs* and replace its
+code with the following:
+
+Filename: src/main.rs
+
+```rust,ignore
+fn main() {
+ let x = 5;
+ println!("The value of x is: {}", x);
+ x = 6;
+ println!("The value of x is: {}", x);
+}
+```
+
+Save and run the program using `cargo run`. You should receive an error
+message, as shown in this output:
+
+```text
+error[E0384]: re-assignment of immutable variable `x`
+ --> src/main.rs:4:5
+ |
+2 | let x = 5;
+ | - first assignment to `x`
+3 | println!("The value of x is: {}", x);
+4 | x = 6;
+ | ^^^^^ re-assignment of immutable variable
+```
+
+This example shows how the compiler helps you find errors in your programs.
+Even though compiler errors can be frustrating, they only mean your program
+isn’t safely doing what you want it to do yet; they do *not* mean that you’re
+not a good programmer! Experienced Rustaceans still get compiler errors. The
+error indicates that the cause of the error is `re-assignment of immutable
+variable`, because we tried to assign a second value to the immutable `x`
+variable.
+
+It’s important that we get compile-time errors when we attempt to change a
+value that we previously designated as immutable because this very situation
+can lead to bugs. If one part of our code operates on the assumption that a
+value will never change and another part of our code changes that value, it’s
+possible that the first part of the code won’t do what it was designed to do.
+This cause of bugs can be difficult to track down after the fact, especially
+when the second piece of code changes the value only *sometimes*.
+
+In Rust the compiler guarantees that when we state that a value won’t change,
+it really won’t change. That means that when you’re reading and writing code,
+you don’t have to keep track of how and where a value might change, which can
+make code easier to reason about.
+
+But mutability can be very useful. Variables are immutable only by default; we
+can make them mutable by adding `mut` in front of the variable name. In
+addition to allowing this value to change, it conveys intent to future readers
+of the code by indicating that other parts of the code will be changing this
+variable value.
+
+For example, change *src/main.rs* to the following:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let mut x = 5;
+ println!("The value of x is: {}", x);
+ x = 6;
+ println!("The value of x is: {}", x);
+}
+```
+
+When we run this program, we get the following:
+
+```text
+$ cargo run
+ Compiling variables v0.1.0 (file:///projects/variables)
+ Running `target/debug/variables`
+The value of x is: 5
+The value of x is: 6
+```
+
+Using `mut`, we’re allowed to change the value that `x` binds to from `5` to
+`6`. In some cases, you’ll want to make a variable mutable because it makes the
+code more convenient to write than an implementation that only uses immutable
+variables.
+
+There are multiple trade-offs to consider, in addition to the prevention of
+bugs. For example, in cases where you’re using large data structures, mutating
+an instance in place may be faster than copying and returning newly allocated
+instances. With smaller data structures, creating new instances and writing in
+a more functional programming style may be easier to reason about, so the lower
+performance might be a worthwhile penalty for gaining that clarity.
+
+### Differences Between Variables and Constants
+
+Being unable to change the value of a variable might have reminded you of
+another programming concept that most other languages have: *constants*. Like
+immutable variables, constants are also values that are bound to a name and
+are not allowed to change, but there are a few differences between constants
+and variables.
+
+First, we aren’t allowed to use `mut` with constants: constants aren't only
+immutable by default, they're always immutable.
+
+We declare constants using the `const` keyword instead of the `let` keyword,
+and the type of the value *must* be annotated. We're about to cover types and
+type annotations in the next section, “Data Types,” so don't worry about the
+details right now, just know that we must always annotate the type.
+
+Constants can be declared in any scope, including the global scope, which makes
+them useful for values that many parts of code need to know about.
+
+The last difference is that constants may only be set to a constant expression,
+not the result of a function call or any other value that could only be
+computed at runtime.
+
+Here's an example of a constant declaration where the constant's name is
+`MAX_POINTS` and its value is set to 100,000. (Rust constant naming convention
+is to use all upper case with underscores between words):
+
+```rust
+const MAX_POINTS: u32 = 100_000;
+```
+
+Constants are valid for the entire time a program runs, within the scope they
+were declared in, making them a useful choice for values in your application
+domain that multiple part of the program might need to know about, such as the
+maximum number of points any player of a game is allowed to earn or the speed
+of light.
+
+Naming hardcoded values used throughout your program as constants is useful in
+conveying the meaning of that value to future maintainers of the code. It also
+helps to have only one place in your code you would need to change if the
+hardcoded value needed to be updated in the future.
+
+### Shadowing
+
+As we saw in the guessing game tutorial in Chapter 2, we can declare new
+variables with the same name as a previous variables, and the new variable
+*shadows* the previous variable. Rustaceans say that the first variable is
+*shadowed* by the second, which means that the second variable’s value is what
+we’ll see when we use the variable. We can shadow a variable by using the same
+variable’s name and repeating the use of the `let` keyword as follows:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let x = 5;
+
+ let x = x + 1;
+
+ let x = x * 2;
+
+ println!("The value of x is: {}", x);
+}
+```
+
+This program first binds `x` to a value of `5`. Then it shadows `x` by
+repeating `let x =`, taking the original value and adding `1` so the value of
+`x` is then `6`. The third `let` statement also shadows `x`, taking the
+previous value and multiplying it by `2` to give `x` a final value of `12`.
+When you run this program, it will output the following:
+
+```text
+$ cargo run
+ Compiling variables v0.1.0 (file:///projects/variables)
+ Running `target/debug/variables`
+The value of x is: 12
+```
+
+This is different than marking a variable as `mut`, because unless we use the
+`let` keyword again, we’ll get a compile-time error if we accidentally try to
+reassign to this variable. We can perform a few transformations on a value but
+have the variable be immutable after those transformations have been completed.
+
+The other difference between `mut` and shadowing is that because we’re
+effectively creating a new variable when we use the `let` keyword again, we can
+change the type of the value, but reuse the same name. For example, say our
+program asks a user to show how many spaces they want between some text by
+inputting space characters, but we really want to store that input as a number:
+
+```rust
+let spaces = " ";
+let spaces = spaces.len();
+```
+
+This construct is allowed because the first `spaces` variable is a string type,
+and the second `spaces` variable, which is a brand-new variable that happens to
+have the same name as the first one, is a number type. Shadowing thus spares us
+from having to come up with different names, like `spaces_str` and
+`spaces_num`; instead, we can reuse the simpler `spaces` name. However, if we
+try to use `mut` for this, as shown here:
+
+```rust,ignore
+let mut spaces = " ";
+spaces = spaces.len();
+```
+
+we’ll get a compile-time error because we’re not allowed to mutate a variable’s
+type:
+
+```text
+error[E0308]: mismatched types
+ --> src/main.rs:3:14
+ |
+3 | spaces = spaces.len();
+ | ^^^^^^^^^^^^ expected &str, found usize
+ |
+ = note: expected type `&str`
+ found type `usize`
+```
+
+Now that we’ve explored how variables work, let’s look at more data types they
+can have.
diff --git a/trpl-2nd-edition/ch03-02-data-types.md b/trpl-2nd-edition/ch03-02-data-types.md
new file mode 100644
index 0000000..334cd60
--- /dev/null
+++ b/trpl-2nd-edition/ch03-02-data-types.md
@@ -0,0 +1,367 @@
+## Data Types
+
+Every value in Rust is of a certain *type*, which tells Rust what kind of data
+is being specified so it knows how to work with that data. In this section,
+we’ll look at a number of types that are built into the language. We split the
+types into two subsets: scalar and compound.
+
+Throughout this section, keep in mind that Rust is a *statically typed*
+language, which means that it must know the types of all variables at compile
+time. The compiler can usually infer what type we want to use based on the
+value and how we use it. In cases when many types are possible, such as when we
+converted a `String` to a numeric type using `parse` in Chapter 2, we must add
+a type annotation, like this:
+
+```rust
+let guess: u32 = "42".parse().expect("Not a number!");
+```
+
+If we don’t add the type annotation here, Rust will display the following
+error, which means the compiler needs more information from us to know which
+possible type we want to use:
+
+```text
+error[E0282]: unable to infer enough type information about `_`
+ --> src/main.rs:2:9
+ |
+2 | let guess = "42".parse().expect("Not a number!");
+ | ^^^^^ cannot infer type for `_`
+ |
+ = note: type annotations or generic parameter binding required
+```
+
+You’ll see different type annotations as we discuss the various data types.
+
+### Scalar Types
+
+A *scalar* type represents a single value. Rust has four primary scalar types:
+integers, floating-point numbers, booleans, and characters. You’ll likely
+recognize these from other programming languages, but let’s jump into how they
+work in Rust.
+
+#### Integer Types
+
+An *integer* is a number without a fractional component. We used one integer
+type earlier in this chapter, the `i32` type. This type declaration indicates
+that the value it’s associated with should be a signed integer (hence the `i`,
+as opposed to a `u` for unsigned) that takes up 32 bits of space. Table 3-1
+shows the built-in integer types in Rust. Each variant in the Signed and
+Unsigned columns (for example, *i32*) can be used to declare the type of an
+integer value.
+
+Table 3-1: Integer Types in Rust
+
+| Length | Signed | Unsigned |
+|--------|--------|----------|
+| 8-bit | i8 | u8 |
+| 16-bit | i16 | u16 |
+| 32-bit | i32 | u32 |
+| 64-bit | i64 | u64 |
+| arch | isize | usize |
+
+Each variant can be either signed or unsigned and has an explicit size.
+Signed and unsigned refers to whether it’s possible for the number to be
+negative or positive; in other words, whether the number needs to have a sign
+with it (signed) or whether it will only ever be positive and can therefore be
+represented without a sign (unsigned). It’s like writing numbers on paper: when
+the sign matters, a number is shown with a plus sign or a minus sign; however,
+when it’s safe to assume the number is positive, it’s shown with no sign.
+Signed numbers are stored using two’s complement representation (if you’re
+unsure what this is, you can search for it online; an explanation is outside
+the scope of this book).
+
+Each signed variant can store numbers from -(2n - 1) to 2n -
+1 - 1 inclusive, where `n` is the number of bits that variant uses. So an
+`i8` can store numbers from -(27) to 27 - 1, which equals
+-128 to 127. Unsigned variants can store numbers from 0 to 2n - 1,
+so a `u8` can store numbers from 0 to 28 - 1, which equals 0 to 255.
+
+Additionally, the `isize` and `usize` types depend on the kind of computer your
+program is running on: 64-bits if you’re on a 64-bit architecture and 32-bits
+if you’re on a 32-bit architecture.
+
+You can write integer literals in any of the forms shown in Table 3-2. Note
+that all number literals except the byte literal allow a type suffix, such as
+`57u8`, and `_` as a visual separator, such as `1_000`.
+
+Table 3-2: Integer Literals in Rust
+
+| Number literals | Example |
+|------------------|---------------|
+| Decimal | `98_222` |
+| Hex | `0xff` |
+| Octal | `0o77` |
+| Binary | `0b1111_0000` |
+| Byte (`u8` only) | `b'A'` |
+
+So how do you know which type of integer to use? If you’re unsure, Rust’s
+defaults are generally good choices, and integer types default to `i32`: it’s
+generally the fastest, even on 64-bit systems. The primary situation in which
+you’d use `isize` or `usize` is when indexing some sort of collection.
+
+#### Floating-Point Types
+
+Rust also has two primitive types for *floating-point numbers*, which are
+numbers with decimal points. Rust’s floating-point types are `f32` and `f64`,
+which are 32 bits and 64 bits in size, respectively. The default type is `f64`
+because it’s roughly the same speed as `f32` but is capable of more precision.
+It’s possible to use an `f64` type on 32-bit systems, but it will be slower
+than using an `f32` type on those systems. Most of the time, trading potential
+worse performance for better precision is a reasonable initial choice, and you
+should benchmark your code if you suspect floating-point size is a problem in
+your situation.
+
+Here’s an example that shows floating-point numbers in action:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let x = 2.0; // f64
+
+ let y: f32 = 3.0; // f32
+}
+```
+
+Floating-point numbers are represented according to the IEEE-754 standard. The
+`f32` type is a single-precision float, and `f64` has double precision.
+
+#### Numeric Operations
+
+Rust supports the usual basic mathematic operations you’d expect for all of the
+number types: addition, subtraction, multiplication, division, and remainder.
+The following code shows how you’d use each one in a `let` statement:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ // addition
+ let sum = 5 + 10;
+
+ // subtraction
+ let difference = 95.5 - 4.3;
+
+ // multiplication
+ let product = 4 * 30;
+
+ // division
+ let quotient = 56.7 / 32.2;
+
+ // remainder
+ let remainder = 43 % 5;
+}
+```
+
+Each expression in these statements uses a mathematical operator and evaluates
+to a single value, which is then bound to a variable. Appendix B contains a
+list of all operators that Rust provides.
+
+#### The Boolean Type
+
+As in most other programming languages, a boolean type in Rust has two possible
+values: `true` and `false`. The boolean type in Rust is specified using `bool`.
+For example:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let t = true;
+
+ let f: bool = false; // with explicit type annotation
+}
+```
+
+The main way to consume boolean values is through conditionals, such as an `if`
+statement. We’ll cover how `if` statements work in Rust in the “Control Flow”
+section.
+
+#### The Character Type
+
+So far we’ve only worked with numbers, but Rust supports letters too. Rust’s
+`char` type is the language’s most primitive alphabetic type, and the following
+code shows one way to use it:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let c = 'z';
+ let z = 'ℤ';
+ let heart_eyed_cat = '😻';
+}
+```
+
+Rust’s `char` type represents a Unicode Scalar Value, which means it can
+represent a lot more than just ASCII. Accented letters, Chinese/Japanese/Korean
+ideographs, emoji, and zero width spaces are all valid `char` types in Rust.
+Unicode Scalar Values range from `U+0000` to `U+D7FF` and `U+E000` to
+`U+10FFFF` inclusive. However, a “character” isn’t really a concept in Unicode,
+so your human intuition for what a “character” is may not match up with what a
+`char` is in Rust. We’ll discuss this topic in detail in the “Strings” section
+in Chapter 8.
+
+### Compound Types
+
+*Compound types* can group multiple values of other types into one type. Rust
+has two primitive compound types: tuples and arrays.
+
+#### Grouping Values into Tuples
+
+A tuple is a general way of grouping together some number of other values with
+a variety of types into one compound type.
+
+We create a tuple by writing a comma-separated list of values inside
+parentheses. Each position in the tuple has a type, and the types of the
+different values in the tuple don’t have to be the same. We’ve added optional
+type annotations in this example:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let tup: (i32, f64, u8) = (500, 6.4, 1);
+}
+```
+
+The variable `tup` binds to the entire tuple, since a tuple is considered a
+single compound element. To get the individual values out of a tuple, we can
+use pattern matching to destructure a tuple value, like this:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let tup = (500, 6.4, 1);
+
+ let (x, y, z) = tup;
+
+ println!("The value of y is: {}", y);
+}
+```
+
+This program first creates a tuple and binds it to the variable `tup`. It then
+uses a pattern with `let` to take `tup` and turn it into three separate
+variables, `x`, `y`, and `z`. This is called *destructuring*, because it breaks
+the single tuple into three parts. Finally, the program prints the value of
+`y`, which is `6.4`.
+
+In addition to destructuring through pattern matching, we can also access a
+tuple element directly by using a period (`.`) followed by the index of the
+value we want to access. For example:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let x: (i32, f64, u8) = (500, 6.4, 1);
+
+ let five_hundred = x.0;
+
+ let six_point_four = x.1;
+
+ let one = x.2;
+}
+```
+
+This program creates a tuple, `x`, and then makes new variables for each
+element by using their index. As with most programming languages, the first
+index in a tuple is 0.
+
+#### Arrays
+
+Another way to have a collection of multiple values is with an *array*. Unlike
+a tuple, every element of an array must have the same type. Arrays in Rust are
+different than arrays in some other languages because arrays in Rust have a
+fixed length: once declared, they cannot grow or shrink in size.
+
+In Rust, the values going into an array are written as a comma-separated list
+inside square brackets:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let a = [1, 2, 3, 4, 5];
+}
+```
+
+Arrays are useful when you want your data allocated on the stack rather than
+the heap (we will discuss the stack and the heap more in Chapter 4), or when
+you want to ensure you always have a fixed number of elements. They aren’t as
+flexible as the vector type, though. The vector type is a similar collection
+type provided by the standard library that *is* allowed to grow or shrink in
+size. If you’re unsure whether to use an array or a vector, you should probably
+use a vector: Chapter 8 discusses vectors in more detail.
+
+An example of when you might want to use an array rather than a vector is in a
+program that needs to know the names of the months of the year. It’s very
+unlikely that such a program will need to add or remove months, so you can use
+an array because you know it will always contain 12 items:
+
+```rust
+let months = ["January", "February", "March", "April", "May", "June", "July",
+ "August", "September", "October", "November", "December"];
+```
+
+##### Accessing Array Elements
+
+An array is a single chunk of memory allocated on the stack. We can access
+elements of an array using indexing, like this:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let a = [1, 2, 3, 4, 5];
+
+ let first = a[0];
+ let second = a[1];
+}
+```
+
+In this example, the variable named `first` will get the value `1`, because
+that is the value at index `[0]` in the array. The variable named `second` will
+get the value `2` from index `[1]` in the array.
+
+##### Invalid Array Element Access
+
+What happens if we try to access an element of an array that is past the end of
+the array? Say we change the example to the following:
+
+Filename: src/main.rs
+
+```rust,ignore
+fn main() {
+ let a = [1, 2, 3, 4, 5];
+ let index = 10;
+
+ let element = a[index];
+
+ println!("The value of element is: {}", element);
+}
+```
+
+Running this code using `cargo run` produces the following result:
+
+```text
+$ cargo run
+ Compiling arrays v0.1.0 (file:///projects/arrays)
+ Running `target/debug/arrays`
+thread '' panicked at 'index out of bounds: the len is 5 but the index is
+ 10', src/main.rs:6
+note: Run with `RUST_BACKTRACE=1` for a backtrace.
+```
+
+The compilation didn’t produce any errors, but the program results in a
+*runtime* error and didn’t exit successfully. When you attempt to access an
+element using indexing, Rust will check that the index you’ve specified is less
+than the array length. If the index is greater than the length, Rust will
+*panic*, which is the term Rust uses when a program exits with an error.
+
+This is the first example of Rust’s safety principles in action. In many
+low-level languages, this kind of check is not done, and when you provide an
+incorrect index, invalid memory can be accessed. Rust protects you against this
+kind of error by immediately exiting instead of allowing the memory access and
+continuing. Chapter 9 discusses more of Rust’s error handling.
diff --git a/trpl-2nd-edition/ch03-03-how-functions-work.md b/trpl-2nd-edition/ch03-03-how-functions-work.md
new file mode 100644
index 0000000..00c00a9
--- /dev/null
+++ b/trpl-2nd-edition/ch03-03-how-functions-work.md
@@ -0,0 +1,343 @@
+## How Functions Work
+
+Functions are pervasive in Rust code. You’ve already seen one of the most
+important functions in the language: the `main` function, which is the entry
+point of many programs. You’ve also seen the `fn` keyword, which allows you to
+declare new functions.
+
+Rust code uses *snake case* as the conventional style for function and variable
+names. In snake case, all letters are lowercase and underscores separate words.
+Here’s a program that contains an example function definition:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ println!("Hello, world!");
+
+ another_function();
+}
+
+fn another_function() {
+ println!("Another function.");
+}
+```
+
+Function definitions in Rust start with `fn` and have a set of parentheses
+after the function name. The curly braces tell the compiler where the function
+body begins and ends.
+
+We can call any function we’ve defined by entering its name followed by a set
+of parentheses. Because `another_function` is defined in the program, it can be
+called from inside the `main` function. Note that we defined `another_function`
+*after* the `main` function in the source code; we could have defined it before
+as well. Rust doesn’t care where you define your functions, only that they’re
+defined somewhere.
+
+Let’s start a new binary project named *functions* to explore functions
+further. Place the `another_function` example in *src/main.rs* and run it. You
+should see the following output:
+
+```text
+$ cargo run
+ Compiling functions v0.1.0 (file:///projects/functions)
+ Running `target/debug/functions`
+Hello, world!
+Another function.
+```
+
+The lines execute in the order in which they appear in the `main` function.
+First, the “Hello, world!” message prints, and then `another_function` is
+called and its message is printed.
+
+### Function Parameters
+
+Functions can also be defined to have *parameters*, which are special variables
+that are part of a function's signature. When a function has parameters, we can
+provide it with concrete values for those parameters. Technically, the concrete
+values are called *arguments*, but in casual conversation people tend to use
+the words “parameter” and “argument” interchangeably for either the variables
+in a function's definition or the concrete values passed in when you call a
+function.
+
+The following rewritten version of `another_function` shows what parameters
+look like in Rust:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ another_function(5);
+}
+
+fn another_function(x: i32) {
+ println!("The value of x is: {}", x);
+}
+```
+
+Try running this program; you should get the following output:
+
+```text
+$ cargo run
+ Compiling functions v0.1.0 (file:///projects/functions)
+ Running `target/debug/functions`
+The value of x is: 5
+```
+
+The declaration of `another_function` has one parameter named `x`. The type of
+`x` is specified as `i32`. When `5` is passed to `another_function`, the
+`println!` macro puts `5` where the pair of curly braces were in the format
+string.
+
+In function signatures, you *must* declare the type of each parameter. This is
+a deliberate decision in Rust’s design: requiring type annotations in function
+definitions means the compiler almost never needs you to use them elsewhere in
+the code to figure out what you mean.
+
+When you want a function to have multiple parameters, separate the parameter
+declarations with commas, like this:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ another_function(5, 6);
+}
+
+fn another_function(x: i32, y: i32) {
+ println!("The value of x is: {}", x);
+ println!("The value of y is: {}", y);
+}
+```
+
+This example creates a function with two parameters, both of which are `i32`
+types. The function then prints out the values in both of its parameters. Note
+that function parameters don't all need to be the same type, they just happen
+to be in this example.
+
+Let’s try running this code. Replace the program currently in your *function*
+project’s *src/main.rs* file with the preceding example, and run it using
+`cargo run`:
+
+```text
+$ cargo run
+ Compiling functions v0.1.0 (file:///projects/functions)
+ Running `target/debug/functions`
+The value of x is: 5
+The value of y is: 6
+```
+
+Because we called the function with `5` as the value for `x` and `6` is passed
+as the value for `y`, the two strings are printed with these values.
+
+### Function Bodies
+
+Function bodies are made up of a series of statements optionally ending in an
+expression. So far, we’ve only covered functions without an ending expression,
+but we have seen expressions as parts of statements. Because Rust is an
+expression-based language, this is an important distinction to understand.
+Other languages don’t have the same distinctions, so let’s look at what
+statements and expressions are and how their differences affect the bodies of
+functions.
+
+### Statements and Expressions
+
+We’ve actually already used statements and expressions. *Statements* are
+instructions that perform some action and do not return a value. *Expressions*
+evaluate to a resulting value. Let’s look at some examples.
+
+Creating a variable and assigning a value to it with the `let` keyword is a
+statement. In Listing 3-3, `let y = 6;` is a statement:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let y = 6;
+}
+```
+
+Listing 3-3: A `main` function declaration containing one statement.
+
+Function definitions are also statements; the entire preceding example is a
+statement in itself.
+
+Statements do not return values. Therefore, you can’t assign a `let` statement
+to another variable, as the following code tries to do:
+
+Filename: src/main.rs
+
+```rust,ignore
+fn main() {
+ let x = (let y = 6);
+}
+```
+
+When you run this program, you’ll get an error like this:
+
+```text
+$ cargo run
+ Compiling functions v0.1.0 (file:///projects/functions)
+error: expected expression, found statement (`let`)
+ --> src/main.rs:2:14
+ |
+2 | let x = (let y = 6);
+ | ^^^
+ |
+ = note: variable declaration using `let` is a statement
+```
+
+The `let y = 6` statement does not return a value, so there isn’t anything for
+`x` to bind to. This is different than in other languages, such as C and Ruby,
+where the assignment returns the value of the assignment. In those languages,
+you can write `x = y = 6` and have both `x` and `y` have the value `6`; that is
+not the case in Rust.
+
+Expressions evaluate to something and make up most of the rest of the code that
+you’ll write in Rust. Consider a simple math operation, such as `5 + 6`, which
+is an expression that evaluates to the value `11`. Expressions can be part of
+statements: in Listing 3-3 that had the statement `let y = 6;`, `6` is an
+expression that evaluates to the value `6`. Calling a function is an
+expression. Calling a macro is an expression. The block that we use to create
+new scopes, `{}`, is an expression, for example:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let x = 5;
+
+ let y = {
+ let x = 3;
+ x + 1
+ };
+
+ println!("The value of y is: {}", y);
+}
+```
+
+This expression:
+
+```rust,ignore
+{
+ let x = 3;
+ x + 1
+}
+```
+
+is a block that, in this case, evaluates to `4`. That value gets bound to `y`
+as part of the `let` statement. Note the line without a semicolon at the end,
+unlike most of the lines you’ve seen so far. Expressions do not include ending
+semicolons. If you add a semicolon to the end of an expression, you turn it
+into a statement, which will then not return a value. Keep this in mind as you
+explore function return values and expressions next.
+
+### Functions with Return Values
+
+Functions can return values to the code that calls them. We don’t name return
+values, but we do declare their type after an arrow (`->`). In Rust, the return
+value of the function is synonymous with the value of the final expression in
+the block of the body of a function. Here’s an example of a function that
+returns a value:
+
+Filename: src/main.rs
+
+```rust
+fn five() -> i32 {
+ 5
+}
+
+fn main() {
+ let x = five();
+
+ println!("The value of x is: {}", x);
+}
+```
+
+There are no function calls, macros, or even `let` statements in the `five`
+function—just the number `5` by itself. That’s a perfectly valid function in
+Rust. Note that the function’s return type is specified, too, as `-> i32`. Try
+running this code; the output should look like this:
+
+```text
+$ cargo run
+ Compiling functions v0.1.0 (file:///projects/functions)
+ Running `target/debug/functions`
+The value of x is: 5
+```
+
+The `5` in `five` is the function’s return value, which is why the return type
+is `i32`. Let’s examine this in more detail. There are two important bits:
+first, the line `let x = five();` shows that we’re using the return value of a
+function to initialize a variable. Because the function `five` returns a `5`,
+that line is the same as the following:
+
+```rust
+let x = 5;
+```
+
+Second, the `five` function has no parameters and defines the type of the
+return value, but the body of the function is a lonely `5` with no semicolon
+because it’s an expression whose value we want to return. Let’s look at another
+example:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let x = plus_one(5);
+
+ println!("The value of x is: {}", x);
+}
+
+fn plus_one(x: i32) -> i32 {
+ x + 1
+}
+```
+
+Running this code will print `The value of x is: 6`. What happens if we place a
+semicolon at the end of the line containing `x + 1`, changing it from an
+expression to a statement?
+
+Filename: src/main.rs
+
+```rust,ignore
+fn main() {
+ let x = plus_one(5);
+
+ println!("The value of x is: {}", x);
+}
+
+fn plus_one(x: i32) -> i32 {
+ x + 1;
+}
+```
+
+Running this code produces an error, as follows:
+
+```text
+error[E0308]: mismatched types
+ --> src/main.rs:7:28
+ |
+7 | fn plus_one(x: i32) -> i32 {
+ | ____________________________^ starting here...
+8 | | x + 1;
+9 | | }
+ | |_^ ...ending here: expected i32, found ()
+ |
+ = note: expected type `i32`
+ found type `()`
+help: consider removing this semicolon:
+ --> src/main.rs:8:10
+ |
+8 | x + 1;
+ | ^
+```
+
+The main error message, “mismatched types,” reveals the core issue with this
+code. The definition of the function `plus_one` says that it will return an
+`i32`, but statements don’t evaluate to a value, which is expressed by `()`,
+the empty tuple. Therefore, nothing is returned, which contradicts the function
+definition and results in an error. In this output, Rust provides a message to
+possibly help rectify this issue: it suggests removing the semicolon, which
+would fix the error.
diff --git a/trpl-2nd-edition/ch03-04-comments.md b/trpl-2nd-edition/ch03-04-comments.md
new file mode 100644
index 0000000..664e155
--- /dev/null
+++ b/trpl-2nd-edition/ch03-04-comments.md
@@ -0,0 +1,46 @@
+## Comments
+
+All programmers strive to make their code easy to understand, but sometimes
+extra explanation is warranted. In these cases, programmers leave notes, or
+*comments*, in their source code that the compiler will ignore but people
+reading the source code may find useful.
+
+Here’s a simple comment:
+
+```rust
+// Hello, world.
+```
+
+In Rust, comments must start with two slashes and continue until the end of the
+line. For comments that extend beyond a single line, you’ll need to include
+`//` on each line, like this:
+
+```rust
+// So we’re doing something complicated here, long enough that we need
+// multiple lines of comments to do it! Whew! Hopefully, this comment will
+// explain what’s going on.
+```
+
+Comments can also be placed at the end of lines containing code:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let lucky_number = 7; // I’m feeling lucky today.
+}
+```
+
+But you’ll more often see them used in this format, with the comment on a
+separate line above the code it's annotating:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ // I’m feeling lucky today.
+ let lucky_number = 7;
+}
+```
+
+That’s all there is to comments. They’re not particularly complicated.
diff --git a/trpl-2nd-edition/ch03-05-control-flow.md b/trpl-2nd-edition/ch03-05-control-flow.md
new file mode 100644
index 0000000..a448176
--- /dev/null
+++ b/trpl-2nd-edition/ch03-05-control-flow.md
@@ -0,0 +1,450 @@
+## Control Flow
+
+Deciding whether or not to run some code depending on if a condition is true or
+deciding to run some code repeatedly while a condition is true are basic
+building blocks in most programming languages. The most common constructs that
+let you control the flow of execution of Rust code are `if` expressions and
+loops.
+
+### `if` Expressions
+
+An `if` expression allows us to branch our code depending on conditions. We
+provide a condition and then state, “If this condition is met, run this block
+of code. If the condition is not met, do not run this block of code.”
+
+Create a new project called *branches* in your *projects* directory to explore
+the `if` expression. In the *src/main.rs* file, input the following:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let number = 3;
+
+ if number < 5 {
+ println!("condition was true");
+ } else {
+ println!("condition was false");
+ }
+}
+```
+
+
+
+All `if` expressions start with the keyword `if`, which is followed by a
+condition. In this case, the condition checks whether or not the variable
+`number` has a value less than 5. The block of code we want to execute if the
+condition is true is placed immediately after the condition inside curly
+braces. Blocks of code associated with the conditions in `if` expressions are
+sometimes called *arms*, just like the arms in `match` expressions that we
+discussed in the “Comparing the Guess to the Secret Number” section of
+Chapter 2. Optionally, we can also include an `else` expression, which we chose
+to do here, to give the program an alternative block of code to execute should
+the condition evaluate to false. If you don’t provide an `else` expression and
+the condition is false, the program will just skip the `if` block and move on
+to the next bit of code.
+
+Try running this code; you should see the following output:
+
+```text
+$ cargo run
+ Compiling branches v0.1.0 (file:///projects/branches)
+ Running `target/debug/branches`
+condition was true
+```
+
+Let’s try changing the value of `number` to a value that makes the condition
+`false` to see what happens:
+
+```rust,ignore
+let number = 7;
+```
+
+Run the program again, and look at the output:
+
+```text
+$ cargo run
+ Compiling branches v0.1.0 (file:///projects/branches)
+ Running `target/debug/branches`
+condition was false
+```
+
+It’s also worth noting that the condition in this code *must* be a `bool`. To
+see what happens if the condition isn’t a `bool`, try running the following
+code:
+
+Filename: src/main.rs
+
+```rust,ignore
+fn main() {
+ let number = 3;
+
+ if number {
+ println!("number was three");
+ }
+}
+```
+
+The `if` condition evaluates to a value of `3` this time, and Rust throws an
+error:
+
+```text
+error[E0308]: mismatched types
+ --> src/main.rs:4:8
+ |
+4 | if number {
+ | ^^^^^^ expected bool, found integral variable
+ |
+ = note: expected type `bool`
+ found type `{integer}`
+```
+
+The error indicates that Rust expected a `bool` but got an integer. Rust will
+not automatically try to convert non-boolean types to a boolean, unlike
+languages such as Ruby and JavaScript. You must be explicit and always provide
+`if` with a `boolean` as its condition. If we want the `if` code block to run
+only when a number is not equal to `0`, for example, we can change the `if`
+expression to the following:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let number = 3;
+
+ if number != 0 {
+ println!("number was something other than zero");
+ }
+}
+```
+
+Running this code will print `number was something other than zero`.
+
+#### Multiple Conditions with `else if`
+
+We can have multiple conditions by combining `if` and `else` in an `else if`
+expression. For example:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let number = 6;
+
+ if number % 4 == 0 {
+ println!("number is divisible by 4");
+ } else if number % 3 == 0 {
+ println!("number is divisible by 3");
+ } else if number % 2 == 0 {
+ println!("number is divisible by 2");
+ } else {
+ println!("number is not divisible by 4, 3, or 2");
+ }
+}
+```
+
+This program has four possible paths it can take. After running it, you should
+see the following output:
+
+```text
+$ cargo run
+ Compiling branches v0.1.0 (file:///projects/branches)
+ Running `target/debug/branches`
+number is divisible by 3
+```
+
+When this program executes, it checks each `if` expression in turn and executes
+the first body for which the condition holds true. Note that even though 6 is
+divisible by 2, we don’t see the output `number is divisible by 2`, nor do we
+see the `number is not divisible by 4, 3, or 2` text from the `else` block. The
+reason is that Rust will only execute the block for the first true condition,
+and once it finds one, it won’t even check the rest.
+
+Using too many `else if` expressions can clutter your code, so if you have more
+than one, you might want to refactor your code. Chapter 6 describes a powerful
+Rust branching construct called `match` for these cases.
+
+#### Using `if` in a `let` statement
+
+Because `if` is an expression, we can use it on the right side of a `let`
+statement, for instance in Listing 3-4:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let condition = true;
+ let number = if condition {
+ 5
+ } else {
+ 6
+ };
+
+ println!("The value of number is: {}", number);
+}
+```
+
+Listing 3-4: Assigning the result of an `if` expression
+to a variable
+
+The `number` variable will be bound to a value based on the outcome of the `if`
+expression. Run this code to see what happens:
+
+```text
+$ cargo run
+ Compiling branches v0.1.0 (file:///projects/branches)
+ Running `target/debug/branches`
+The value of number is: 5
+```
+
+Remember that blocks of code evaluate to the last expression in them, and
+numbers by themselves are also expressions. In this case, the value of the
+whole `if` expression depends on which block of code executes. This means the
+values that have the potential to be results from each arm of the `if` must be
+the same type; in Listing 3-4, the results of both the `if` arm and the `else`
+arm were `i32` integers. But what happens if the types are mismatched, as in
+the following example?
+
+Filename: src/main.rs
+
+```rust,ignore
+fn main() {
+ let condition = true;
+
+ let number = if condition {
+ 5
+ } else {
+ "six"
+ };
+
+ println!("The value of number is: {}", number);
+}
+```
+
+When we try to run this code, we’ll get an error. The `if` and `else` arms have
+value types that are incompatible, and Rust indicates exactly where to find the
+problem in the program:
+
+```text
+error[E0308]: if and else have incompatible types
+ --> src/main.rs:4:18
+ |
+4 | let number = if condition {
+ | __________________^ starting here...
+5 | | 5
+6 | | } else {
+7 | | "six"
+8 | | };
+ | |_____^ ...ending here: expected integral variable, found reference
+ |
+ = note: expected type `{integer}`
+ found type `&'static str`
+```
+
+The expression in the `if` block evaluates to an integer, and the expression in
+the `else` block evaluates to a string. This won’t work because variables must
+have a single type. Rust needs to know at compile time what type the `number`
+variable is, definitively, so it can verify at compile time that its type is
+valid everywhere we use `number`. Rust wouldn’t be able to do that if the type
+of `number` was only determined at runtime; the compiler would be more complex
+and would make fewer guarantees about the code if it had to keep track of
+multiple hypothetical types for any variable.
+
+### Repetition with Loops
+
+It’s often useful to execute a block of code more than once. For this task,
+Rust provides several *loops*. A loop runs through the code inside the loop
+body to the end and then starts immediately back at the beginning. To
+experiment with loops, let’s make a new project called *loops*.
+
+Rust has three kinds of loops: `loop`, `while`, and `for`. Let’s try each one.
+
+#### Repeating Code with `loop`
+
+The `loop` keyword tells Rust to execute a block of code over and over again
+forever or until you explicitly tell it to stop.
+
+As an example, change the *src/main.rs* file in your *loops* directory to look
+like this:
+
+Filename: src/main.rs
+
+```rust,ignore
+fn main() {
+ loop {
+ println!("again!");
+ }
+}
+```
+
+When we run this program, we’ll see `again!` printed over and over continuously
+until we stop the program manually. Most terminals support a keyboard shortcut,
+ ctrl-C, to halt a program that is stuck in a continual loop. Give it a try:
+
+```text
+$ cargo run
+ Compiling loops v0.1.0 (file:///projects/loops)
+ Running `target/debug/loops`
+again!
+again!
+again!
+again!
+^Cagain!
+```
+
+The symbol `^C` represents where you pressed ctrl-C. You may or may not see the
+word `again!` printed after the `^C`, depending on where the code was in the
+loop when it received the halt signal.
+
+Fortunately, Rust provides another, more reliable way to break out of a loop.
+You can place the `break` keyword within the loop to tell the program when to
+stop executing the loop. Recall that we did this in the guessing game in the
+“Quitting After a Correct Guess” section of Chapter 2 to exit the
+program when the user won the game by guessing the correct number.
+
+#### Conditional Loops with `while`
+
+It’s often useful for a program to evaluate a condition within a loop. While
+the condition is true, the loop runs. When the condition ceases to be true, you
+call `break`, stopping the loop. This loop type could be implemented using a
+combination of `loop`, `if`, `else`, and `break`; you could try that now in a
+program, if you’d like.
+
+However, this pattern is so common that Rust has a built-in language construct
+for it, and it’s called a `while` loop. The following example uses `while`: the
+program loops three times, counting down each time. Then, after the loop, it
+prints another message and exits:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let mut number = 3;
+
+ while number != 0 {
+ println!("{}!", number);
+
+ number = number - 1;
+ }
+
+ println!("LIFTOFF!!!");
+}
+```
+
+This construct eliminates a lot of nesting that would be necessary if you used
+`loop`, `if`, `else`, and `break`, and it’s clearer. While a condition holds
+true, the code runs; otherwise, it exits the loop.
+
+#### Looping Through a Collection with `for`
+
+You could use the `while` construct to loop over the elements of a collection,
+such as an array. For example:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let a = [10, 20, 30, 40, 50];
+ let mut index = 0;
+
+ while index < 5 {
+ println!("the value is: {}", a[index]);
+
+ index = index + 1;
+ }
+}
+```
+
+Listing 3-5: Looping through each element of a collection
+using a `while` loop
+
+Here, the code counts up through the elements in the array. It starts at index
+`0`, and then loops until it reaches the final index in the array (that is,
+when `index < 5` is no longer true). Running this code will print out every
+element in the array:
+
+```text
+$ cargo run
+ Compiling loops v0.1.0 (file:///projects/loops)
+ Running `target/debug/loops`
+the value is: 10
+the value is: 20
+the value is: 30
+the value is: 40
+the value is: 50
+```
+
+All five array values appear in the terminal, as expected. Even though `index`
+will reach a value of `5` at some point, the loop stops executing before trying
+to fetch a sixth value from the array.
+
+But this approach is error prone; we could cause the program to panic if the
+index length is incorrect. It’s also slow, because the compiler adds runtime
+code to perform the conditional check on every element on every iteration
+through the loop.
+
+As a more efficient alternative, you can use a `for` loop and execute some code
+for each item in a collection. A `for` loop looks like this:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let a = [10, 20, 30, 40, 50];
+
+ for element in a.iter() {
+ println!("the value is: {}", element);
+ }
+}
+```
+
+Listing 3-6: Looping through each element of a collection
+using a `for` loop
+
+When we run this code, we’ll see the same output as in Listing 3-5. More
+importantly, we’ve now increased the safety of the code and eliminated the
+chance of bugs that might result from going beyond the end of the array or not
+going far enough and missing some items.
+
+For example, in the code in Listing 3-5, if you removed an item from the `a`
+array but forgot to update the condition to `while index < 4`, the code would
+panic. Using the `for` loop, you don’t need to remember to change any other
+code if you changed the number of values in the array.
+
+The safety and conciseness of `for` loops make them the most commonly used loop
+construct in Rust. Even in situations in which you want to run some code a
+certain number of times, as in the countdown example that used a `while` loop
+in Listing 3-5, most Rustaceans would use a `for` loop. The way to do that
+would be to use a `Range`, which is a type provided by the standard library
+that generates all numbers in sequence starting from one number and ending
+before another number.
+
+Here’s what the countdown would look like using a `for` loop and another method
+we’ve not yet talked about, `rev`, to reverse the range:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ for number in (1..4).rev() {
+ println!("{}!", number);
+ }
+ println!("LIFTOFF!!!");
+}
+```
+
+This code is a bit nicer, isn’t it?
+
+## Summary
+
+You made it! That was a sizable chapter: you learned about variables, scalar
+and`if` expressions, and loops! If you want to practice with the concepts
+discussed in this chapter, try building programs to do the following:
+
+* Convert temperatures between Fahrenheit and Celsius.
+* Generate the nth Fibonacci number.
+* Print the lyrics to the Christmas carol “The Twelve Days of Christmas,”
+taking advantage of the repetition in the song.
+
+When you’re ready to move on, we’ll talk about a concept in Rust that *doesn’t*
+commonly exist in other programming languages: ownership.
diff --git a/trpl-2nd-edition/ch04-00-understanding-ownership.md b/trpl-2nd-edition/ch04-00-understanding-ownership.md
new file mode 100644
index 0000000..0b132e5
--- /dev/null
+++ b/trpl-2nd-edition/ch04-00-understanding-ownership.md
@@ -0,0 +1,7 @@
+# Understanding Ownership
+
+Ownership is Rust’s most unique feature, and it enables Rust to make memory
+safety guarantees without needing a garbage collector. Therefore, it’s
+important to understand how ownership works in Rust. In this chapter we’ll talk
+about ownership as well as several related features: borrowing, slices, and how
+Rust lays data out in memory.
diff --git a/trpl-2nd-edition/ch04-01-what-is-ownership.md b/trpl-2nd-edition/ch04-01-what-is-ownership.md
new file mode 100644
index 0000000..5324398
--- /dev/null
+++ b/trpl-2nd-edition/ch04-01-what-is-ownership.md
@@ -0,0 +1,548 @@
+## What Is Ownership?
+
+Rust’s central feature is *ownership*. Although the feature is straightforward
+to explain, it has deep implications for the rest of the language.
+
+All programs have to manage the way they use a computer’s memory while running.
+Some languages have garbage collection that constantly looks for no longer used
+memory as the program runs; in other languages, the programmer must explicitly
+allocate and free the memory. Rust uses a third approach: memory is managed
+through a system of ownership with a set of rules that the compiler checks at
+compile time. No run-time costs are incurred for any of the ownership features.
+
+Because ownership is a new concept for many programmers, it does take some time
+to get used to. The good news is that the more experienced you become with Rust
+and the rules of the ownership system, the more you’ll be able to naturally
+develop code that is safe and efficient. Keep at it!
+
+When you understand ownership, you’ll have a solid foundation for understanding
+the features that make Rust unique. In this chapter, you’ll learn ownership by
+working through some examples that focus on a very common data structure:
+strings.
+
+
+
+> ### The Stack and the Heap
+>
+> In many programming languages, we don’t have to think about the stack and the
+> heap very often. But in a systems programming language like Rust, whether a
+> value is on the stack or the heap has more of an effect on how the language
+> behaves and why we have to make certain decisions. We’ll describe parts of
+> ownership in relation to the stack and the heap later in this chapter, so here
+> is a brief explanation in preparation.
+>
+> Both the stack and the heap are parts of memory that is available to your code
+> to use at runtime, but they are structured in different ways. The stack stores
+> values in the order it gets them and removes the values in the opposite order.
+> This is referred to as *last in, first out*. Think of a stack of plates: when
+> you add more plates, you put them on top of the pile, and when you need a
+> plate, you take one off the top. Adding or removing plates from the middle or
+> bottom wouldn’t work as well! Adding data is called *pushing onto the stack*,
+> and removing data is called *popping off the stack*.
+>
+> The stack is fast because of the way it accesses the data: it never has to
+> search for a place to put new data or a place to get data from because that
+> place is always the top. Another property that makes the stack fast is that all
+> data on the stack must take up a known, fixed size.
+>
+> For data with a size unknown to us at compile time or a size that might change,
+> we can store data on the heap instead. The heap is less organized: when we put
+> data on the heap, we ask for some amount of space. The operating system finds
+> an empty spot somewhere in the heap that is big enough, marks it as being in
+> use, and returns to us a pointer to that location. This process is called
+> *allocating on the heap*, and sometimes we abbreviate the phrase as just
+> “allocating.” Pushing values onto the stack is not considered allocating.
+> Because the pointer is a known, fixed size, we can store the pointer on the
+> stack, but when we want the actual data, we have to follow the pointer.
+>
+> Think of being seated at a restaurant. When you enter, you state the number of
+> people in your group, and the staff finds an empty table that fits everyone and
+> leads you there. If someone in your group comes late, they can ask where you’ve
+> been seated to find you.
+>
+> Accessing data in the heap is slower than accessing data on the stack because
+> we have to follow a pointer to get there. Contemporary processors are faster if
+> they jump around less in memory. Continuing the analogy, consider a server at a
+> restaurant taking orders from many tables. It’s most efficient to get all the
+> orders at one table before moving on to the next table. Taking an order from
+> table A, then an order from table B, then one from A again, and then one from B
+> again would be a much slower process. By the same token, a processor can do its
+> job better if it works on data that’s close to other data (as it is on the
+> stack) rather than farther away (as it can be on the heap). Allocating a large
+> amount of space on the heap can also take time.
+>
+> When our code calls a function, the values passed into the function (including,
+> potentially, pointers to data on the heap) and the function’s local variables
+> get pushed onto the stack. When the function is over, those values get popped
+> off the stack.
+>
+> Keeping track of what parts of code are using what data on the heap, minimizing
+> the amount of duplicate data on the heap, and cleaning up unused data on the
+> heap so we don’t run out of space are all problems that ownership addresses.
+> Once you understand ownership, you won’t need to think about the stack and the
+> heap very often, but knowing that managing heap data is why ownership exists
+> can help explain why it works the way it does.
+>
+
+
+### Ownership Rules
+
+First, let’s take a look at the ownership rules. Keep these rules in mind as we
+work through the examples that illustrate the rules:
+
+> 1. Each value in Rust has a variable that’s called its *owner*.
+> 2. There can only be one owner at a time.
+> 3. When the owner goes out of scope, the value will be dropped.
+
+### Variable Scope
+
+We’ve walked through an example of a Rust program already in Chapter 2. Now
+that we’re past basic syntax, we won’t include all the `fn main() {` code in
+examples, so if you’re following along, you’ll have to put the following
+examples inside a `main` function manually. As a result, our examples will be a
+bit more concise, letting us focus on the actual details rather than
+boilerplate code.
+
+As a first example of ownership, we’ll look at the *scope* of some variables. A
+scope is the range within a program for which an item is valid. Let’s say we
+have a variable that looks like this:
+
+```rust
+let s = "hello";
+```
+
+The variable `s` refers to a string literal, where the value of the string is
+hardcoded into the text of our program. The variable is valid from the point at
+which it’s declared until the end of the current *scope*. Listing 4-1 has
+comments annotating where the variable `s` is valid:
+
+```rust
+{ // s is not valid here, it’s not yet declared
+ let s = "hello"; // s is valid from this point forward
+
+ // do stuff with s
+} // this scope is now over, and s is no longer valid
+```
+
+Listing 4-1: A variable and the scope in which it is
+valid
+
+In other words, there are two important points in time here:
+
+1. When `s` comes *into scope*, it is valid.
+1. It remains so until it goes *out of scope*.
+
+At this point, the relationship between scopes and when variables are valid is
+similar to other programming languages. Now we’ll build on top of this
+understanding by introducing the `String` type.
+
+### The `String` Type
+
+To illustrate the rules of ownership, we need a data type that is more complex
+than the ones we covered in Chapter 3. All the data types we’ve looked at
+previously are stored on the stack and popped off the stack when their scope is
+over, but we want to look at data that is stored on the heap and explore how
+Rust knows when to clean up that data.
+
+We’ll use `String` as the example here and concentrate on the parts of `String`
+that relate to ownership. These aspects also apply to other complex data types
+provided by the standard library and that you create. We’ll discuss `String` in
+more depth in Chapter 8.
+
+We’ve already seen string literals, where a string value is hardcoded into our
+program. String literals are convenient, but they aren’t always suitable for
+every situation in which you want to use text. One reason is that they’re
+immutable. Another is that not every string value can be known when we write
+our code: for example, what if we want to take user input and store it? For
+these situations, Rust has a second string type, `String`. This type is
+allocated on the heap and as such is able to store an amount of text that is
+unknown to us at compile time. You can create a `String` from a string literal
+using the `from` function, like so:
+
+```rust
+let s = String::from("hello");
+```
+
+The double colon (`::`) is an operator that allows us to namespace this
+particular `from` function under the `String` type rather than using some sort
+of name like `string_from`. We’ll discuss this syntax more in the “Method
+Syntax” section of Chapter 5 and when we talk about namespacing with modules in
+Chapter 7.
+
+This kind of string *can* be mutated:
+
+```rust
+let mut s = String::from("hello");
+
+s.push_str(", world!"); // push_str() appends a literal to a String
+
+println!("{}", s); // This will print `hello, world!`
+```
+
+So, what’s the difference here? Why can `String` be mutated but literals
+cannot? The difference is how these two types deal with memory.
+
+### Memory and Allocation
+
+In the case of a string literal, we know the contents at compile time so the
+text is hardcoded directly into the final executable, making string literals
+fast and efficient. But these properties only come from its immutability.
+Unfortunately, we can’t put a blob of memory into the binary for each piece of
+text whose size is unknown at compile time and whose size might change while
+running the program.
+
+With the `String` type, in order to support a mutable, growable piece of text,
+we need to allocate an amount of memory on the heap, unknown at compile time,
+to hold the contents. This means:
+
+1. The memory must be requested from the operating system at runtime.
+2. We need a way of returning this memory to the operating system when we’re
+done with our `String`.
+
+That first part is done by us: when we call `String::from`, its implementation
+requests the memory it needs. This is pretty much universal in programming
+languages.
+
+However, the second part is different. In languages with a *garbage collector
+(GC)*, the GC keeps track and cleans up memory that isn’t being used anymore,
+and we, as the programmer, don’t need to think about it. Without a GC, it’s the
+programmer’s responsibility to identify when memory is no longer being used and
+call code to explicitly return it, just as we did to request it. Doing this
+correctly has historically been a difficult programming problem. If we forget,
+we’ll waste memory. If we do it too early, we’ll have an invalid variable. If
+we do it twice, that’s a bug too. We need to pair exactly one `allocate` with
+exactly one `free`.
+
+Rust takes a different path: the memory is automatically returned once the
+variable that owns it goes out of scope. Here’s a version of our scope example
+from Listing 4-1 using a `String` instead of a string literal:
+
+```rust
+{
+ let s = String::from("hello"); // s is valid from this point forward
+
+ // do stuff with s
+} // this scope is now over, and s is no
+ // longer valid
+```
+
+There is a natural point at which we can return the memory our `String` needs
+to the operating system: when `s` goes out of scope. When a variable goes out
+of scope, Rust calls a special function for us. This function is called `drop`,
+and it’s where the author of `String` can put the code to return the memory.
+Rust calls `drop` automatically at the closing `}`.
+
+> Note: In C++, this pattern of deallocating resources at the end of an item's
+> lifetime is sometimes called *Resource Acquisition Is Initialization (RAII)*.
+> The `drop` function in Rust will be familiar to you if you’ve used RAII
+> patterns.
+
+This pattern has a profound impact on the way Rust code is written. It may seem
+simple right now, but the behavior of code can be unexpected in more
+complicated situations when we want to have multiple variables use the data
+we’ve allocated on the heap. Let’s explore some of those situations now.
+
+#### Ways Variables and Data Interact: Move
+
+Multiple variables can interact with the same data in different ways in Rust.
+Let’s look at an example using an integer in Listing 4-2:
+
+```rust
+let x = 5;
+let y = x;
+```
+
+Listing 4-2: Assigning the integer value of variable `x`
+to `y`
+
+We can probably guess what this is doing based on our experience with other
+languages: “Bind the value `5` to `x`; then make a copy of the value in `x` and
+bind it to `y`.” We now have two variables, `x` and `y`, and both equal `5`.
+This is indeed what is happening because integers are simple values with a
+known, fixed size, and these two `5` values are pushed onto the stack.
+
+Now let’s look at the `String` version:
+
+```rust
+let s1 = String::from("hello");
+let s2 = s1;
+```
+
+This looks very similar to the previous code, so we might assume that the way
+it works would be the same: that is, the second line would make a copy of the
+value in `s1` and bind it to `s2`. But this isn’t quite what happens.
+
+To explain this more thoroughly, let’s look at what `String` looks like under
+the covers in Figure 4-3. A `String` is made up of three parts, shown on the
+left: a pointer to the memory that holds the contents of the string, a length,
+and a capacity. This group of data is stored on the stack. On the right is the
+memory on the heap that holds the contents.
+
+
+
+Figure 4-3: Representation in memory of a `String`
+holding the value `"hello"` bound to `s1`
+
+The length is how much memory, in bytes, the contents of the `String` is
+currently using. The capacity is the total amount of memory, in bytes, that the
+`String` has received from the operating system. The difference between length
+and capacity matters, but not in this context, so for now, it’s fine to ignore
+the capacity.
+
+When we assign `s1` to `s2`, the `String` data is copied, meaning we copy the
+pointer, the length, and the capacity that are on the stack. We do not copy the
+data on the heap that the pointer refers to. In other words, the data
+representation in memory looks like Figure 4-4.
+
+
+
+Figure 4-4: Representation in memory of the variable `s2`
+that has a copy of the pointer, length, and capacity of `s1`
+
+The representation does *not* look like Figure 4-5, which is what memory would
+look like if Rust instead copied the heap data as well. If Rust did this, the
+operation `s2 = s1` could potentially be very expensive in terms of runtime
+performance if the data on the heap was large.
+
+
+
+Figure 4-5: Another possibility of what `s2 = s1` might
+do if Rust copied the heap data as well
+
+Earlier, we said that when a variable goes out of scope, Rust automatically
+calls the `drop` function and cleans up the heap memory for that variable. But
+Figure 4-4 shows both data pointers pointing to the same location. This is a
+problem: when `s2` and `s1` go out of scope, they will both try to free the
+same memory. This is known as a *double free* error and is one of the memory
+safety bugs we mentioned previously. Freeing memory twice can lead to memory
+corruption, which can potentially lead to security vulnerabilities.
+
+To ensure memory safety, there’s one more detail to what happens in this
+situation in Rust. Instead of trying to copy the allocated memory, Rust
+considers `s1` to no longer be valid and therefore, Rust doesn’t need to free
+anything when `s1` goes out of scope. Check out what happens when you try to
+use `s1` after `s2` is created:
+
+```rust,ignore
+let s1 = String::from("hello");
+let s2 = s1;
+
+println!("{}", s1);
+```
+
+You’ll get an error like this because Rust prevents you from using the
+invalidated reference:
+
+```text
+error[E0382]: use of moved value: `s1`
+ --> src/main.rs:4:27
+ |
+3 | let s2 = s1;
+ | -- value moved here
+4 | println!("{}, world!",s1);
+ | ^^ value used here after move
+ |
+ = note: move occurs because `s1` has type `std::string::String`,
+which does not implement the `Copy` trait
+```
+
+If you’ve heard the terms “shallow copy” and “deep copy” while working with
+other languages, the concept of copying the pointer, length, and capacity
+without copying the data probably sounds like a shallow copy. But because Rust
+also invalidates the first variable, instead of calling this a shallow copy,
+it’s known as a *move*. Here we would read this by saying that `s1` was *moved*
+into `s2`. So what actually happens is shown in Figure 4-6.
+
+
+
+Figure 4-6: Representation in memory after `s1` has been
+invalidated
+
+That solves our problem! With only `s2` valid, when it goes out of scope, it
+alone will free the memory, and we’re done.
+
+In addition, there’s a design choice that’s implied by this: Rust will never
+automatically create “deep” copies of your data. Therefore, any *automatic*
+copying can be assumed to be inexpensive in terms of runtime performance.
+
+#### Ways Variables and Data Interact: Clone
+
+If we *do* want to deeply copy the heap data of the `String`, not just the
+stack data, we can use a common method called `clone`. We’ll discuss method
+syntax in Chapter 5, but because methods are a common feature in many
+programming languages, you’ve probably seen them before.
+
+Here’s an example of the `clone` method in action:
+
+```rust
+let s1 = String::from("hello");
+let s2 = s1.clone();
+
+println!("s1 = {}, s2 = {}", s1, s2);
+```
+
+This works just fine and is how you can explicitly produce the behavior shown
+in Figure 4-5, where the heap data *does* get copied.
+
+When you see a call to `clone`, you know that some arbitrary code is being
+executed and that code may be expensive. It’s a visual indicator that something
+different is going on.
+
+#### Stack-Only Data: Copy
+
+There’s another wrinkle we haven’t talked about yet. This code using integers,
+part of which was shown earlier in Listing 4-2, works and is valid:
+
+```rust
+let x = 5;
+let y = x;
+
+println!("x = {}, y = {}", x, y);
+```
+
+But this code seems to contradict what we just learned: we don’t have a call to
+`clone`, but `x` is still valid and wasn’t moved into `y`.
+
+The reason is that types like integers that have a known size at compile time
+are stored entirely on the stack, so copies of the actual values are quick to
+make. That means there’s no reason we would want to prevent `x` from being
+valid after we create the variable `y`. In other words, there’s no difference
+between deep and shallow copying here, so calling `clone` wouldn’t do anything
+differently from the usual shallow copying and we can leave it out.
+
+Rust has a special annotation called the `Copy` trait that we can place on
+types like integers that are stored on the stack (we’ll talk more about traits
+in Chapter 10). If a type has the `Copy` trait, an older variable is still
+usable after assignment. Rust won’t let us annotate a type with the `Copy`
+trait if the type, or any of its parts, has implemented the `Drop` trait. If
+the type needs something special to happen when the value goes out of scope and
+we add the `Copy` annotation to that type, we’ll get a compile time error. To
+learn about how to add the `Copy` annotation to your type, see Appendix C on
+Derivable Traits.
+
+So what types are `Copy`? You can check the documentation for the given type to
+be sure, but as a general rule, any group of simple scalar values can be
+`Copy`, and nothing that requires allocation or is some form of resource is
+`Copy`. Here are some of the types that are `Copy`:
+
+* All the integer types, like `u32`.
+* The boolean type, `bool`, with values `true` and `false`.
+* All the floating point types, like `f64`.
+* Tuples, but only if they contain types that are also `Copy`. `(i32, i32)` is
+`Copy`, but `(i32, String)` is not.
+
+### Ownership and Functions
+
+The semantics for passing a value to a function are similar to assigning a
+value to a variable. Passing a variable to a function will move or copy, just
+like assignment. Listing 4-7 has an example with some annotations showing where
+variables go into and out of scope:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let s = String::from("hello"); // s comes into scope.
+
+ takes_ownership(s); // s's value moves into the function...
+ // ... and so is no longer valid here.
+ let x = 5; // x comes into scope.
+
+ makes_copy(x); // x would move into the function,
+ // but i32 is Copy, so it’s okay to still
+ // use x afterward.
+
+} // Here, x goes out of scope, then s. But since s's value was moved, nothing
+ // special happens.
+
+fn takes_ownership(some_string: String) { // some_string comes into scope.
+ println!("{}", some_string);
+} // Here, some_string goes out of scope and `drop` is called. The backing
+ // memory is freed.
+
+fn makes_copy(some_integer: i32) { // some_integer comes into scope.
+ println!("{}", some_integer);
+} // Here, some_integer goes out of scope. Nothing special happens.
+```
+
+Listing 4-7: Functions with ownership and scope
+annotated
+
+If we tried to use `s` after the call to `takes_ownership`, Rust would throw a
+compile time error. These static checks protect us from mistakes. Try adding
+code to `main` that uses `s` and `x` to see where you can use them and where
+the ownership rules prevent you from doing so.
+
+### Return Values and Scope
+
+Returning values can also transfer ownership. Here’s an example with similar
+annotations to those in Listing 4-7:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let s1 = gives_ownership(); // gives_ownership moves its return
+ // value into s1.
+
+ let s2 = String::from("hello"); // s2 comes into scope.
+
+ let s3 = takes_and_gives_back(s2); // s2 is moved into
+ // takes_and_gives_back, which also
+ // moves its return value into s3.
+} // Here, s3 goes out of scope and is dropped. s2 goes out of scope but was
+ // moved, so nothing happens. s1 goes out of scope and is dropped.
+
+fn gives_ownership() -> String { // gives_ownership will move its
+ // return value into the function
+ // that calls it.
+
+ let some_string = String::from("hello"); // some_string comes into scope.
+
+ some_string // some_string is returned and
+ // moves out to the calling
+ // function.
+}
+
+// takes_and_gives_back will take a String and return one.
+fn takes_and_gives_back(a_string: String) -> String { // a_string comes into
+ // scope.
+
+ a_string // a_string is returned and moves out to the calling function.
+}
+```
+
+The ownership of a variable follows the same pattern every time: assigning a
+value to another variable moves it. When a variable that includes data on the
+heap goes out of scope, the value will be cleaned up by `drop` unless the data
+has been moved to be owned by another variable.
+
+Taking ownership and then returning ownership with every function is a bit
+tedious. What if we want to let a function use a value but not take ownership?
+It’s quite annoying that anything we pass in also needs to be passed back if we
+want to use it again, in addition to any data resulting from the body of the
+function that we might want to return as well.
+
+It’s possible to return multiple values using a tuple, like this:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let s1 = String::from("hello");
+
+ let (s2, len) = calculate_length(s1);
+
+ println!("The length of '{}' is {}.", s2, len);
+}
+
+fn calculate_length(s: String) -> (String, usize) {
+ let length = s.len(); // len() returns the length of a String.
+
+ (s, length)
+}
+```
+
+But this is too much ceremony and a lot of work for a concept that should be
+common. Luckily for us, Rust has a feature for this concept, and it’s called
+*references*.
diff --git a/trpl-2nd-edition/ch04-02-references-and-borrowing.md b/trpl-2nd-edition/ch04-02-references-and-borrowing.md
new file mode 100644
index 0000000..d42229b
--- /dev/null
+++ b/trpl-2nd-edition/ch04-02-references-and-borrowing.md
@@ -0,0 +1,316 @@
+## References and Borrowing
+
+The issue with the tuple code at the end of the preceding section is that we
+have to return the `String` to the calling function so we can still use the
+`String` after the call to `calculate_length`, because the `String` was moved
+into `calculate_length`.
+
+Here is how you would define and use a `calculate_length` function that has a
+*reference* to an object as a parameter instead of taking ownership of the
+value:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let s1 = String::from("hello");
+
+ let len = calculate_length(&s1);
+
+ println!("The length of '{}' is {}.", s1, len);
+}
+
+fn calculate_length(s: &String) -> usize {
+ s.len()
+}
+```
+
+First, notice that all the tuple code in the variable declaration and the
+function return value is gone. Second, note that we pass `&s1` into
+`calculate_length`, and in its definition, we take `&String` rather than
+`String`.
+
+These ampersands are *references*, and they allow you to refer to some value
+without taking ownership of it. Figure 4-8 shows a diagram.
+
+
+
+Figure 4-8: `&String s` pointing at `String s1`
+
+Let’s take a closer look at the function call here:
+
+```rust
+# fn calculate_length(s: &String) -> usize {
+# s.len()
+# }
+let s1 = String::from("hello");
+
+let len = calculate_length(&s1);
+```
+
+The `&s1` syntax lets us create a reference that *refers* to the value of `s1`
+but does not own it. Because it does not own it, the value it points to will
+not be dropped when the reference goes out of scope.
+
+Likewise, the signature of the function uses `&` to indicate that the type of
+the parameter `s` is a reference. Let’s add some explanatory annotations:
+
+```rust
+fn calculate_length(s: &String) -> usize { // s is a reference to a String
+ s.len()
+} // Here, s goes out of scope. But because it does not have ownership of what
+ // it refers to, nothing happens.
+```
+
+The scope in which the variable `s` is valid is the same as any function
+parameter's scope, but we don’t drop what the reference points to when it goes
+out of scope because we don’t have ownership. Functions that have references as
+parameters instead of the actual values mean we won’t need to return the values
+in order to give back ownership, since we never had ownership.
+
+We call having references as function parameters *borrowing*. As in real life,
+if a person owns something, you can borrow it from them. When you’re done, you
+have to give it back.
+
+So what happens if we try to modify something we’re borrowing? Try the code in
+Listing 4-9. Spoiler alert: it doesn’t work!
+
+Filename: src/main.rs
+
+```rust,ignore
+fn main() {
+ let s = String::from("hello");
+
+ change(&s);
+}
+
+fn change(some_string: &String) {
+ some_string.push_str(", world");
+}
+```
+
+Listing 4-9: Attempting to modify a borrowed value
+
+Here’s the error:
+
+```text
+error: cannot borrow immutable borrowed content `*some_string` as mutable
+ --> error.rs:8:5
+ |
+8 | some_string.push_str(", world");
+ | ^^^^^^^^^^^
+```
+
+Just as variables are immutable by default, so are references. We’re not
+allowed to modify something we have a reference to.
+
+### Mutable References
+
+We can fix the error in the code from Listing 4-9 with just a small tweak:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let mut s = String::from("hello");
+
+ change(&mut s);
+}
+
+fn change(some_string: &mut String) {
+ some_string.push_str(", world");
+}
+```
+
+First, we had to change `s` to be `mut`. Then we had to create a mutable
+reference with `&mut s` and accept a mutable reference with `some_string: &mut
+String`.
+
+But mutable references have one big restriction: you can only have one mutable
+reference to a particular piece of data in a particular scope. This code will
+fail:
+
+Filename: src/main.rs
+
+```rust,ignore
+let mut s = String::from("hello");
+
+let r1 = &mut s;
+let r2 = &mut s;
+```
+
+Here’s the error:
+
+```text
+error[E0499]: cannot borrow `s` as mutable more than once at a time
+ --> borrow_twice.rs:5:19
+ |
+4 | let r1 = &mut s;
+ | - first mutable borrow occurs here
+5 | let r2 = &mut s;
+ | ^ second mutable borrow occurs here
+6 | }
+ | - first borrow ends here
+```
+
+This restriction allows for mutation but in a very controlled fashion. It’s
+something that new Rustaceans struggle with, because most languages let you
+mutate whenever you’d like. The benefit of having this restriction is that Rust
+can prevent data races at compile time.
+
+A *data race* is a particular type of race condition in which these three
+behaviors occur:
+
+1. Two or more pointers access the same data at the same time.
+1. At least one of the pointers is being used to write to the data.
+1. There’s no mechanism being used to synchronize access to the data.
+
+Data races cause undefined behavior and can be difficult to diagnose and fix
+when you’re trying to track them down at runtime; Rust prevents this problem
+from happening because it won’t even compile code with data races!
+
+As always, we can use curly brackets to create a new scope, allowing for
+multiple mutable references, just not *simultaneous* ones:
+
+```rust
+let mut s = String::from("hello");
+
+{
+ let r1 = &mut s;
+
+} // r1 goes out of scope here, so we can make a new reference with no problems.
+
+let r2 = &mut s;
+```
+
+A similar rule exists for combining mutable and immutable references. This code
+results in an error:
+
+```rust,ignore
+let mut s = String::from("hello");
+
+let r1 = &s; // no problem
+let r2 = &s; // no problem
+let r3 = &mut s; // BIG PROBLEM
+```
+
+Here’s the error:
+
+```text
+error[E0502]: cannot borrow `s` as mutable because it is also borrowed as
+immutable
+ --> borrow_thrice.rs:6:19
+ |
+4 | let r1 = &s; // no problem
+ | - immutable borrow occurs here
+5 | let r2 = &s; // no problem
+6 | let r3 = &mut s; // BIG PROBLEM
+ | ^ mutable borrow occurs here
+7 | }
+ | - immutable borrow ends here
+```
+
+Whew! We *also* cannot have a mutable reference while we have an immutable one.
+Users of an immutable reference don’t expect the values to suddenly change out
+from under them! However, multiple immutable references are okay because no one
+who is just reading the data has the ability to affect anyone else’s reading of
+the data.
+
+Even though these errors may be frustrating at times, remember that it’s the
+Rust compiler pointing out a potential bug early (at compile time rather than
+at runtime) and showing you exactly where the problem is instead of you having
+to track down why sometimes your data isn’t what you thought it should be.
+
+### Dangling References
+
+In languages with pointers, it’s easy to erroneously create a *dangling
+pointer*, a pointer that references a location in memory that may have been
+given to someone else, by freeing some memory while preserving a pointer to
+that memory. In Rust, by contrast, the compiler guarantees that references will
+never be dangling references: if we have a reference to some data, the compiler
+will ensure that the data will not go out of scope before the reference to the
+data does.
+
+Let’s try to create a dangling reference:
+
+Filename: src/main.rs
+
+```rust,ignore
+fn main() {
+ let reference_to_nothing = dangle();
+}
+
+fn dangle() -> &String {
+ let s = String::from("hello");
+
+ &s
+}
+```
+
+Here’s the error:
+
+```text
+error[E0106]: missing lifetime specifier
+ --> dangle.rs:5:16
+ |
+5 | fn dangle() -> &String {
+ | ^^^^^^^
+ |
+ = help: this function's return type contains a borrowed value, but there is no
+ value for it to be borrowed from
+ = help: consider giving it a 'static lifetime
+
+error: aborting due to previous error
+```
+
+This error message refers to a feature we haven’t covered yet: *lifetimes*.
+We’ll discuss lifetimes in detail in Chapter 10. But, if you disregard the
+parts about lifetimes, the message does contain the key to why this code is a
+problem:
+
+```text
+this function's return type contains a borrowed value, but there is no value
+for it to be borrowed from.
+```
+
+Let’s take a closer look at exactly what’s happening at each stage of our
+`dangle` code:
+
+```rust,ignore
+fn dangle() -> &String { // dangle returns a reference to a String
+
+ let s = String::from("hello"); // s is a new String
+
+ &s // we return a reference to the String, s
+} // Here, s goes out of scope, and is dropped. Its memory goes away.
+ // Danger!
+```
+
+Because `s` is created inside `dangle`, when the code of `dangle` is finished,
+`s` will be deallocated. But we tried to return a reference to it. That means
+this reference would be pointing to an invalid `String`! That’s no good. Rust
+won’t let us do this.
+
+The solution here is to return the `String` directly:
+
+```rust
+fn no_dangle() -> String {
+ let s = String::from("hello");
+
+ s
+}
+```
+
+This works without any problems. Ownership is moved out, and nothing is
+deallocated.
+
+### The Rules of References
+
+Let’s recap what we’ve discussed about references:
+
+1. At any given time, you can have *either* but not both of:
+ * One mutable reference.
+ * Any number of immutable references.
+2. References must always be valid.
+
+Next, we’ll look at a different kind of reference: slices.
diff --git a/trpl-2nd-edition/ch04-03-slices.md b/trpl-2nd-edition/ch04-03-slices.md
new file mode 100644
index 0000000..e348491
--- /dev/null
+++ b/trpl-2nd-edition/ch04-03-slices.md
@@ -0,0 +1,379 @@
+## Slices
+
+Another data type that does not have ownership is the *slice*. Slices let you
+reference a contiguous sequence of elements in a collection rather than the
+whole collection.
+
+Here’s a small programming problem: write a function that takes a string and
+returns the first word it finds in that string. If the function doesn’t find a
+space in the string, it means the whole string is one word, so the entire
+string should be returned.
+
+Let’s think about the signature of this function:
+
+```rust,ignore
+fn first_word(s: &String) -> ?
+```
+
+This function, `first_word`, has a `&String` as a parameter. We don’t want
+ownership, so this is fine. But what should we return? We don’t really have a
+way to talk about *part* of a string. However, we could return the index of the
+end of the word. Let’s try that as shown in Listing 4-10:
+
+Filename: src/main.rs
+
+```rust
+fn first_word(s: &String) -> usize {
+ let bytes = s.as_bytes();
+
+ for (i, &item) in bytes.iter().enumerate() {
+ if item == b' ' {
+ return i;
+ }
+ }
+
+ s.len()
+}
+```
+
+Listing 4-10: The `first_word` function that returns a
+byte index value into the `String` parameter
+
+Let’s break down this code a bit. Because we need to go through the `String`
+element by element and check whether a value is a space, we’ll convert our
+`String` to an array of bytes using the `as_bytes` method:
+
+```rust,ignore
+let bytes = s.as_bytes();
+```
+
+Next, we create an iterator over the array of bytes using the `iter` method :
+
+```rust,ignore
+for (i, &item) in bytes.iter().enumerate() {
+```
+
+We’ll discuss iterators in more detail in Chapter 13. For now, know that `iter`
+is a method that returns each element in a collection, and `enumerate` wraps
+the result of `iter` and returns each element as part of a tuple instead. The
+first element of the returned tuple is the index, and the second element is a
+reference to the element. This is a bit more convenient than calculating the
+index ourselves.
+
+Because the `enumerate` method returns a tuple, we can use patterns to
+destructure that tuple, just like everywhere else in Rust. So in the `for`
+loop, we specify a pattern that has `i` for the index in the tuple and `&item`
+for the single byte in the tuple. Because we get a reference to the element
+from `.iter().enumerate()`, we use `&` in the pattern.
+
+We search for the byte that represents the space by using the byte literal
+syntax. If we find a space, we return the position. Otherwise, we return the
+length of the string by using `s.len()`:
+
+```rust,ignore
+ if item == b' ' {
+ return i;
+ }
+}
+s.len()
+```
+
+We now have a way to find out the index of the end of the first word in the
+string, but there’s a problem. We’re returning a `usize` on its own, but it’s
+only a meaningful number in the context of the `&String`. In other words,
+because it’s a separate value from the `String`, there’s no guarantee that it
+will still be valid in the future. Consider the program in Listing 4-11 that
+uses the `first_word` function from Listing 4-10:
+
+Filename: src/main.rs
+
+```rust
+# fn first_word(s: &String) -> usize {
+# let bytes = s.as_bytes();
+#
+# for (i, &item) in bytes.iter().enumerate() {
+# if item == b' ' {
+# return i;
+# }
+# }
+#
+# s.len()
+# }
+#
+fn main() {
+ let mut s = String::from("hello world");
+
+ let word = first_word(&s); // word will get the value 5.
+
+ s.clear(); // This empties the String, making it equal to "".
+
+ // word still has the value 5 here, but there's no more string that
+ // we could meaningfully use the value 5 with. word is now totally invalid!
+}
+```
+
+Listing 4-11: Storing the result from calling the
+`first_word` function then changing the `String` contents
+
+This program compiles without any errors and also would if we used `word` after
+calling `s.clear()`. `word` isn’t connected to the state of `s` at all, so
+`word` still contains the value `5`. We could use that value `5` with the
+variable `s` to try to extract the first word out, but this would be a bug
+because the contents of `s` have changed since we saved `5` in `word`.
+
+Having to worry about the index in `word` getting out of sync with the data in
+`s` is tedious and error prone! Managing these indices is even more brittle if
+we write a `second_word` function. Its signature would have to look like this:
+
+```rust,ignore
+fn second_word(s: &String) -> (usize, usize) {
+```
+
+Now we’re tracking a start *and* an ending index, and we have even more values
+that were calculated from data in a particular state but aren’t tied to that
+state at all. We now have three unrelated variables floating around that need
+to be kept in sync.
+
+Luckily, Rust has a solution to this problem: string slices.
+
+### String Slices
+
+A *string slice* is a reference to part of a `String`, and looks like this:
+
+```rust
+let s = String::from("hello world");
+
+let hello = &s[0..5];
+let world = &s[6..11];
+```
+
+This is similar to taking a reference to the whole `String` but with the extra
+`[0..5]` bit. Rather than a reference to the entire `String`, it’s a reference
+to an internal position in the `String` and the number of elements that it
+refers to.
+
+We create slices with a range of `[starting_index..ending_index]`, but the
+slice data structure actually stores the starting position and the length of
+the slice. So in the case of `let world = &s[6..11];`, `world` would be a slice
+that contains a pointer to the 6th byte of `s` and a length value of 5.
+
+Figure 4-12 shows this in a diagram.
+
+
+
+Figure 4-12: String slice referring to part of a
+`String`
+
+With Rust’s `..` range syntax, if you want to start at the first index (zero),
+you can drop the value before the two periods. In other words, these are equal:
+
+```rust
+let s = String::from("hello");
+
+let slice = &s[0..2];
+let slice = &s[..2];
+```
+
+By the same token, if your slice includes the last byte of the `String`, you
+can drop the trailing number. That means these are equal:
+
+```rust
+let s = String::from("hello");
+
+let len = s.len();
+
+let slice = &s[3..len];
+let slice = &s[3..];
+```
+
+You can also drop both values to take a slice of the entire string. So these
+are equal:
+
+```rust
+let s = String::from("hello");
+
+let len = s.len();
+
+let slice = &s[0..len];
+let slice = &s[..];
+```
+
+With all this information in mind, let’s rewrite `first_word` to return a
+slice. The type that signifies “string slice” is written as `&str`:
+
+Filename: src/main.rs
+
+```rust
+fn first_word(s: &String) -> &str {
+ let bytes = s.as_bytes();
+
+ for (i, &item) in bytes.iter().enumerate() {
+ if item == b' ' {
+ return &s[0..i];
+ }
+ }
+
+ &s[..]
+}
+```
+
+We get the index for the end of the word in the same way as we did in Listing
+4-10, by looking for the first occurrence of a space. When we find a space, we
+return a string slice using the start of the string and the index of the space
+as the starting and ending indices.
+
+Now when we call `first_word`, we get back a single value that is tied to the
+underlying data. The value is made up of a reference to the starting point of
+the slice and the number of elements in the slice.
+
+Returning a slice would also work for a `second_word` function:
+
+```rust,ignore
+fn second_word(s: &String) -> &str {
+```
+
+We now have a straightforward API that’s much harder to mess up, since the
+compiler will ensure the references into the `String` remain valid. Remember
+the bug in the program in Listing 4-11, when we got the index to the end of the
+first word but then cleared the string so our index was invalid? That code was
+logically incorrect but didn’t show any immediate errors. The problems would
+show up later if we kept trying to use the first word index with an emptied
+string. Slices make this bug impossible and let us know we have a problem with
+our code much sooner. Using the slice version of `first_word` will throw a
+compile time error:
+
+Filename: src/main.rs
+
+```rust,ignore
+fn main() {
+ let mut s = String::from("hello world");
+
+ let word = first_word(&s);
+
+ s.clear(); // Error!
+}
+```
+
+Here’s the compiler error:
+
+```text
+17:6 error: cannot borrow `s` as mutable because it is also borrowed as
+ immutable [E0502]
+ s.clear(); // Error!
+ ^
+15:29 note: previous borrow of `s` occurs here; the immutable borrow prevents
+ subsequent moves or mutable borrows of `s` until the borrow ends
+ let word = first_word(&s);
+ ^
+18:2 note: previous borrow ends here
+fn main() {
+
+}
+^
+```
+
+Recall from the borrowing rules that if we have an immutable reference to
+something, we cannot also take a mutable reference. Because `clear` needs to
+truncate the `String`, it tries to take a mutable reference, which fails. Not
+only has Rust made our API easier to use, but it has also eliminated an entire
+class of errors at compile time!
+
+#### String Literals Are Slices
+
+Recall that we talked about string literals being stored inside the binary. Now
+that we know about slices, we can properly understand string literals:
+
+```rust
+let s = "Hello, world!";
+```
+
+The type of `s` here is `&str`: it’s a slice pointing to that specific point of
+the binary. This is also why string literals are immutable; `&str` is an
+immutable reference.
+
+#### String Slices as Parameters
+
+Knowing that you can take slices of literals and `String`s leads us to one more
+improvement on `first_word`, and that’s its signature:
+
+```rust,ignore
+fn first_word(s: &String) -> &str {
+```
+
+A more experienced Rustacean would write the following line instead because it
+allows us to use the same function on both `String`s and `&str`s:
+
+```rust,ignore
+fn first_word(s: &str) -> &str {
+```
+
+If we have a string slice, we can pass that directly. If we have a `String`, we
+can pass a slice of the entire `String`. Defining a function to take a string
+slice instead of a reference to a String makes our API more general and useful
+without losing any functionality:
+
+Filename: src/main.rs
+
+```rust
+# fn first_word(s: &str) -> &str {
+# let bytes = s.as_bytes();
+#
+# for (i, &item) in bytes.iter().enumerate() {
+# if item == b' ' {
+# return &s[0..i];
+# }
+# }
+#
+# &s[..]
+# }
+fn main() {
+ let my_string = String::from("hello world");
+
+ // first_word works on slices of `String`s
+ let word = first_word(&my_string[..]);
+
+ let my_string_literal = "hello world";
+
+ // first_word works on slices of string literals
+ let word = first_word(&my_string_literal[..]);
+
+ // since string literals *are* string slices already,
+ // this works too, without the slice syntax!
+ let word = first_word(my_string_literal);
+}
+```
+
+### Other Slices
+
+String slices, as you might imagine, are specific to strings. But there’s a
+more general slice type, too. Consider this array:
+
+```rust
+let a = [1, 2, 3, 4, 5];
+```
+
+Just like we might want to refer to a part of a string, we might want to refer
+to part of an array and would do so like this:
+
+```rust
+let a = [1, 2, 3, 4, 5];
+
+let slice = &a[1..3];
+```
+
+This slice has the type `&[i32]`. It works the same way as string slices do, by
+storing a reference to the first element and a length. You’ll use this kind of
+slice for all sorts of other collections. We’ll discuss these collections in
+detail when we talk about vectors in Chapter 8.
+
+## Summary
+
+The concepts of ownership, borrowing, and slices are what ensure memory safety
+in Rust programs at compile time. The Rust language gives you control over your
+memory usage like other systems programming languages, but having the owner of
+data automatically clean up that data when the owner goes out of scope means
+you don’t have to write and debug extra code to get this control.
+
+Ownership affects how lots of other parts of Rust work, so we’ll talk about
+these concepts further throughout the rest of the book. Let’s move on to the
+next chapter and look at grouping pieces of data together in a `struct`.
diff --git a/trpl-2nd-edition/ch05-00-structs.md b/trpl-2nd-edition/ch05-00-structs.md
new file mode 100644
index 0000000..69d55df
--- /dev/null
+++ b/trpl-2nd-edition/ch05-00-structs.md
@@ -0,0 +1,393 @@
+# Structs
+
+A `struct`, short for *structure*, is a custom data type that lets us name and
+package together multiple related values that make up a meaningful group. If
+you come from an object-oriented language, a `struct` is like an object’s data
+attributes. In the next section of this chapter, we’ll talk about how to define
+methods on our structs; methods are how you specify the *behavior* that goes
+along with a struct’s data. The `struct` and `enum` (that we will talk about in
+Chapter 6) concepts are the building blocks for creating new types in your
+program’s domain in order to take full advantage of Rust’s compile-time type
+checking.
+
+One way of thinking about structs is that they are similar to tuples, which we
+talked about in Chapter 3. Like tuples, the pieces of a struct can be different
+types. Unlike tuples, we name each piece of data so that it’s clearer what the
+values mean. Structs are more flexible as a result of these names: we don’t
+have to rely on the order of the data to specify or access the values of an
+instance.
+
+To define a struct, we enter the keyword `struct` and give the whole struct a
+name. A struct’s name should describe what the significance is of these pieces
+of data being grouped together. Then, inside curly braces, we define the names
+of the pieces of data, which we call *fields*, and specify each field’s type.
+For example, Listing 5-1 shows a struct to store information about a user
+account:
+
+```rust
+struct User {
+ username: String,
+ email: String,
+ sign_in_count: u64,
+ active: bool,
+}
+```
+
+Listing 5-1: A `User` struct definition
+
+To use a struct once we've defined it, we create an *instance* of that struct
+by specifying concrete values for each of the fields. Creating an instance is
+done by stating the name of the struct, then curly braces with `key: value`
+pairs inside it where the keys are the names of the fields and the values are
+the data we want to store in those fields. The fields don’t have to be
+specified in the same order in which the struct declared them. In other words,
+the struct definition is like a general template for the type, and instances
+fill in that template with particular data to create values of the type. For
+example, we can declare a particular user like this:
+
+```rust
+# struct User {
+# username: String,
+# email: String,
+# sign_in_count: u64,
+# active: bool,
+# }
+#
+let user1 = User {
+ email: String::from("someone@example.com"),
+ username: String::from("someusername123"),
+ active: true,
+ sign_in_count: 1,
+};
+```
+
+To get a particular value out of a struct, we can use dot notation. If we
+wanted just this user’s email address, we can say `user1.email`.
+
+## Ownership of Struct Data
+
+In the `User` struct definition in Listing 5-1, we used the owned `String` type
+rather than the `&str` string slice type. This is a deliberate choice because
+we want instances of this struct to own all of its data, and for that data to
+be valid for as long as the entire struct is valid.
+
+It is possible for structs to store references to data owned by something else,
+but to do so requires the use of *lifetimes*, a feature of Rust that we'll
+discuss in Chapter 10. Lifetimes ensure that the data a struct references is
+valid for as long as the struct is. If you try to store a reference in a struct
+without specifying lifetimes, like this:
+
+Filename: src/main.rs
+
+```rust,ignore
+struct User {
+ username: &str,
+ email: &str,
+ sign_in_count: u64,
+ active: bool,
+}
+
+fn main() {
+ let user1 = User {
+ email: "someone@example.com",
+ username: "someusername123",
+ active: true,
+ sign_in_count: 1,
+ };
+}
+```
+
+The compiler will complain that it needs lifetime specifiers:
+
+```text
+error[E0106]: missing lifetime specifier
+ -->
+ |
+2 | username: &str,
+ | ^ expected lifetime parameter
+
+error[E0106]: missing lifetime specifier
+ -->
+ |
+3 | email: &str,
+ | ^ expected lifetime parameter
+```
+
+We will talk about how to fix these errors in order to store references in
+structs in Chapter 10, but for now, fix errors like these by switching to owned
+types like `String` instead of references like `&str`.
+
+## An Example Program
+
+To understand when we might want to use structs, let’s write a program that
+calculates the area of a rectangle. We’ll start off with single variables, then
+refactor our program until we’re using structs instead.
+
+Let’s make a new binary project with Cargo called *rectangles* that will take
+the length and width of a rectangle specified in pixels and will calculate the
+area of the rectangle. Listing 5-2 has a short program with one way of doing
+just that in our project’s *src/main.rs*:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let length1 = 50;
+ let width1 = 30;
+
+ println!(
+ "The area of the rectangle is {} square pixels.",
+ area(length1, width1)
+ );
+}
+
+fn area(length: u32, width: u32) -> u32 {
+ length * width
+}
+```
+
+Listing 5-2: Calculating the area of a rectangle
+specified by its length and width in separate variables
+
+Let’s try running this program with `cargo run`:
+
+```text
+The area of the rectangle is 1500 square pixels.
+```
+
+### Refactoring with Tuples
+
+Our little program works okay; it figures out the area of the rectangle by
+calling the `area` function with each dimension. But we can do better. The
+length and the width are related to each other since together they describe one
+rectangle.
+
+The issue with this method is evident in the signature of `area`:
+
+```rust,ignore
+fn area(length: u32, width: u32) -> u32 {
+```
+
+The `area` function is supposed to calculate the area of one rectangle, but our
+function has two parameters. The parameters are related, but that’s not
+expressed anywhere in our program itself. It would be more readable and more
+manageable to group length and width together.
+
+We’ve already discussed one way we might do that in Chapter 3: tuples. Listing
+5-3 has a version of our program which uses tuples:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let rect1 = (50, 30);
+
+ println!(
+ "The area of the rectangle is {} square pixels.",
+ area(rect1)
+ );
+}
+
+fn area(dimensions: (u32, u32)) -> u32 {
+ dimensions.0 * dimensions.1
+}
+```
+
+Listing 5-3: Specifying the length and width of the
+rectangle with a tuple
+
+
+
+In one way, this is a little better. Tuples let us add a bit of structure, and
+we’re now passing just one argument when we call `area`. But in another way
+this method is less clear: tuples don’t give names to their elements, so our
+calculation has gotten more confusing because we have to index into the parts
+of the tuple:
+
+
+
+```rust,ignore
+dimensions.0 * dimensions.1
+```
+
+It doesn’t matter if we mix up length and width for the area calculation, but
+if we were to draw the rectangle on the screen it would matter! We would have
+to remember that `length` was the tuple index `0` and `width` was the tuple
+index `1`. If someone else was to work on this code, they would have to figure
+this out and remember it as well. It would be easy to forget or mix these
+values up and cause errors, since we haven’t conveyed the meaning of our data
+in our code.
+
+### Refactoring with Structs: Adding More Meaning
+
+Here is where we bring in structs. We can transform our tuple into a data type
+with a name for the whole as well as names for the parts, as shown in Listing
+5-4:
+
+Filename: src/main.rs
+
+```rust
+struct Rectangle {
+ length: u32,
+ width: u32,
+}
+
+fn main() {
+ let rect1 = Rectangle { length: 50, width: 30 };
+
+ println!(
+ "The area of the rectangle is {} square pixels.",
+ area(&rect1)
+ );
+}
+
+fn area(rectangle: &Rectangle) -> u32 {
+ rectangle.length * rectangle.width
+}
+```
+
+Listing 5-4: Defining a `Rectangle` struct
+
+
+
+Here we’ve defined a struct and given it the name `Rectangle`. Inside the `{}`
+we defined the fields to be `length` and `width`, both of which have type
+`u32`. Then in `main`, we create a particular instance of a `Rectangle` that
+has a length of 50 and a width of 30.
+
+Our `area` function is now defined with one parameter that we’ve named
+`rectangle` whose type is an immutable borrow of a struct `Rectangle` instance.
+As we covered in Chapter 4, we want to borrow the struct rather than take
+ownership of it so that `main` keeps its ownership and can continue using
+`rect1`, so that’s why we have the `&` in the function signature and at the
+call site.
+
+The `area` function accesses the `length` and `width` fields of the
+`Rectangle`. Our function signature for `area` now says exactly what we mean:
+calculate the area of a `Rectangle`, using its `length` and `width` fields.
+This conveys that the length and width are related to each other, and gives
+descriptive names to the values rather than using the tuple index values of `0`
+and `1`. This is a win for clarity.
+
+### Adding Useful Functionality with Derived Traits
+
+It’d be nice to be able to print out an instance of our `Rectangle` while we’re
+debugging our program and see the values for all its fields. Listing 5-5 tries
+using the `println!` macro as we have been:
+
+Filename: src/main.rs
+
+```rust,ignore
+struct Rectangle {
+ length: u32,
+ width: u32,
+}
+
+fn main() {
+ let rect1 = Rectangle { length: 50, width: 30 };
+
+ println!("rect1 is {}", rect1);
+}
+```
+
+Listing 5-5: Attempting to print a `Rectangle`
+instance
+
+If we run this, we get an error with this core message:
+
+```text
+error[E0277]: the trait bound `Rectangle: std::fmt::Display` is not satisfied
+```
+
+The `println!` macro can do many kinds of formatting, and by default, `{}`
+tells `println!` to use formatting known as `Display`: output intended for
+direct end-user consumption. The primitive types we’ve seen so far implement
+`Display` by default, as there’s only one way you’d want to show a `1` or any
+other primitive type to a user. But with structs, the way `println!` should
+format the output is less clear as there are more display possibilities: Do you
+want commas or not? Do you want to print the struct `{}`s? Should all the
+fields be shown? Because of this ambiguity, Rust doesn’t try to guess what we
+want and structs do not have a provided implementation of `Display`.
+
+If we keep reading the errors, though, we’ll find this helpful note:
+
+```text
+note: `Rectangle` cannot be formatted with the default formatter; try using
+`:?` instead if you are using a format string
+```
+
+Let’s try it! The `println!` will now look like
+`println!("rect1 is {:?}", rect1);`. Putting the specifier `:?` inside
+the `{}` tells `println!` we want to use an output format called `Debug`.
+`Debug` is a trait that enables us to print out our struct in a way that is
+useful for developers so that we can see its value while we are debugging our
+code.
+
+Let’s try running with this change and… drat. We still get an error:
+
+```text
+error: the trait bound `Rectangle: std::fmt::Debug` is not satisfied
+```
+
+Again, though, the compiler has given us a helpful note!
+
+```text
+note: `Rectangle` cannot be formatted using `:?`; if it is defined in your
+crate, add `#[derive(Debug)]` or manually implement it
+```
+
+Rust *does* include functionality to print out debugging information, but we
+have to explicitly opt-in to having that functionality be available for our
+struct. To do that, we add the annotation `#[derive(Debug)]` just before our
+struct definition, as shown in Listing 5-6:
+
+```rust
+#[derive(Debug)]
+struct Rectangle {
+ length: u32,
+ width: u32,
+}
+
+fn main() {
+ let rect1 = Rectangle { length: 50, width: 30 };
+
+ println!("rect1 is {:?}", rect1);
+}
+```
+
+Listing 5-6: Adding the annotation to derive the `Debug`
+trait and printing the `Rectangle` instance using debug formatting
+
+At this point, if we run this program, we won’t get any errors and we’ll see
+the following output:
+
+```text
+rect1 is Rectangle { length: 50, width: 30 }
+```
+
+Nice! It’s not the prettiest output, but it shows the values of all the fields
+for this instance, which would definitely help during debugging. If we want
+output that is a bit prettier and easier to read, which can be helpful with
+larger structs, we can use `{:#?}` in place of `{:?}` in the `println!` string.
+If we use the pretty debug style in this example, the output will look like:
+
+```text
+rect1 is Rectangle {
+ length: 50,
+ width: 30
+}
+```
+
+There are a number of traits Rust has provided for us to use with the `derive`
+annotation that can add useful behavior to our custom types. Those traits and
+their behaviors are listed in Appendix C. We’ll be covering how to implement
+these traits with custom behavior, as well as creating your own traits, in
+Chapter 10.
+
+Our `area` function is pretty specific—it only computes the area of rectangles.
+It would be nice to tie this behavior together more closely with our
+`Rectangle` struct, since it’s behavior that our `Rectangle` type has
+specifically. Let’s now look at how we can continue to refactor this code by
+turning the `area` function into an `area` *method* defined on our `Rectangle`
+type.
diff --git a/trpl-2nd-edition/ch05-01-method-syntax.md b/trpl-2nd-edition/ch05-01-method-syntax.md
new file mode 100644
index 0000000..c5819f5
--- /dev/null
+++ b/trpl-2nd-edition/ch05-01-method-syntax.md
@@ -0,0 +1,253 @@
+## Method Syntax
+
+*Methods* are similar to functions: they’re declared with the `fn` keyword and
+their name, they can have parameters and return values, and they contain some
+code that gets run when they’re called from somewhere else. Methods are
+different from functions, however, because they’re defined within the context
+of a struct (or an enum or a trait object, which we will cover in Chapters 6
+and 17, respectively), and their first parameter is always `self`, which
+represents the instance of the struct that the method is being called on.
+
+### Defining Methods
+
+Let’s change our `area` function that has a `Rectangle` instance as a parameter
+and instead make an `area` method defined on the `Rectangle` struct, as shown
+in Listing 5-7:
+
+Filename: src/main.rs
+
+```rust
+#[derive(Debug)]
+struct Rectangle {
+ length: u32,
+ width: u32,
+}
+
+impl Rectangle {
+ fn area(&self) -> u32 {
+ self.length * self.width
+ }
+}
+
+fn main() {
+ let rect1 = Rectangle { length: 50, width: 30 };
+
+ println!(
+ "The area of the rectangle is {} square pixels.",
+ rect1.area()
+ );
+}
+```
+
+Listing 5-7: Defining an `area` method on the `Rectangle`
+struct
+
+
+
+In order to make the function be defined within the context of `Rectangle`, we
+start an `impl` block (`impl` is short for *implementation*). Then we move the
+function within the `impl` curly braces, and change the first (and in this
+case, only) parameter to be `self` in the signature and everywhere within the
+body. Then in `main` where we called the `area` function and passed `rect1` as
+an argument, we can instead use *method syntax* to call the `area` method on
+our `Rectangle` instance. Method syntax is taking an instance and adding a dot
+followed by the method name, parentheses, and any arguments.
+
+In the signature for `area`, we get to use `&self` instead of `rectangle:
+&Rectangle` because Rust knows the type of `self` is `Rectangle` due to this
+method being inside the `impl Rectangle` context. Note we still need to have
+the `&` before `self`, just like we had `&Rectangle`. Methods can choose to
+take ownership of `self`, borrow `self` immutably as we’ve done here, or borrow
+`self` mutably, just like any other parameter.
+
+We’ve chosen `&self` here for the same reason we used `&Rectangle` in the
+function version: we don’t want to take ownership, and we just want to be able
+to read the data in the struct, not write to it. If we wanted to be able to
+change the instance that we’ve called the method on as part of what the method
+does, we’d put `&mut self` as the first parameter instead. Having a method that
+takes ownership of the instance by having just `self` as the first parameter is
+rarer; this is usually used when the method transforms `self` into something
+else and we want to prevent the caller from using the original instance after
+the transformation.
+
+The main benefit of using methods over functions, in addition to getting to use
+method syntax and not having to repeat the type of `self` in every method’s
+signature, is for organization. We’ve put all the things we can do with an
+instance of a type together in one `impl` block, rather than make future users
+of our code search for capabilities of `Rectangle` all over the place.
+
+
+
+> ### Where’s the `->` operator?
+>
+> In languages like C++, there are two different operators for calling methods:
+> `.` if you’re calling a method on the object directly, and `->` if you’re
+> calling the method on a pointer to the object and thus need to dereference the
+> pointer first. In other words, if `object` is a pointer, `object->something()`
+> is like `(*object).something()`.
+>
+> Rust doesn’t have an equivalent to the `->` operator; instead, Rust has a
+> feature called *automatic referencing and dereferencing*. Calling methods is
+> one of the few places in Rust that has behavior like this.
+>
+> Here’s how it works: when you call a method with `object.something()`, Rust
+> will automatically add in `&`, `&mut`, or `*` so that `object` matches the
+> signature of the method. In other words, these are the same:
+>
+> ```rust
+> # #[derive(Debug,Copy,Clone)]
+> # struct Point {
+> # x: f64,
+> # y: f64,
+> # }
+> #
+> # impl Point {
+> # fn distance(&self, other: &Point) -> f64 {
+> # let x_squared = f64::powi(other.x - self.x, 2);
+> # let y_squared = f64::powi(other.y - self.y, 2);
+> #
+> # f64::sqrt(x_squared + y_squared)
+> # }
+> # }
+> # let p1 = Point { x: 0.0, y: 0.0 };
+> # let p2 = Point { x: 5.0, y: 6.5 };
+> p1.distance(&p2);
+> (&p1).distance(&p2);
+> ```
+>
+> The first one looks much, much cleaner. This automatic referencing behavior
+> works because methods have a clear receiver — the type of `self`. Given the
+> receiver and name of a method, Rust can figure out definitively whether the
+> method is just reading (so needs `&self`), mutating (so `&mut self`), or
+> consuming (so `self`). The fact that Rust makes borrowing implicit for method
+> receivers is a big part of making ownership ergonomic in practice.
+
+
+
+### Methods with More Parameters
+
+Let’s practice some more with methods by implementing a second method on our
+`Rectangle` struct. This time, we’d like for an instance of `Rectangle` to take
+another instance of `Rectangle` and return `true` if the second rectangle could
+fit completely within `self` and `false` if it would not. That is, if we run
+the code in Listing 5-8, once we've defined the `can_hold` method:
+
+Filename: src/main.rs
+
+```rust,ignore
+fn main() {
+ let rect1 = Rectangle { length: 50, width: 30 };
+ let rect2 = Rectangle { length: 40, width: 10 };
+ let rect3 = Rectangle { length: 45, width: 60 };
+
+ println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2));
+ println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3));
+}
+```
+
+Listing 5-8: Demonstration of using the as-yet-unwritten
+`can_hold` method
+
+We want to see this output, since both of `rect2`’s dimensions are smaller than
+`rect1`’s, but `rect3` is wider than `rect1`:
+
+```text
+Can rect1 hold rect2? true
+Can rect1 hold rect3? false
+```
+
+We know we want to define a method, so it will be within the `impl Rectangle`
+block. The method name will be `can_hold`, and it will take an immutable borrow
+of another `Rectangle` as a parameter. We can tell what the type of the
+parameter will be by looking at a call site: `rect1.can_hold(&rect2)` passes in
+`&rect2`, which is an immutable borrow to `rect2`, an instance of `Rectangle`.
+This makes sense, since we only need to read `rect2` (rather than write, which
+would mean we’d need a mutable borrow) and we want `main` to keep ownership of
+`rect2` so that we could use it again after calling this method. The return
+value of `can_hold` will be a boolean, and the implementation will check to see
+if `self`’s length and width are both greater than the length and width of the
+other `Rectangle`, respectively. Let’s add this new method to the `impl` block
+from Listing 5-7, shown in Listing 5-9:
+
+
+Filename: src/main.rs
+
+```rust
+# #[derive(Debug)]
+# struct Rectangle {
+# length: u32,
+# width: u32,
+# }
+#
+impl Rectangle {
+ fn area(&self) -> u32 {
+ self.length * self.width
+ }
+
+ fn can_hold(&self, other: &Rectangle) -> bool {
+ self.length > other.length && self.width > other.width
+ }
+}
+```
+
+
+
+Listing 5-9: Implementing the `can_hold` method on `Rectangle` that takes
+another `Rectangle` instance as an argument
+
+
+
+
+
+
+If we run this with the `main` from Listing 5-8, we will get our desired output!
+Methods can have multiple parameters that we add to the signature after the
+`self` parameter, and those parameters work just like parameters in functions
+do.
+
+### Associated Functions
+
+One more useful feature of `impl` blocks: we’re allowed to define functions
+within `impl` blocks that *don’t* take `self` as a parameter. These are called
+*associated functions*, since they’re associated with the struct. They’re still
+functions though, not methods, since they don’t have an instance of the struct
+to work with. You’ve already used an associated function: `String::from`.
+
+Associated functions are often used for constructors that will return a new
+instance of the struct. For example, we could provide an associated function
+that would have one dimension parameter and use that as both length and width,
+thus making it easier to create a square `Rectangle` rather than having to
+specify the same value twice:
+
+Filename: src/main.rs
+
+```rust
+# #[derive(Debug)]
+# struct Rectangle {
+# length: u32,
+# width: u32,
+# }
+#
+impl Rectangle {
+ fn square(size: u32) -> Rectangle {
+ Rectangle { length: size, width: size }
+ }
+}
+```
+
+To call this associated function, we use the `::` syntax with the struct name:
+`let sq = Rectangle::square(3);`, for example. This function is namespaced by
+the struct: the `::` syntax is used for both associated functions and
+namespaces created by modules, which we’ll learn about in Chapter 7.
+
+## Summary
+
+Structs let us create custom types that are meaningful for our domain. By using
+structs, we can keep associated pieces of data connected to each other and name
+each piece to make our code clear. Methods let us specify the behavior that
+instances of our structs have, and associated functions let us namespace
+functionality that is particular to our struct without having an instance
+available.
+
+Structs aren’t the only way we can create custom types, though; let’s turn to
+the `enum` feature of Rust and add another tool to our toolbox.
diff --git a/trpl-2nd-edition/ch06-00-enums.md b/trpl-2nd-edition/ch06-00-enums.md
new file mode 100644
index 0000000..f88f4ed
--- /dev/null
+++ b/trpl-2nd-edition/ch06-00-enums.md
@@ -0,0 +1,15 @@
+# Enums and Pattern Matching
+
+In this chapter we’ll look at *enumerations*, also referred to as *enums*.
+Enums allow you to define a type by enumerating its possible values. First,
+we’ll define and use an enum to show how an enum can encode meaning along with
+data. Next, we’ll explore a particularly useful enum, called `Option`, which
+expresses that a value can be either something or nothing. Then we’ll look at
+how pattern matching in the `match` expression makes it easy to run different
+code for different values of an enum. Finally, we’ll cover how the `if let`
+construct is another convenient and concise idiom available to you to handle
+enums in your code.
+
+Enums are a feature in many languages, but their capabilities differ in each
+language. Rust’s enums are most similar to *algebraic data types* in functional
+languages like F#, OCaml, and Haskell.
diff --git a/trpl-2nd-edition/ch06-01-defining-an-enum.md b/trpl-2nd-edition/ch06-01-defining-an-enum.md
new file mode 100644
index 0000000..13f05b0
--- /dev/null
+++ b/trpl-2nd-edition/ch06-01-defining-an-enum.md
@@ -0,0 +1,400 @@
+## Defining an Enum
+
+Let’s look at a situation we might want to express in code and see why enums
+are useful and more appropriate than structs in this case. Say we need to work
+with IP addresses. Currently, two major standards are used for IP addresses:
+version four and version six. These are the only possibilities for an IP
+address that our program will come across: we can *enumerate* all possible
+values, which is where enumeration gets its name.
+
+Any IP address can be either a version four or a version six address but not
+both at the same time. That property of IP addresses makes the enum data
+structure appropriate for this case, because enum values can only be one of the
+variants. Both version four and version six addresses are still fundamentally
+IP addresses, so they should be treated as the same type when the code is
+handling situations that apply to any kind of IP address.
+
+We can express this concept in code by defining an `IpAddrKind` enumeration and
+listing the possible kinds an IP address can be, `V4` and `V6`. These are known
+as the *variants* of the enum:
+
+```rust
+enum IpAddrKind {
+ V4,
+ V6,
+}
+```
+
+`IpAddrKind` is now a custom data type that we can use elsewhere in our code.
+
+### Enum Values
+
+We can create instances of each of the two variants of `IpAddrKind` like this:
+
+```rust
+# enum IpAddrKind {
+# V4,
+# V6,
+# }
+#
+let four = IpAddrKind::V4;
+let six = IpAddrKind::V6;
+```
+
+Note that the variants of the enum are namespaced under its identifier, and we
+use a double colon to separate the two. The reason this is useful is that now
+both values `IpAddrKind::V4` and `IpAddrKind::V6` are of the same type:
+`IpAddrKind`. We can then, for instance, define a function that takes any
+`IpAddrKind`:
+
+```rust
+# enum IpAddrKind {
+# V4,
+# V6,
+# }
+#
+fn route(ip_type: IpAddrKind) { }
+```
+
+And we can call this function with either variant:
+
+```rust
+# enum IpAddrKind {
+# V4,
+# V6,
+# }
+#
+# fn route(ip_type: IpAddrKind) { }
+#
+route(IpAddrKind::V4);
+route(IpAddrKind::V6);
+```
+
+Using enums has even more advantages. Thinking more about our IP address type,
+at the moment we don’t have a way to store the actual IP address *data*; we
+only know what *kind* it is. Given that you just learned about structs in
+Chapter 5, you might tackle this problem as shown in Listing 6-1:
+
+```rust
+enum IpAddrKind {
+ V4,
+ V6,
+}
+
+struct IpAddr {
+ kind: IpAddrKind,
+ address: String,
+}
+
+let home = IpAddr {
+ kind: IpAddrKind::V4,
+ address: String::from("127.0.0.1"),
+};
+
+let loopback = IpAddr {
+ kind: IpAddrKind::V6,
+ address: String::from("::1"),
+};
+```
+
+Listing 6-1: Storing the data and `IpAddrKind` variant of
+an IP address using a `struct`
+
+Here, we’ve defined a struct `IpAddr` that has two fields: a `kind` field that
+is of type `IpAddrKind` (the enum we defined previously) and an `address` field
+of type `String`. We have two instances of this struct. The first, `home`, has
+the value `IpAddrKind::V4` as its `kind` with associated address data of
+`127.0.0.1`. The second instance, `loopback`, has the other variant of
+`IpAddrKind` as its `kind` value, `V6`, and has address `::1` associated with
+it. We’ve used a struct to bundle the `kind` and `address` values together, so
+now the variant is associated with the value.
+
+We can represent the same concept in a more concise way using just an enum
+rather than an enum as part of a struct by putting data directly into each enum
+variant. This new definition of the `IpAddr` enum says that both `V4` and `V6`
+variants will have associated `String` values:
+
+```rust
+enum IpAddr {
+ V4(String),
+ V6(String),
+}
+
+let home = IpAddr::V4(String::from("127.0.0.1"));
+
+let loopback = IpAddr::V6(String::from("::1"));
+```
+
+We attach data to each variant of the enum directly, so there is no need for an
+extra struct.
+
+There’s another advantage to using an enum rather than a struct: each variant
+can have different types and amounts of associated data. Version four type IP
+addresses will always have four numeric components that will have values
+between 0 and 255. If we wanted to store `V4` addresses as four `u8` values but
+still express `V6` addresses as one `String` value, we wouldn’t be able to with
+a struct. Enums handle this case with ease:
+
+```rust
+enum IpAddr {
+ V4(u8, u8, u8, u8),
+ V6(String),
+}
+
+let home = IpAddr::V4(127, 0, 0, 1);
+
+let loopback = IpAddr::V6(String::from("::1"));
+```
+
+We’ve shown several different possibilities that we could define in our code
+for storing IP addresses of the two different varieties using an enum. However,
+as it turns out, wanting to store IP addresses and encode which kind they are
+is so common that [the standard library has a definition we can
+use!][IpAddr] Let’s look at how the standard library defines
+`IpAddr`: it has the exact enum and variants that we’ve defined and used, but
+it embeds the address data inside the variants in the form of two different
+structs, which are defined differently for each variant:
+
+[IpAddr]: ../../std/net/enum.IpAddr.html
+
+```rust
+struct Ipv4Addr {
+ // details elided
+}
+
+struct Ipv6Addr {
+ // details elided
+}
+
+enum IpAddr {
+ V4(Ipv4Addr),
+ V6(Ipv6Addr),
+}
+```
+
+This code illustrates that you can put any kind of data inside an enum variant:
+strings, numeric types, or structs, for example. You can even include another
+enum! Also, standard library types are often not much more complicated than
+what you might come up with.
+
+Note that even though the standard library contains a definition for `IpAddr`,
+we can still create and use our own definition without conflict because we
+haven’t brought the standard library’s definition into our scope. We’ll talk
+more about importing types in Chapter 7.
+
+Let’s look at another example of an enum in Listing 6-2: this one has a wide
+variety of types embedded in its variants:
+
+```rust
+enum Message {
+ Quit,
+ Move { x: i32, y: i32 },
+ Write(String),
+ ChangeColor(i32, i32, i32),
+}
+```
+
+Listing 6-2: A `Message` enum whose variants each store
+different amounts and types of values
+
+This enum has four variants with different types:
+
+* `Quit` has no data associated with it at all.
+* `Move` includes an anonymous struct inside it.
+* `Write` includes a single `String`.
+* `ChangeColor` includes three `i32`s.
+
+Defining an enum with variants like the ones in Listing 6-2 is similar to
+defining different kinds of struct definitions except the enum doesn’t use the
+`struct` keyword and all the variants are grouped together under the `Message`
+type. The following structs could hold the same data that the preceding enum
+variants hold:
+
+```rust
+struct QuitMessage; // unit struct
+struct MoveMessage {
+ x: i32,
+ y: i32,
+}
+struct WriteMessage(String); // tuple struct
+struct ChangeColorMessage(i32, i32, i32); // tuple struct
+```
+
+But if we used the different structs, which each have their own type, we
+wouldn’t be able to as easily define a function that could take any of these
+kinds of messages as we could with the `Message` enum defined in Listing 6-2,
+which is a single type.
+
+There is one more similarity between enums and structs: just as we’re able to
+define methods on structs using `impl`, we’re also able to define methods on
+enums. Here’s a method named `call` that we could define on our `Message` enum:
+
+```rust
+# enum Message {
+# Quit,
+# Move { x: i32, y: i32 },
+# Write(String),
+# ChangeColor(i32, i32, i32),
+# }
+#
+impl Message {
+ fn call(&self) {
+ // method body would be defined here
+ }
+}
+
+let m = Message::Write(String::from("hello"));
+m.call();
+```
+
+The body of the method would use `self` to get the value that we called the
+method on. In this example, we’ve created a variable `m` that has the value
+`Message::Write("hello")`, and that is what `self` will be in the body of the
+`call` method when `m.call()` runs.
+
+Let’s look at another enum in the standard library that is very common and
+useful: `Option`.
+
+### The `Option` Enum and Its Advantages Over Null Values
+
+In the previous section, we looked at how the `IpAddr` enum let us use Rust’s
+type system to encode more information than just the data into our program.
+This section explores a case study of `Option`, which is another enum defined
+by the standard library. The `Option` type is used in many places because it
+encodes the very common scenario in which a value could be something or it
+could be nothing. Expressing this concept in terms of the type system means the
+compiler can check that you’ve handled all the cases you should be handling,
+which can prevent bugs that are extremely common in other programming languages.
+
+Programming language design is often thought of in terms of which features you
+include, but the features you exclude are important too. Rust doesn’t have the
+null feature that many other languages have. *Null* is a value that means there
+is no value there. In languages with null, variables can always be in one of
+two states: null or not-null.
+
+In “Null References: The Billion Dollar Mistake,” Tony Hoare, the inventor of
+null, has this to say:
+
+> I call it my billion-dollar mistake. At that time, I was designing the first
+> comprehensive type system for references in an object-oriented language. My
+> goal was to ensure that all use of references should be absolutely safe, with
+> checking performed automatically by the compiler. But I couldn't resist the
+> temptation to put in a null reference, simply because it was so easy to
+> implement. This has led to innumerable errors, vulnerabilities, and system
+> crashes, which have probably caused a billion dollars of pain and damage in
+> the last forty years.
+
+The problem with null values is that if you try to actually use a value that’s
+null as if it is a not-null value, you’ll get an error of some kind. Because
+this null or not-null property is pervasive, it’s extremely easy to make this
+kind of error.
+
+However, the concept that null is trying to express is still a useful one: a
+null is a value that is currently invalid or absent for some reason.
+
+The problem isn’t with the actual concept but with the particular
+implementation. As such, Rust does not have nulls, but it does have an enum
+that can encode the concept of a value being present or absent. This enum is
+`Option`, and it is [defined by the standard library][option]
+as follows:
+
+[option]: ../../std/option/enum.Option.html
+
+```rust
+enum Option {
+ Some(T),
+ None,
+}
+```
+
+The `Option` enum is so useful that it’s even included in the prelude; you
+don’t need to import it explicitly. In addition, so are its variants: you can
+use `Some` and `None` directly without prefixing them with `Option::`.
+`Option` is still just a regular enum, and `Some(T)` and `None` are still
+variants of type `Option`.
+
+The `` syntax is a feature of Rust we haven’t talked about yet. It’s a
+generic type parameter, and we’ll cover generics in more detail in Chapter 10.
+For now, all you need to know is that `` means the `Some` variant of the
+`Option` enum can hold one piece of data of any type. Here are some examples of
+using `Option` values to hold number types and string types:
+
+```rust
+let some_number = Some(5);
+let some_string = Some("a string");
+
+let absent_number: Option = None;
+```
+
+If we use `None` rather than `Some`, we need to tell Rust what type of
+`Option` we have, because the compiler can't infer the type that the `Some`
+variant will hold by looking only at a `None` value.
+
+When we have a `Some` value, we know that a value is present, and the value is
+held within the `Some`. When we have a `None` value, in some sense, it means
+the same thing as null: we don’t have a valid value. So why is having
+`Option` any better than having null?
+
+In short, because `Option` and `T` (where `T` can be any type) are different
+types, the compiler won’t let us use an `Option` value as if it was
+definitely a valid value. For example, this code won’t compile because it’s
+trying to compare an `Option` to an `i8`:
+
+```rust,ignore
+let x: i8 = 5;
+let y: Option = Some(5);
+
+let sum = x + y;
+```
+
+If we run this code, we get an error message like this:
+
+```text
+error[E0277]: the trait bound `i8: std::ops::Add>` is
+not satisfied
+ -->
+ |
+7 | let sum = x + y;
+ | ^^^^^
+ |
+```
+
+Intense! In effect, this error message means that Rust doesn’t understand how
+to add an `Option` and an `i8`, because they’re different types. When we
+have a value of a type like `i8` in Rust, the compiler will ensure that we
+always have a valid value. We can proceed confidently without having to check
+for null before using that value. Only when we have an `Option` (or
+whatever type of value we’re working with) do we have to worry about possibly
+not having a value, and the compiler will make sure we handle that case before
+using the value.
+
+In other words, you have to convert an `Option` to a `T` before you can
+perform `T` operations with it. Generally, this helps catch one of the most
+common issues with null: assuming that something isn’t null when it actually
+is.
+
+Not having to worry about missing an assumption of having a not-null value
+helps you to be more confident in your code. In order to have a value that can
+possibly be null, you must explicitly opt in by making the type of that value
+`Option`. Then, when you use that value, you are required to explicitly
+handle the case when the value is null. Everywhere that a value has a type that
+isn’t an `Option`, you *can* safely assume that the value isn’t null. This
+was a deliberate design decision for Rust to limit null’s pervasiveness and
+increase the safety of Rust code.
+
+So, how do you get the `T` value out of a `Some` variant when you have a value
+of type `Option` so you can use that value? The `Option` enum has a large
+number of methods that are useful in a variety of situations; you can check
+them out in [its documentation][docs]. Becoming familiar with
+the methods on `Option` will be extremely useful in your journey with Rust.
+
+[docs]: ../../std/option/enum.Option.html
+
+In general, in order to use an `Option` value, we want to have code that
+will handle each variant. We want some code that will run only when we have a
+`Some(T)` value, and this code is allowed to use the inner `T`. We want some
+other code to run if we have a `None` value, and that code doesn’t have a `T`
+value available. The `match` expression is a control flow construct that does
+just this when used with enums: it will run different code depending on which
+variant of the enum it has, and that code can use the data inside the matching
+value.
diff --git a/trpl-2nd-edition/ch06-02-match.md b/trpl-2nd-edition/ch06-02-match.md
new file mode 100644
index 0000000..427cbde
--- /dev/null
+++ b/trpl-2nd-edition/ch06-02-match.md
@@ -0,0 +1,299 @@
+## The `match` Control Flow Operator
+
+Rust has an extremely powerful control-flow operator called `match` that allows
+us to compare a value against a series of patterns and then execute code based
+on which pattern matches. Patterns can be made up of literal values, variable
+names, wildcards, and many other things; Chapter 18 will cover all the
+different kinds of patterns and what they do. The power of `match` comes from
+the expressiveness of the patterns and the compiler checks that make sure all
+possible cases are handled.
+
+Think of a `match` expression kind of like a coin sorting machine: coins slide
+down a track with variously sized holes along it, and each coin falls through
+the first hole it encounters that it fits into. In the same way, values go
+through each pattern in a `match`, and at the first pattern the value “fits,”
+the value will fall into the associated code block to be used during execution.
+
+Because we just mentioned coins, let’s use them as an example using `match`! We
+can write a function that can take an unknown United States coin and, in a
+similar way as the counting machine, determine which coin it is and return its
+value in cents, as shown here in Listing 6-3:
+
+```rust
+enum Coin {
+ Penny,
+ Nickel,
+ Dime,
+ Quarter,
+}
+
+fn value_in_cents(coin: Coin) -> i32 {
+ match coin {
+ Coin::Penny => 1,
+ Coin::Nickel => 5,
+ Coin::Dime => 10,
+ Coin::Quarter => 25,
+ }
+}
+```
+
+Listing 6-3: An enum and a `match` expression that has
+the variants of the enum as its patterns.
+
+Let’s break down the `match` in the `value_in_cents` function. First, we list
+the `match` keyword followed by an expression, which in this case is the value
+`coin`. This seems very similar to an expression used with `if`, but there’s a
+big difference: with `if`, the expression needs to return a boolean value.
+Here, it can be any type. The type of `coin` in this example is the `Coin` enum
+that we defined in Listing 6-3.
+
+Next are the `match` arms. An arm has two parts: a pattern and some code. The
+first arm here has a pattern that is the value `Coin::Penny` and then the `=>`
+operator that separates the pattern and the code to run. The code in this case
+is just the value `1`. Each arm is separated from the next with a comma.
+
+When the `match` expression executes, it compares the resulting value against
+the pattern of each arm, in order. If a pattern matches the value, the code
+associated with that pattern is executed. If that pattern doesn’t match the
+value, execution continues to the next arm, much like a coin sorting machine.
+We can have as many arms as we need: in Listing 6-3, our `match` has four arms.
+
+The code associated with each arm is an expression, and the resulting value of
+the expression in the matching arm is the value that gets returned for the
+entire `match` expression.
+
+Curly braces typically aren’t used if the match arm code is short, as it is in
+Listing 6-3 where each arm just returns a value. If you want to run multiple
+lines of code in a match arm, you can use curly braces. For example, the
+following code would print out “Lucky penny!” every time the method was called
+with a `Coin::Penny` but would still return the last value of the block, `1`:
+
+```rust
+# enum Coin {
+# Penny,
+# Nickel,
+# Dime,
+# Quarter,
+# }
+#
+fn value_in_cents(coin: Coin) -> i32 {
+ match coin {
+ Coin::Penny => {
+ println!("Lucky penny!");
+ 1
+ },
+ Coin::Nickel => 5,
+ Coin::Dime => 10,
+ Coin::Quarter => 25,
+ }
+}
+```
+
+### Patterns that Bind to Values
+
+Another useful feature of match arms is that they can bind to parts of the
+values that match the pattern. This is how we can extract values out of enum
+variants.
+
+As an example, let’s change one of our enum variants to hold data inside it.
+From 1999 through 2008, the United States printed quarters with different
+designs for each of the 50 states on one side. No other coins got state
+designs, so only quarters have this extra value. We can add this information to
+our `enum` by changing the `Quarter` variant to include a `State` value stored
+inside it, which we've done here in Listing 6-4:
+
+```rust
+#[derive(Debug)] // So we can inspect the state in a minute
+enum UsState {
+ Alabama,
+ Alaska,
+ // ... etc
+}
+
+enum Coin {
+ Penny,
+ Nickel,
+ Dime,
+ Quarter(UsState),
+}
+```
+
+Listing 6-4: A `Coin` enum where the `Quarter` variant
+also holds a `UsState` value
+
+Let’s imagine that a friend of ours is trying to collect all 50 state quarters.
+While we sort our loose change by coin type, we’ll also call out the name of
+the state associated with each quarter so if it’s one our friend doesn’t have,
+they can add it to their collection.
+
+In the match expression for this code, we add a variable called `state` to the
+pattern that matches values of the variant `Coin::Quarter`. When a
+`Coin::Quarter` matches, the `state` variable will bind to the value of that
+quarter’s state. Then we can use `state` in the code for that arm, like so:
+
+```rust
+# #[derive(Debug)]
+# enum UsState {
+# Alabama,
+# Alaska,
+# }
+#
+# enum Coin {
+# Penny,
+# Nickel,
+# Dime,
+# Quarter(UsState),
+# }
+#
+fn value_in_cents(coin: Coin) -> i32 {
+ match coin {
+ Coin::Penny => 1,
+ Coin::Nickel => 5,
+ Coin::Dime => 10,
+ Coin::Quarter(state) => {
+ println!("State quarter from {:?}!", state);
+ 25
+ },
+ }
+}
+```
+
+If we were to call `value_in_cents(Coin::Quarter(UsState::Alaska))`, `coin`
+would be `Coin::Quarter(UsState::Alaska)`. When we compare that value with each
+of the match arms, none of them match until we reach `Coin::Quarter(state)`. At
+that point, the binding for `state` will be the value `UsState::Alaska`. We can
+then use that binding in the `println!` expression, thus getting the inner
+state value out of the `Coin` enum variant for `Quarter`.
+
+### Matching with `Option`
+
+In the previous section we wanted to get the inner `T` value out of the `Some`
+case when using `Option`; we can also handle `Option` using `match` as we
+did with the `Coin` enum! Instead of comparing coins, we’ll compare the
+variants of `Option`, but the way that the `match` expression works remains
+the same.
+
+Let’s say we want to write a function that takes an `Option`, and if
+there’s a value inside, adds one to that value. If there isn’t a value inside,
+the function should return the `None` value and not attempt to perform any
+operations.
+
+This function is very easy to write, thanks to `match`, and will look like
+Listing 6-5:
+
+```rust
+fn plus_one(x: Option) -> Option {
+ match x {
+ None => None,
+ Some(i) => Some(i + 1),
+ }
+}
+
+let five = Some(5);
+let six = plus_one(five);
+let none = plus_one(None);
+```
+
+Listing 6-5: A function that uses a `match` expression on
+an `Option`
+
+#### Matching `Some(T)`
+
+Let’s examine the first execution of `plus_one` in more detail. When we call
+`plus_one(five)`, the variable `x` in the body of `plus_one` will have the
+value `Some(5)`. We then compare that against each match arm.
+
+```rust,ignore
+None => None,
+```
+
+The `Some(5)` value doesn’t match the pattern `None`, so we continue to the
+next arm.
+
+```rust,ignore
+Some(i) => Some(i + 1),
+```
+
+Does `Some(5)` match `Some(i)`? Why yes it does! We have the same variant.
+The `i` binds to the value contained in `Some`, so `i` takes the value `5`. The
+code in the match arm is then executed, so we add one to the value of `i` and
+create a new `Some` value with our total `6` inside.
+
+#### Matching `None`
+
+Now let’s consider the second call of `plus_one` in Listing 6-5 where `x` is
+`None`. We enter the `match` and compare to the first arm.
+
+```rust,ignore
+None => None,
+```
+
+It matches! There’s no value to add to, so the program stops and returns the
+`None` value on the right side of `=>`. Because the first arm matched, no other
+arms are compared.
+
+Combining `match` and enums is useful in many situations. You’ll see this
+pattern a lot in Rust code: `match` against an enum, bind a variable to the
+data inside, and then execute code based on it. It’s a bit tricky at first, but
+once you get used to it, you’ll wish you had it in all languages. It’s
+consistently a user favorite.
+
+### Matches Are Exhaustive
+
+There’s one other aspect of `match` we need to discuss. Consider this version
+of our `plus_one` function:
+
+```rust,ignore
+fn plus_one(x: Option) -> Option {
+ match x {
+ Some(i) => Some(i + 1),
+ }
+}
+```
+
+We didn’t handle the `None` case, so this code will cause a bug. Luckily, it’s
+a bug Rust knows how to catch. If we try to compile this code, we’ll get this
+error:
+
+```text
+error[E0004]: non-exhaustive patterns: `None` not covered
+ -->
+ |
+6 | match x {
+ | ^ pattern `None` not covered
+```
+
+Rust knows that we didn’t cover every possible case and even knows which
+pattern we forgot! Matches in Rust are *exhaustive*: we must exhaust every last
+possibility in order for the code to be valid. Especially in the case of
+`Option`, when Rust prevents us from forgetting to explicitly handle the
+`None` case, it protects us from assuming that we have a value when we might
+have null, thus making the billion dollar mistake discussed earlier.
+
+### The `_` Placeholder
+
+Rust also has a pattern we can use in situations when we don’t want to list all
+possible values. For example, a `u8` can have valid values of 0 through 255. If
+we only care about the values 1, 3, 5, and 7, we don’t want to have to list out
+0, 2, 4, 6, 8, 9 all the way up to 255. Fortunately, we don’t have to: we can
+use the special pattern `_` instead:
+
+```rust
+let some_u8_value = 0u8;
+match some_u8_value {
+ 1 => println!("one"),
+ 3 => println!("three"),
+ 5 => println!("five"),
+ 7 => println!("seven"),
+ _ => (),
+}
+```
+
+The `_` pattern will match any value. By putting it after our other arms, the
+`_` will match all the possible cases that aren’t specified before it. The `()`
+is just the unit value, so nothing will happen in the `_` case. As a result, we
+can say that we want to do nothing for all the possible values that we don’t
+list before the `_` placeholder.
+
+However, the `match` expression can be a bit wordy in a situation in which we
+only care about *one* of the cases. For this situation, Rust provides `if let`.
diff --git a/trpl-2nd-edition/ch06-03-if-let.md b/trpl-2nd-edition/ch06-03-if-let.md
new file mode 100644
index 0000000..b2c9afd
--- /dev/null
+++ b/trpl-2nd-edition/ch06-03-if-let.md
@@ -0,0 +1,118 @@
+## Concise Control Flow with `if let`
+
+The `if let` syntax lets you combine `if` and `let` into a less verbose way to
+handle values that match one pattern and ignore the rest. Consider the program
+in Listing 6-6 that matches on an `Option` value but only wants to execute
+code if the value is three:
+
+```rust
+let some_u8_value = Some(0u8);
+match some_u8_value {
+ Some(3) => println!("three"),
+ _ => (),
+}
+```
+
+Listing 6-6: A `match` that only cares about executing
+code when the value is `Some(3)`
+
+We want to do something with the `Some(3)` match but do nothing with any other
+`Some` value or the `None` value. To satisfy the `match` expression, we
+have to add `_ => ()` after processing just one variant, which is a lot of
+boilerplate code to add.
+
+Instead, we could write this in a shorter way using `if let`. The following
+code behaves the same as the `match` in Listing 6-6:
+
+```rust
+# let some_u8_value = Some(0u8);
+if let Some(3) = some_u8_value {
+ println!("three");
+}
+```
+
+`if let` takes a pattern and an expression separated by an `=`. It works the
+same way as a `match`, where the expression is given to the `match` and the
+pattern is its first arm.
+
+Using `if let` means you have less to type, less indentation, and less
+boilerplate code. However, we’ve lost the exhaustive checking that `match`
+enforces. Choosing between `match` and `if let` depends on what you’re doing in
+your particular situation and if gaining conciseness is an appropriate
+trade-off for losing exhaustive checking.
+
+In other words, you can think of `if let` as syntax sugar for a `match` that
+runs code when the value matches one pattern and then ignores all other values.
+
+We can include an `else` with an `if let`. The block of code that goes with the
+`else` is the same as the block of code that would go with the `_` case in the
+`match` expression that is equivalent to the `if let` and `else`. Recall the
+`Coin` enum definition in Listing 6-4, where the `Quarter` variant also held a
+`UsState` value. If we wanted to count all non-quarter coins we see while also
+announcing the state of the quarters, we could do that with a `match`
+expression like this:
+
+```rust
+# #[derive(Debug)]
+# enum UsState {
+# Alabama,
+# Alaska,
+# }
+#
+# enum Coin {
+# Penny,
+# Nickel,
+# Dime,
+# Quarter(UsState),
+# }
+# let coin = Coin::Penny;
+let mut count = 0;
+match coin {
+ Coin::Quarter(state) => println!("State quarter from {:?}!", state),
+ _ => count += 1,
+}
+```
+
+Or we could use an `if let` and `else` expression like this:
+
+```rust
+# #[derive(Debug)]
+# enum UsState {
+# Alabama,
+# Alaska,
+# }
+#
+# enum Coin {
+# Penny,
+# Nickel,
+# Dime,
+# Quarter(UsState),
+# }
+# let coin = Coin::Penny;
+let mut count = 0;
+if let Coin::Quarter(state) = coin {
+ println!("State quarter from {:?}!", state);
+} else {
+ count += 1;
+}
+```
+
+If you have a situation in which your program has logic that is too verbose to
+express using a `match`, remember that `if let` is in your Rust toolbox as well.
+
+## Summary
+
+We’ve now covered how to use enums to create custom types that can be one of a
+set of enumerated values. We’ve shown how the standard library’s `Option`
+type helps you use the type system to prevent errors. When enum values have
+data inside them, you can use `match` or `if let` to extract and use those
+values, depending on how many cases you need to handle.
+
+Your Rust programs can now express concepts in your domain using structs and
+enums. Creating custom types to use in your API ensures type safety: the
+compiler will make certain your functions only get values of the type each
+function expects.
+
+In order to provide a well-organized API to your users that is straightforward
+to use and only exposes exactly what your users will need, let’s now turn to
+Rust’s modules.
diff --git a/trpl-2nd-edition/ch07-00-modules.md b/trpl-2nd-edition/ch07-00-modules.md
new file mode 100644
index 0000000..d2c61a0
--- /dev/null
+++ b/trpl-2nd-edition/ch07-00-modules.md
@@ -0,0 +1,24 @@
+# Modules
+
+When you start writing programs in Rust, your code might live solely in the
+`main` function. As your code grows, you’ll eventually move functionality out
+into other functions, both for re-use and for better organization. By splitting
+your code up into smaller chunks, each chunk is easier to understand on its
+own. But what happens if you find yourself with too many functions? Rust has a
+module system that handles the problem of wanting to re-use code while keeping
+your code organized.
+
+In the same way that you extract lines of code into a function, you can extract
+functions (and other code like structs and enums too) into different modules. A
+*module* is a namespace that contains definitions of functions or types, and
+you can choose whether those definitions are visible outside their module
+(public) or not (private). Here’s an overview of how modules work:
+
+* You declare a new module with the keyword `mod`
+* By default, everything is set as private (including modules). You can use the
+ `pub` keyword to make a module public and therefore visible outside of its
+ namespace.
+* The `use` keyword allows you to bring modules, or the definitions inside
+ modules, into scope so that it’s easier to refer to them.
+
+We’ll take a look at each of these parts and see how they fit into the whole.
diff --git a/trpl-2nd-edition/ch07-01-mod-and-the-filesystem.md b/trpl-2nd-edition/ch07-01-mod-and-the-filesystem.md
new file mode 100644
index 0000000..e2f91cd
--- /dev/null
+++ b/trpl-2nd-edition/ch07-01-mod-and-the-filesystem.md
@@ -0,0 +1,464 @@
+## `mod` and the Filesystem
+
+We’ll start our module example by making a new project with Cargo, but instead
+of creating a binary crate, we’re going to make a library crate: a project that
+other people can pull into their projects as a dependency. We saw this with the
+`rand` crate in Chapter 2.
+
+We’ll create a skeleton of a library that provides some general networking
+functionality; we’re going to concentrate on the organization of the modules
+and functions, but not worry about what code goes in the function bodies. We’ll
+call our library `communicator`. By default, cargo will create a library unless
+another type of project is specified, so if we leave off the `--bin` option
+that we’ve been using so far our project will be a library:
+
+```text
+$ cargo new communicator
+$ cd communicator
+```
+
+Notice that Cargo generated *src/lib.rs* instead of *src/main.rs*. Inside
+*src/lib.rs* we’ll find this:
+
+Filename: src/lib.rs
+
+```rust
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn it_works() {
+ }
+}
+```
+
+Cargo creates an empty test to help us get our library started, rather than the
+“Hello, world!” binary that we get with the `--bin` option. We’ll look at the
+`#[]` and `mod tests` syntax a little later, but for now just make sure to
+leave it in your *src/lib.rs*.
+
+Since we don’t have a *src/main.rs*, there’s nothing for Cargo to execute with
+the `cargo run` command. Therefore, we will be using the `cargo build` command
+to only compile our library crate’s code.
+
+We’re going to look at different options for organizing your library’s code
+which will be suitable in a variety of situations, depending on the intentions
+you have for your code.
+
+### Module Definitions
+
+For our `communicator` networking library, we’re first going to define a module
+named `network` that contains the definition of a function called `connect`.
+Every module definition in Rust starts with the `mod` keyword. Add this code to
+the beginning of the *src/lib.rs* file, above the test code:
+
+Filename: src/lib.rs
+
+```rust
+mod network {
+ fn connect() {
+ }
+}
+```
+
+After the `mod` keyword, we put the name of the module, `network`, then a block
+of code in curly braces. Everything inside this block is inside the namespace
+`network`. In this case, we have a single function, `connect`. If we wanted to
+call this function from a script outside the `network` module, we would need to
+specify the module and use the namespace syntax `::`, like so:
+`network::connect()`, rather than just `connect()`.
+
+We can also have multiple modules, side-by-side, in the same *src/lib.rs* file.
+For example, to have a `client` module too, that also has a function named
+`connect`, we can add it as shown in Listing 7-1:
+
+Filename: src/lib.rs
+
+```rust
+mod network {
+ fn connect() {
+ }
+}
+
+mod client {
+ fn connect() {
+ }
+}
+```
+
+Listing 7-1: The `network` module and the `client` module
+defined side-by-side in *src/lib.rs*
+
+Now we have a `network::connect` function and a `client::connect` function.
+These can have completely different functionality, and the function names do
+not conflict with each other since they’re in different modules.
+
+While in this case we’re building a library, there's nothing special about
+*src/lib.rs*. We could also make use of submodules in *src/main.rs* as well. In
+fact, we can also put modules inside of modules. This can be useful as your
+modules grow to keep related functionality organized together and separate
+functionality apart. The choice of how you organize your code depends on how
+you think about the relationship between the parts of your code. For instance,
+the `client` code and its `connect` function might make more sense to users of
+our library if it was inside the `network` namespace instead, like in Listing
+7-2:
+
+Filename: src/lib.rs
+
+```rust
+mod network {
+ fn connect() {
+ }
+
+ mod client {
+ fn connect() {
+ }
+ }
+}
+```
+
+Listing 7-2: Moving the `client` module inside of the
+`network` module
+
+In your *src/lib.rs* file, replace the existing `mod network` and `mod client`
+definitions with this one that has the `client` module as an inner module of
+`network`. Now we have the functions `network::connect` and
+`network::client::connect`: again, the two functions named `connect` don’t
+conflict with each other since they’re in different namespaces.
+
+In this way, modules form a hierarchy. The contents of *src/lib.rs* are at the
+topmost level, and the submodules are at lower levels. Here’s what the
+organization of our example from Listing 7-1 looks like when thought of this
+way:
+
+```text
+communicator
+ ├── network
+ └── client
+```
+
+And here’s the example from Listing 7-2:
+
+```text
+communicator
+ └── network
+ └── client
+```
+
+You can see that in Listing 7-2, `client` is a child of the `network` module,
+rather than a sibling. More complicated projects can have a lot of modules, and
+they’ll need to be organized logically in order to keep track of them. What
+“logically” means in your project is up to you and depends on how you and users
+of your library think about your project’s domain. Use the techniques we’ve
+shown here to create side-by-side modules and nested modules in whatever
+structure you would like.
+
+### Moving Modules to Other Files
+
+Modules form a hierarchical structure, much like another structure in computing
+that you’re used to: file systems! We can use Rust’s module system along with
+multiple files to split Rust projects up so that not everything lives in
+*src/lib.rs*. For this example, we will start with the code in Listing 7-3:
+
+Filename: src/lib.rs
+
+```rust
+mod client {
+ fn connect() {
+ }
+}
+
+mod network {
+ fn connect() {
+ }
+
+ mod server {
+ fn connect() {
+ }
+ }
+}
+```
+
+Listing 7-3: Three modules, `client`, `network`, and
+`network::server`, all defined in *src/lib.rs*
+
+which has this module hierarchy:
+
+```text
+communicator
+ ├── client
+ └── network
+ └── server
+```
+
+If these modules had many functions, and those functions were getting long, it
+would be difficult to scroll through this file to find the code we wanted to
+work with. Because the functions are nested inside one or more mod blocks, the
+lines of code inside the functions will start getting long as well. These would
+be good reasons to pull each of the `client`, `network`, and `server` modules
+out of *src/lib.rs* and into their own files.
+
+Let’s start by extracting the `client` module into another file. First, replace
+the `client` module code in *src/lib.rs* with the following:
+
+Filename: src/lib.rs
+
+```rust,ignore
+mod client;
+
+mod network {
+ fn connect() {
+ }
+
+ mod server {
+ fn connect() {
+ }
+ }
+}
+```
+
+We’re still *defining* the `client` module here, but by removing the curly
+braces and definitions inside the `client` module and replacing them with a
+semicolon, we’re letting Rust know to look in another location for the code
+defined inside that module.
+
+So now we need to create the external file with that module name. Create a
+*client.rs* file in your *src/* directory, then open it up and enter the
+following, which is the `connect` function in the `client` module that we
+removed in the previous step:
+
+Filename: src/client.rs
+
+```rust
+fn connect() {
+}
+```
+
+Note that we don’t need a `mod` declaration in this file; that’s because we
+already declared the `client` module with `mod` in *src/lib.rs*. This file just
+provides the *contents* of the `client` module. If we put a `mod client` here,
+we’d be giving the `client` module its own submodule named `client`!
+
+Rust only knows to look in *src/lib.rs* by default. If we want to add more
+files to our project, we need to tell Rust in *src/lib.rs* to look in other
+files; this is why `mod client` needs to be defined in *src/lib.rs* and can’t
+be defined in *src/client.rs*.
+
+Now, everything should compile successfully, though you’ll get a few warnings.
+Remember to use `cargo build` instead of `cargo run` since we have a library
+crate rather than a binary crate:
+
+```text
+$ cargo build
+ Compiling communicator v0.1.0 (file:///projects/communicator)
+
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+ --> src/client.rs:1:1
+ |
+1 | fn connect() {
+ | ^
+
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+ --> src/lib.rs:4:5
+ |
+4 | fn connect() {
+ | ^
+
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+ --> src/lib.rs:8:9
+ |
+8 | fn connect() {
+ | ^
+```
+
+These warnings tell us that we have functions that are never used. Don’t worry
+about those warnings for now; we’ll address them later in the chapter. The good
+news is that they’re just warnings; our project was built successfully!
+
+Let’s extract the `network` module into its own file next, using the same
+pattern. In *src/lib.rs*, delete the body of the `network` module and add a
+semicolon to the declaration, like so:
+
+Filename: src/lib.rs
+
+```rust,ignore
+mod client;
+
+mod network;
+```
+
+Then create a new *src/network.rs* file and enter the following:
+
+Filename: src/network.rs
+
+```rust
+fn connect() {
+}
+
+mod server {
+ fn connect() {
+ }
+}
+```
+
+Notice that we still have a `mod` declaration within this module file; this is
+because we still want `server` to be a sub-module of `network`.
+
+Now run `cargo build` again. Success! We have one more module to extract:
+`server`. Because it’s a sub-module—that is, a module within a module—our
+current tactic of extracting a module into a file named after that module won’t
+work. We’re going to try anyway so that we can see the error. First change
+*src/network.rs* to have `mod server;` instead of the `server` module’s
+contents:
+
+Filename: src/network.rs
+
+```rust,ignore
+fn connect() {
+}
+
+mod server;
+```
+
+Then create a *src/server.rs* file and enter the contents of the `server`
+module that we extracted:
+
+Filename: src/server.rs
+
+```rust
+fn connect() {
+}
+```
+
+When we try to `cargo build`, we’ll get the error shown in Listing 7-4:
+
+```text
+$ cargo build
+ Compiling communicator v0.1.0 (file:///projects/communicator)
+error: cannot declare a new module at this location
+ --> src/network.rs:4:5
+ |
+4 | mod server;
+ | ^^^^^^
+ |
+note: maybe move this module `network` to its own directory via `network/mod.rs`
+ --> src/network.rs:4:5
+ |
+4 | mod server;
+ | ^^^^^^
+note: ... or maybe `use` the module `server` instead of possibly redeclaring it
+ --> src/network.rs:4:5
+ |
+4 | mod server;
+ | ^^^^^^
+```
+
+Listing 7-4: Error when trying to extract the `server`
+submodule into *src/server.rs*
+
+The error says we `cannot declare a new module at this location` and is
+pointing to the `mod server;` line in *src/network.rs*. So *src/network.rs* is
+different than *src/lib.rs* somehow; let’s keep reading to understand why.
+
+The note in the middle of Listing 7-4 is actually pretty helpful, as it points
+out something we haven’t yet talked about doing:
+
+```text
+note: maybe move this module `network` to its own directory via `network/mod.rs`
+```
+
+Instead of continuing to follow the same file naming pattern we used
+previously, we can do what the note suggests:
+
+1. Make a new *directory* named *network*, the parent module’s name
+2. Move the *src/network.rs* file into the new *network* directory and rename
+ it so that it is now *src/network/mod.rs*
+3. Move the submodule file *src/server.rs* into the *network* directory
+
+Here are commands to carry out these steps:
+
+```text
+$ mkdir src/network
+$ mv src/network.rs src/network/mod.rs
+$ mv src/server.rs src/network
+```
+
+Now if we try to `cargo build`, compilation will work (we’ll still have
+warnings though). Our module layout still looks like this, which is exactly the
+same as it did when we had all the code in *src/lib.rs* in Listing 7-3:
+
+```text
+communicator
+ ├── client
+ └── network
+ └── server
+```
+
+The corresponding file layout now looks like this:
+
+```text
+├── src
+│ ├── client.rs
+│ ├── lib.rs
+│ └── network
+│ ├── mod.rs
+│ └── server.rs
+```
+
+So when we wanted to extract the `network::server` module, why did we have to
+also change the *src/network.rs* file into the *src/network/mod.rs* file, and
+put the code for `network::server` in the *network* directory in
+*src/network/server.rs*, instead of just being able to extract the
+`network::server` module into *src/server.rs*? The reason is that Rust wouldn’t
+be able to tell that `server` was supposed to be a submodule of `network` if
+the *server.rs* file was in the *src* directory. To make it clearer why Rust
+can’t tell, let’s consider a different example with the following module
+hierarchy, where all the definitions are in *src/lib.rs*:
+
+```text
+communicator
+ ├── client
+ └── network
+ └── client
+```
+
+In this example, we have three modules again, `client`, `network`, and
+`network::client`. If we follow the same steps we originally did above for
+extracting modules into files, for the `client` module we would create
+*src/client.rs*. For the `network` module, we would create *src/network.rs*.
+Then we wouldn’t be able to extract the `network::client` module into a
+*src/client.rs* file, because that already exists for the top-level `client`
+module! If we put the code in both the `client` and `network::client` modules
+in the *src/client.rs* file, Rust would not have any way to know whether the
+code was for `client` or for `network::client`.
+
+Therefore, once we wanted to extract a file for the `network::client` submodule
+of the `network` module, we needed to create a directory for the `network`
+module instead of a *src/network.rs* file. The code that is in the `network`
+module then goes into the *src/network/mod.rs* file, and the submodule
+`network::client` can have its own *src/network/client.rs* file. Now the
+top-level *src/client.rs* is unambiguously the code that belongs to the
+`client` module.
+
+### Rules of Module File Systems
+
+In summary, these are the rules of modules with regards to files:
+
+* If a module named `foo` has no submodules, you should put the declarations
+ for `foo` in a file named *foo.rs*.
+* If a module named `foo` does have submodules, you should put the declarations
+ for `foo` in a file named *foo/mod.rs*.
+
+These rules apply recursively, so that if a module named `foo` has a submodule
+named `bar` and `bar` does not have submodules, you should have the following
+files in your *src* directory:
+
+```text
+├── foo
+│ ├── bar.rs (contains the declarations in `foo::bar`)
+│ └── mod.rs (contains the declarations in `foo`, including `mod bar`)
+```
+
+The modules themselves should be declared in their parent module’s file using
+the `mod` keyword.
+
+Next, we’ll talk about the `pub` keyword, and get rid of those warnings!
diff --git a/trpl-2nd-edition/ch07-02-controlling-visibility-with-pub.md b/trpl-2nd-edition/ch07-02-controlling-visibility-with-pub.md
new file mode 100644
index 0000000..913722f
--- /dev/null
+++ b/trpl-2nd-edition/ch07-02-controlling-visibility-with-pub.md
@@ -0,0 +1,296 @@
+## Controlling Visibility with `pub`
+
+We resolved the error messages shown in Listing 7-4 by moving the `network` and
+`network::server` code into the *src/network/mod.rs* and
+*src/network/server.rs* files, respectively. At that point, `cargo build` was
+able to build our project, but we still get some warning messages about the
+`client::connect`, `network::connect`, and `network::server::connect` functions
+not being used:
+
+```text
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+src/client.rs:1:1
+ |
+1 | fn connect() {
+ | ^
+
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+ --> src/network/mod.rs:1:1
+ |
+1 | fn connect() {
+ | ^
+
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+ --> src/network/server.rs:1:1
+ |
+1 | fn connect() {
+ | ^
+```
+
+So why are we receiving these warnings? After all, we’re building a library
+with functions that are intended to be used by our *users*, and not necessarily
+by us within our own project, so it shouldn’t matter that these `connect`
+functions go unused. The point of creating them is that they will be used by
+another project and not our own.
+
+To understand why this program invokes these warnings, let’s try using the
+`connect` library as if we were another project, calling it externally. To do
+that, we’ll create a binary crate in the same directory as our library crate,
+by making a *src/main.rs* file containing this code:
+
+Filename: src/main.rs
+
+```rust,ignore
+extern crate communicator;
+
+fn main() {
+ communicator::client::connect();
+}
+```
+
+We use the `extern crate` command to bring the `communicator` library crate
+into scope, because our package actually now contains *two* crates. Cargo
+treats *src/main.rs* as the root file of a binary crate, which is separate from
+the existing library crate whose root file is *src/lib.rs*. This pattern is
+quite common for executable projects: most functionality is in a library crate,
+and the binary crate uses that library crate. This way, other programs can also
+use the library crate, and it’s a nice separation of concerns.
+
+From the point of view of a crate outside of the `communicator` library looking
+in, all of the modules we've been creating are within a module that has the
+same name as the crate, `communicator`. We call the top-level module of a crate
+the *root module*.
+
+Also note that even if we're using an external crate within a submodule of our
+project, the `extern crate` should go in our root module (so in *src/main.rs*
+or *src/lib.rs*). Then, in our submodules, we can refer to items from external
+crates as if the items are top-level modules.
+
+Our binary crate right now just calls our library’s `connect` function from the
+`client` module. However, invoking `cargo build` will now give us an error
+after the warnings:
+
+```text
+error: module `client` is private
+ --> src/main.rs:4:5
+ |
+4 | communicator::client::connect();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+```
+
+Ah ha! This tells us that the `client` module is private, and this is the crux
+of the warnings. It’s also the first time we’ve run into the concepts of
+*public* and *private* in the context of Rust. The default state of all code in
+Rust is private: no one else is allowed to use the code. If you don’t use a
+private function within your own program, since your own program is the only
+code allowed to use that function, Rust will warn you that the function has
+gone unused.
+
+Once we specify that a function like `client::connect` is public, not only will
+our call to that function from our binary crate be allowed, the warning that
+the function is unused will go away. Marking something public lets Rust know
+that we intend for the function to be used by code outside of our program. Rust
+considers the theoretical external usage that’s now possible as the function
+“being used.” Thus, when something is marked as public, Rust will not require
+that it’s used in our own program and will stop warning that the item is unused.
+
+### Making a Function Public
+
+To tell Rust to make something public, we add the `pub` keyword to the start of
+the declaration of the item we want to make public. We’ll focus on fixing the
+warning that tells us that `client::connect` has gone unused for now, as well
+as the “module `client` is private” error from our binary crate. Modify
+*src/lib.rs* to make the `client` module public, like so:
+
+Filename: src/lib.rs
+
+```rust,ignore
+pub mod client;
+
+mod network;
+```
+
+The `pub` goes right before `mod`. Let’s try building again:
+
+```text
+
+error: function `connect` is private
+ --> src/main.rs:4:5
+ |
+4 | communicator::client::connect();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+```
+
+Hooray! We have a different error! Yes, different error messages are a cause
+for celebration. The new error says “function `connect` is private”, so let’s
+edit *src/client.rs* to make `client::connect` public too:
+
+Filename: src/client.rs
+
+```rust
+pub fn connect() {
+}
+```
+
+And run `cargo build` again:
+
+```text
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+ --> src/network/mod.rs:1:1
+ |
+1 | fn connect() {
+ | ^
+
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+ --> src/network/server.rs:1:1
+ |
+1 | fn connect() {
+ | ^
+```
+
+It compiled, and the warning about `client::connect` not being used is gone!
+
+Unused code warnings don’t always indicate that something needs to be made
+public: if you *didn’t* want these functions to be part of your public API,
+unused code warnings could be alerting you to code you no longer needed and can
+safely delete. They could also be alerting you to a bug, if you had just
+accidentally removed all places within your library where this function is
+called.
+
+In our case though, we *do* want the other two functions to be part of our
+crate’s public API, so let’s mark them as `pub` as well to try to get rid of
+the remaining warnings. Modify *src/network/mod.rs* to be:
+
+Filename: src/network/mod.rs
+
+```rust,ignore
+pub fn connect() {
+}
+
+mod server;
+```
+
+And compile:
+
+```text
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+ --> src/network/mod.rs:1:1
+ |
+1 | pub fn connect() {
+ | ^
+
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+ --> src/network/server.rs:1:1
+ |
+1 | fn connect() {
+ | ^
+```
+
+Hmmm, we’re still getting an unused function warning even though
+`network::connect` is set to `pub`. This is because the function is public
+within the module, but the `network` module that the function resides in is not
+public. We’re working from the interior of the library out this time, where
+with `client::connect` we worked from the outside in. We need to change
+*src/lib.rs* to make `network` public too:
+
+Filename: src/lib.rs
+
+```rust,ignore
+pub mod client;
+
+pub mod network;
+```
+
+Now if we compile, that warning is gone:
+
+```text
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+ --> src/network/server.rs:1:1
+ |
+1 | fn connect() {
+ | ^
+```
+
+Only one warning left! Try to fix this one on your own!
+
+### Privacy Rules
+
+Overall, these are the rules for item visibility:
+
+1. If an item is public, it can be accessed through any of its parent modules.
+2. If an item is private, it may be accessed only by the current module and its
+ child modules.
+
+### Privacy Examples
+
+Let’s look at a few more examples to get some practice. Create a new library
+project and enter the code in Listing 7-5 into your new project’s *src/lib.rs*:
+
+Filename: src/lib.rs
+
+```rust,ignore
+mod outermost {
+ pub fn middle_function() {}
+
+ fn middle_secret_function() {}
+
+ mod inside {
+ pub fn inner_function() {}
+
+ fn secret_function() {}
+ }
+}
+
+fn try_me() {
+ outermost::middle_function();
+ outermost::middle_secret_function();
+ outermost::inside::inner_function();
+ outermost::inside::secret_function();
+}
+```
+
+Listing 7-5: Examples of private and public functions,
+some of which are incorrect
+
+Before you try to compile this code, make a guess about which lines in `try_me`
+function will have errors. Then try compiling to see if you were right, and
+read on for discussion of the errors!
+
+#### Looking at the Errors
+
+The `try_me` function is in the root module of our project. The module named
+`outermost` is private, but the second privacy rule says the `try_me` function
+is allowed to access the `outermost` module since `outermost` is in the current
+(root) module, as is `try_me`.
+
+The call to `outermost::middle_function` will work. This is because
+`middle_function` is public, and `try_me` is accessing `middle_function`
+through its parent module, `outermost`. We determined in the previous paragraph
+that this module is accessible.
+
+The call to `outermost::middle_secret_function` will cause a compilation error.
+`middle_secret_function` is private, so the second rule applies. The root
+module is neither the current module of `middle_secret_function` (`outermost`
+is), nor is it a child module of the current module of `middle_secret_function`.
+
+The module named `inside` is private and has no child modules, so it can only
+be accessed by its current module, `outermost`. That means the `try_me`
+function is not allowed to call `outermost::inside::inner_function` or
+`outermost::inside::secret_function` either.
+
+#### Fixing the Errors
+
+Here are some suggestions for changing the code in an attempt to fix the
+errors. Before you try each one, make a guess as to whether it will fix the
+errors, then compile to see if you’re right and use the privacy rules to
+understand why.
+
+* What if the `inside` module was public?
+* What if `outermost` was public and `inside` was private?
+* What if, in the body of `inner_function`, you called
+ `::outermost::middle_secret_function()`? (The two colons at the beginning mean
+ that we want to refer to the modules starting from the root module.)
+
+Feel free to design more experiments and try them out!
+
+Next, let’s talk about bringing items into a scope with the `use` keyword.
diff --git a/trpl-2nd-edition/ch07-03-importing-names-with-use.md b/trpl-2nd-edition/ch07-03-importing-names-with-use.md
new file mode 100644
index 0000000..ab6ecf8
--- /dev/null
+++ b/trpl-2nd-edition/ch07-03-importing-names-with-use.md
@@ -0,0 +1,272 @@
+## Importing Names
+
+We’ve covered how to call functions defined within a module using the module
+name as part of the call, as in the call to the `nested_modules` function shown
+here in Listing 7-6.
+
+Filename: src/main.rs
+
+```rust
+pub mod a {
+ pub mod series {
+ pub mod of {
+ pub fn nested_modules() {}
+ }
+ }
+}
+
+fn main() {
+ a::series::of::nested_modules();
+}
+```
+
+Listing 7-6: Calling a function by fully specifying its
+enclosing module’s namespaces
+
+As you can see, referring to the fully qualified name can get quite lengthy.
+Luckily, Rust has a keyword to make these calls more concise.
+
+### Concise Imports with `use`
+
+Rust’s `use` keyword works to shorten lengthy function calls by bringing the
+modules of the function you want to call into a scope. Here’s an example of
+bringing the `a::series::of` module into a binary crate’s root scope:
+
+Filename: src/main.rs
+
+```rust
+pub mod a {
+ pub mod series {
+ pub mod of {
+ pub fn nested_modules() {}
+ }
+ }
+}
+
+use a::series::of;
+
+fn main() {
+ of::nested_modules();
+}
+```
+
+The line `use a::series::of;` means that rather than using the full
+`a::series::of` path wherever we want to refer to the `of` module, we can use
+`of`.
+
+The `use` keyword brings only what we have specified into scope; it does not
+bring children of modules into scope. That’s why we still have to say
+`of::nested_modules` when we want to call the `nested_modules` function.
+
+We could have chosen to bring the function itself into scope, by instead
+specifying the function in the `use` as follows:
+
+```rust
+pub mod a {
+ pub mod series {
+ pub mod of {
+ pub fn nested_modules() {}
+ }
+ }
+}
+
+use a::series::of::nested_modules;
+
+fn main() {
+ nested_modules();
+}
+```
+
+This allows us to exclude all of the modules and reference the function
+directly.
+
+Since enums also form a sort of namespace like modules, we can import an enum’s
+variants with `use` as well. For any kind of `use` statement, if you’re
+importing multiple items from one namespace, you can list them using curly
+braces and commas in the last position, like so:
+
+```rust
+enum TrafficLight {
+ Red,
+ Yellow,
+ Green,
+}
+
+use TrafficLight::{Red, Yellow};
+
+fn main() {
+ let red = Red;
+ let yellow = Yellow;
+ let green = TrafficLight::Green; // because we didn’t `use` TrafficLight::Green
+}
+```
+
+### Glob Imports with `*`
+
+To import all the items in a namespace at once, we can use the `*` syntax. For
+example:
+
+```rust
+enum TrafficLight {
+ Red,
+ Yellow,
+ Green,
+}
+
+use TrafficLight::*;
+
+fn main() {
+ let red = Red;
+ let yellow = Yellow;
+ let green = Green;
+}
+```
+
+The `*` is called a *glob*, and it will import everything that’s visible inside
+of the namespace. Globs should be used sparingly: they are convenient, but you
+might also pull in more things than you expected and cause naming conflicts.
+
+### Using `super` to Access a Parent Module
+
+As you now know, when you create a library crate, Cargo makes a `tests` module
+for you. Let’s go into more detail about that now. In your `communicator`
+project, open *src/lib.rs*.
+
+Filename: src/lib.rs
+
+```rust,ignore
+pub mod client;
+
+pub mod network;
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn it_works() {
+ }
+}
+```
+
+We’ll explain more about testing in Chapter 11, but parts of this should make
+sense now: we have a module named `tests` that lives next to our other modules
+and contains one function named `it_works`. Even though there are special
+annotations, the `tests` module is just another module! So our module hierarchy
+looks like this:
+
+```text
+communicator
+ ├── client
+ ├── network
+ | └── client
+ └── tests
+```
+
+Tests are for exercising the code within our library, so let’s try to call our
+`client::connect` function from this `it_works` function, even though we’re not
+going to be checking any functionality right now:
+
+Filename: src/lib.rs
+
+```rust
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn it_works() {
+ client::connect();
+ }
+}
+```
+
+Run the tests by invoking the `cargo test` command:
+
+```text
+$ cargo test
+ Compiling communicator v0.1.0 (file:///projects/communicator)
+error[E0433]: failed to resolve. Use of undeclared type or module `client`
+ --> src/lib.rs:9:9
+ |
+9 | client::connect();
+ | ^^^^^^^^^^^^^^^ Use of undeclared type or module `client`
+
+warning: function is never used: `connect`, #[warn(dead_code)] on by default
+ --> src/network/server.rs:1:1
+ |
+1 | fn connect() {
+ | ^
+```
+
+The compilation failed, but why? We don’t need to place `communicator::` in
+front of the function like we did in *src/main.rs* because we are definitely
+within the `communicator` library crate here. The reason is that paths are
+always relative to the current module, which here is `tests`. The only
+exception is in a `use` statement, where paths are relative to the crate root
+by default. Our `tests` module needs the `client` module in its scope!
+
+So how do we get back up one module in the module hierarchy to be able to call
+the `client::connect` function in the `tests` module? In the `tests` module, we
+can either use leading colons to let Rust know that we want to start from the
+root and list the whole path:
+
+```rust,ignore
+::client::connect();
+```
+
+Or we can use `super` to move up one module in the hierarchy from our current
+module:
+
+```rust,ignore
+super::client::connect();
+```
+
+These two options don’t look all that different in this example, but if you’re
+deeper in a module hierarchy, starting from the root every time would get long.
+In those cases, using `super` to get from the current module to sibling modules
+is a good shortcut. Plus, if you’ve specified the path from the root in many
+places in your code and then you rearrange your modules by moving a subtree to
+another place, you’d end up needing to update the path in a lot of places,
+which would be tedious.
+
+It would also be annoying to have to type `super::` all the time in each test,
+but you’ve already seen the tool for that solution: `use`! The `super::`
+functionality changes the path you give to `use` so that it is relative to the
+parent module instead of to the root module.
+
+For these reasons, in the `tests` module especially, `use super::something` is
+usually the way to go. So now our test looks like this:
+
+Filename: src/lib.rs
+
+```rust
+#[cfg(test)]
+mod tests {
+ use super::client;
+
+ #[test]
+ fn it_works() {
+ client::connect();
+ }
+}
+```
+
+If we run `cargo test` again, the test will pass and the first part of the test
+result output will be:
+
+```text
+$ cargo test
+ Compiling communicator v0.1.0 (file:///projects/communicator)
+ Running target/debug/communicator-92007ddb5330fa5a
+
+running 1 test
+test tests::it_works ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+```
+
+## Summary
+
+Now you know techniques for organizing your code! Use these to group related
+functionality together, keep files from getting too long, and present a tidy
+public API to users of your library.
+
+Next, let’s look at some collection data structures in the standard library
+that you can make use of in your nice, neat code!
diff --git a/trpl-2nd-edition/ch08-00-common-collections.md b/trpl-2nd-edition/ch08-00-common-collections.md
new file mode 100644
index 0000000..76abdf9
--- /dev/null
+++ b/trpl-2nd-edition/ch08-00-common-collections.md
@@ -0,0 +1,25 @@
+# Common Collections
+
+Rust’s standard library includes a number of really useful data structures
+called *collections*. Most other data types represent one specific value, but
+collections can contain multiple values. Unlike the built-in array and tuple
+types, the data these collections point to is stored on the heap, which means
+the amount of data does not need to be known at compile time and can grow or
+shrink as the program runs. Each kind of collection has different capabilities
+and costs, and choosing an appropriate one for the situation you’re in is a
+skill you’ll develop over time. In this chapter, we’ll go over three
+collections which are used very often in Rust programs:
+
+* A *vector* allows us to store a variable number of values next to each other.
+* A *string* is a collection of characters. We’ve seen the `String` type
+ before, but we’ll talk about it in depth now.
+* A *hash map* allows us to associate a value with a particular key. It's a
+ particular implementation of the more general data structure called a *map*.
+
+To learn about the other kinds of collections provided by the standard library,
+see [the documentation][collections].
+
+[collections]: ../../std/collections/index.html
+
+We’re going to discuss how to create and update vectors, strings, and hash
+maps, as well as what makes each special.
diff --git a/trpl-2nd-edition/ch08-01-vectors.md b/trpl-2nd-edition/ch08-01-vectors.md
new file mode 100644
index 0000000..f68a2c3
--- /dev/null
+++ b/trpl-2nd-edition/ch08-01-vectors.md
@@ -0,0 +1,225 @@
+## Vectors
+
+The first type we’ll look at is `Vec`, also known as a *vector*. Vectors
+allow us to store more than one value in a single data structure that puts all
+the values next to each other in memory. Vectors can only store values of the
+same type. They are useful in situations where you have a list of items, such
+as the lines of text in a file or the prices of items in a shopping cart.
+
+### Creating a New Vector
+
+To create a new, empty vector, we can call the `Vec::new` function:
+
+```rust
+let v: Vec = Vec::new();
+```
+
+Note that we added a type annotation here. Since we aren’t inserting any values
+into this vector, Rust doesn’t know what kind of elements we intend to store.
+This is an important point. Vectors are homogeneous: they may store many
+values, but those values must all be the same type. Vectors are implemented
+using generics, which Chapter 10 will cover how to use in your own types. For
+now, all you need to know is that the `Vec` type provided by the standard
+library can hold any type, and when a specific `Vec` holds a specific type, the
+type goes within angle brackets. We’ve told Rust that the `Vec` in `v` will
+hold elements of the `i32` type.
+
+In real code, Rust can infer the type of value we want to store once we insert
+values, so you rarely need to do this type annotation. It’s more common to
+create a `Vec` that has initial values, and Rust provides the `vec!` macro for
+convenience. The macro will create a new `Vec` that holds the values we give
+it. This will create a new `Vec` that holds the values `1`, `2`, and `3`:
+
+```rust
+let v = vec![1, 2, 3];
+```
+
+Because we’ve given initial `i32` values, Rust can infer that the type of `v`
+is `Vec`, and the type annotation isn’t necessary. Let’s look at how to
+modify a vector next.
+
+### Updating a Vector
+
+To create a vector then add elements to it, we can use the `push` method:
+
+```rust
+let mut v = Vec::new();
+
+v.push(5);
+v.push(6);
+v.push(7);
+v.push(8);
+```
+
+As with any variable as we discussed in Chapter 3, if we want to be able to
+change its value, we need to make it mutable with the `mut` keyword. The
+numbers we place inside are all of type `i32`, and Rust infers this from the
+data, so we don’t need the `Vec` annotation.
+
+### Dropping a Vector Drops its Elements
+
+Like any other `struct`, a vector will be freed when it goes out of scope:
+
+```rust
+{
+ let v = vec![1, 2, 3, 4];
+
+ // do stuff with v
+
+} // <- v goes out of scope and is freed here
+```
+
+When the vector gets dropped, all of its contents will also be dropped, meaning
+those integers it holds will be cleaned up. This may seem like a
+straightforward point, but can get a little more complicated once we start to
+introduce references to the elements of the vector. Let’s tackle that next!
+
+### Reading Elements of Vectors
+
+Now that you know how to create, update, and destroy vectors, knowing how to
+read their contents is a good next step. There are two ways to reference a
+value stored in a vector. In the examples, we’ve annotated the types of the
+values that are returned from these functions for extra clarity.
+
+This example shows both methods of accessing a value in a vector either with
+indexing syntax or the `get` method:
+
+```rust
+let v = vec![1, 2, 3, 4, 5];
+
+let third: &i32 = &v[2];
+let third: Option<&i32> = v.get(2);
+```
+
+There are a few things to note here. First, that we use the index value of `2`
+to get the third element: vectors are indexed by number, starting at zero.
+Second, the two different ways to get the third element are: using `&` and
+`[]`, which gives us a reference, or using the `get` method with the index
+passed as an argument, which gives us an `Option<&T>`.
+
+The reason Rust has two ways to reference an element is so that you can choose
+how the program behaves when you try to use an index value that the vector
+doesn’t have an element for. As an example, what should a program do if it has
+a vector that holds five elements then tries to access an element at index 100
+like this:
+
+```rust,should_panic
+let v = vec![1, 2, 3, 4, 5];
+
+let does_not_exist = &v[100];
+let does_not_exist = v.get(100);
+```
+
+When you run this, you will find that with the first `[]` method, Rust will
+cause a `panic!` when a non-existent element is referenced. This method would
+be preferable if you want your program to consider an attempt to access an
+element past the end of the vector to be a fatal error that should crash the
+program.
+
+When the `get` method is passed an index that is outside the array, it will
+return `None` without panicking. You would use this if accessing an element
+beyond the range of the vector will happen occasionally under normal
+circumstances. Your code can then have logic to handle having either
+`Some(&element)` or `None`, as we discussed in Chapter 6. For example, the
+index could be coming from a person entering a number. If they accidentally
+enter a number that’s too large and your program gets a `None` value, you could
+tell the user how many items are in the current `Vec` and give them another
+chance to enter a valid value. That would be more user-friendly than crashing
+the program for a typo!
+
+#### Invalid References
+
+Once the program has a valid reference, the borrow checker will enforce the
+ownership and borrowing rules covered in Chapter 4 to ensure this reference and
+any other references to the contents of the vector stay valid. Recall the rule
+that says we can’t have mutable and immutable references in the same scope.
+That rule applies in this example, where we hold an immutable reference to the
+first element in a vector and try to add an element to the end:
+
+```rust,ignore
+let mut v = vec![1, 2, 3, 4, 5];
+
+let first = &v[0];
+
+v.push(6);
+```
+
+Compiling this will give us this error:
+
+```text
+error[E0502]: cannot borrow `v` as mutable because it is also borrowed as
+immutable
+ |
+4 | let first = &v[0];
+ | - immutable borrow occurs here
+5 |
+6 | v.push(6);
+ | ^ mutable borrow occurs here
+7 | }
+ | - immutable borrow ends here
+```
+
+This code might look like it should work: why should a reference to the first
+element care about what changes about the end of the vector? The reason why
+this code isn’t allowed is due to the way vectors work. Adding a new element
+onto the end of the vector might require allocating new memory and copying the
+old elements over to the new space, in the circumstance that there isn’t enough
+room to put all the elements next to each other where the vector was. In that
+case, the reference to the first element would be pointing to deallocated
+memory. The borrowing rules prevent programs from ending up in that situation.
+
+> Note: For more on this, see The Nomicon at
+*https://doc.rust-lang.org/stable/nomicon/vec.html*.
+
+### Using an Enum to Store Multiple Types
+
+At the beginning of this chapter, we said that vectors can only store values
+that are all the same type. This can be inconvenient; there are definitely use
+cases for needing to store a list of things of different types. Luckily, the
+variants of an enum are all defined under the same enum type, so when we need
+to store elements of a different type in a vector, we can define and use an
+enum!
+
+For example, let’s say we want to get values from a row in a spreadsheet, where
+some of the columns in the row contain integers, some floating point numbers,
+and some strings. We can define an enum whose variants will hold the different
+value types, and then all of the enum variants will be considered the same
+type, that of the enum. Then we can create a vector that holds that enum and
+so, ultimately, holds different types:
+
+```rust
+enum SpreadsheetCell {
+ Int(i32),
+ Float(f64),
+ Text(String),
+}
+
+let row = vec![
+ SpreadsheetCell::Int(3),
+ SpreadsheetCell::Text(String::from("blue")),
+ SpreadsheetCell::Float(10.12),
+];
+```
+
+Listing 8-1: Defining an enum to be able to hold
+different types of data in a vector
+
+The reason Rust needs to know exactly what types will be in the vector at
+compile time is so that it knows exactly how much memory on the heap will be
+needed to store each element. A secondary advantage to this is that we can be
+explicit about what types are allowed in this vector. If Rust allowed a vector
+to hold any type, there would be a chance that one or more of the types would
+cause errors with the operations performed on the elements of the vector. Using
+an enum plus a `match` means that Rust will ensure at compile time that we
+always handle every possible case, as we discussed in Chapter 6.
+
+If you don’t know at the time that you’re writing a program the exhaustive set
+of types the program will get at runtime to store in a vector, the enum
+technique won’t work. Instead, you can use a trait object, which we’ll cover in
+Chapter 17.
+
+Now that we’ve gone over some of the most common ways to use vectors, be sure
+to take a look at the API documentation for all of the many useful methods
+defined on `Vec` by the standard library. For example, in addition to `push`
+there’s a `pop` method that will remove and return the last element. Let’s move
+on to the next collection type: `String`!
diff --git a/trpl-2nd-edition/ch08-02-strings.md b/trpl-2nd-edition/ch08-02-strings.md
new file mode 100644
index 0000000..599a1e7
--- /dev/null
+++ b/trpl-2nd-edition/ch08-02-strings.md
@@ -0,0 +1,413 @@
+## Strings
+
+We’ve already talked about strings a bunch in Chapter 4, but let’s take a more
+in-depth look at them now. Strings are an area that new Rustaceans commonly get
+stuck on. This is due to a combination of three things: Rust’s propensity for
+making sure to expose possible errors, strings being a more complicated data
+structure than many programmers give them credit for, and UTF-8. These things
+combine in a way that can seem difficult when coming from other languages.
+
+The reason strings are in the collections chapter is that strings are
+implemented as a collection of bytes plus some methods to provide useful
+functionality when those bytes are interpreted as text. In this section, we’ll
+talk about the operations on `String` that every collection type has, like
+creating, updating, and reading. We’ll also discuss the ways in which `String`
+is different than the other collections, namely how indexing into a `String` is
+complicated by the differences in which people and computers interpret `String`
+data.
+
+### What is a String?
+
+Before we can dig into those aspects, we need to talk about what exactly we
+mean by the term *string*. Rust actually only has one string type in the core
+language itself: `str`, the string slice, which is usually seen in its borrowed
+form, `&str`. We talked about *string slices* in Chapter 4: these are a
+reference to some UTF-8 encoded string data stored elsewhere. String literals,
+for example, are stored in the binary output of the program, and are therefore
+string slices.
+
+The type called `String` is provided in Rust’s standard library rather than
+coded into the core language, and is a growable, mutable, owned, UTF-8 encoded
+string type. When Rustaceans talk about “strings” in Rust, they usually mean
+both the `String` and the string slice `&str` types, not just one of those.
+This section is largely about `String`, but both these types are used heavily
+in Rust’s standard library. Both `String` and string slices are UTF-8 encoded.
+
+Rust’s standard library also includes a number of other string types, such as
+`OsString`, `OsStr`, `CString`, and `CStr`. Library crates may provide even
+more options for storing string data. Similar to the `*String`/`*Str` naming,
+they often provide an owned and borrowed variant, just like `String`/`&str`.
+These string types may store different encodings or be represented in memory in
+a different way, for example. We won’t be talking about these other string
+types in this chapter; see their API documentation for more about how to use
+them and when each is appropriate.
+
+### Creating a New String
+
+Many of the same operations available with `Vec` are available with `String` as
+well, starting with the `new` function to create a string, like so:
+
+```rust
+let s = String::new();
+```
+
+This creates a new empty string called `s` that we can then load data into.
+
+Often, we’ll have some initial data that we’d like to start the string off
+with. For that, we use the `to_string` method, which is available on any type
+that implements the `Display` trait, which string literals do:
+
+```rust
+let data = "initial contents";
+
+let s = data.to_string();
+
+// the method also works on a literal directly:
+let s = "initial contents".to_string();
+```
+
+This creates a string containing `initial contents`.
+
+We can also use the function `String::from` to create a `String` from a string
+literal. This is equivalent to using `to_string`:
+
+```rust
+let s = String::from("initial contents");
+```
+
+Because strings are used for so many things, there are many different generic
+APIs that can be used for strings, so there are a lot of options. Some of them
+can feel redundant, but they all have their place! In this case, `String::from`
+and `.to_string` end up doing the exact same thing, so which you choose is a
+matter of style.
+
+Remember that strings are UTF-8 encoded, so we can include any properly encoded
+data in them:
+
+```rust
+let hello = "السلام عليكم";
+let hello = "Dobrý den";
+let hello = "Hello";
+let hello = "שָׁלוֹם";
+let hello = "नमस्ते";
+let hello = "こんにちは";
+let hello = "안녕하세요";
+let hello = "你好";
+let hello = "Olá";
+let hello = "Здравствуйте";
+let hello = "Hola";
+```
+
+### Updating a String
+
+A `String` can grow in size and its contents can change just like the contents
+of a `Vec`, by pushing more data into it. In addition, `String` has
+concatenation operations implemented with the `+` operator for convenience.
+
+#### Appending to a String with Push
+
+We can grow a `String` by using the `push_str` method to append a string slice:
+
+```rust
+let mut s = String::from("foo");
+s.push_str("bar");
+```
+
+`s` will contain “foobar” after these two lines. The `push_str` method takes a
+string slice because we don’t necessarily want to take ownership of the
+parameter. For example, it would be unfortunate if we weren’t able to use `s2`
+after appending its contents to `s1`:
+
+```rust
+let mut s1 = String::from("foo");
+let s2 = String::from("bar");
+s1.push_str(&s2);
+```
+
+The `push` method is defined to have a single character as a parameter and add
+it to the `String`:
+
+```rust
+let mut s = String::from("lo");
+s.push('l');
+```
+
+After this, `s` will contain “lol”.
+
+#### Concatenation with the + Operator or the `format!` Macro
+
+Often, we’ll want to combine two existing strings together. One way is to use
+the `+` operator like this:
+
+```rust
+let s1 = String::from("Hello, ");
+let s2 = String::from("world!");
+let s3 = s1 + &s2; // Note that s1 has been moved here and can no longer be used
+```
+
+After this code the String `s3` will contain `Hello, world!`. The reason that
+`s1` is no longer valid after the addition and the reason that we used a
+reference to `s2` has to do with the signature of the method that gets called
+when we use the `+` operator. The `+` operator uses the `add` method, whose
+signature looks something like this:
+
+```rust,ignore
+fn add(self, s: &str) -> String {
+```
+
+This isn’t the exact signature that’s in the standard library; there `add` is
+defined using generics. Here, we’re looking at the signature of `add` with
+concrete types substituted for the generic ones, which is what happens when we
+call this method with `String` values. We'll be discussing generics in
+Chapter 10. This signature gives us the clues we need to understand the tricky
+bits of the `+` operator.
+
+First of all, `s2` has an `&`, meaning that we are adding a *reference* of the
+second string to the first string. This is because of the `s` parameter in the
+`add` function: we can only add a `&str` to a `String`, we can't add two
+`String` values together. But wait - the type of `&s2` is `&String`, not
+`&str`, as specified in the second parameter to `add`. Why does our example
+compile? We are able to use `&s2` in the call to `add` because a `&String`
+argument can be *coerced* into a `&str` - when the `add` function is called,
+Rust uses something called a *deref coercion*, which you could think of here as
+turning `&s2` into `&s2[..]` for use in the `add` function. We'll discuss deref
+coercion in more depth in Chapter 15. Because `add` does not take ownership of
+the parameter, `s2` will still be a valid `String` after this operation.
+
+Second, we can see in the signature that `add` takes ownership of `self`,
+because `self` does *not* have an `&`. This means `s1` in the above example
+will be moved into the `add` call and no longer be valid after that. So while
+`let s3 = s1 + &s2;` looks like it will copy both strings and create a new one,
+this statement actually takes ownership of `s1`, appends a copy of the contents
+of `s2`, then returns ownership of the result. In other words, it looks like
+it’s making a lot of copies, but isn’t: the implementation is more efficient
+than copying.
+
+If we need to concatenate multiple strings, the behavior of `+` gets unwieldy:
+
+```rust
+let s1 = String::from("tic");
+let s2 = String::from("tac");
+let s3 = String::from("toe");
+
+let s = s1 + "-" + &s2 + "-" + &s3;
+```
+
+`s` will be “tic-tac-toe” at this point. With all of the `+` and `"`
+characters, it gets hard to see what’s going on. For more complicated string
+combining, we can use the `format!` macro:
+
+```rust
+let s1 = String::from("tic");
+let s2 = String::from("tac");
+let s3 = String::from("toe");
+
+let s = format!("{}-{}-{}", s1, s2, s3);
+```
+
+This code will also set `s` to “tic-tac-toe”. The `format!` macro works in the
+same way as `println!`, but instead of printing the output to the screen, it
+returns a `String` with the contents. This version is much easier to read, and
+also does not take ownership of any of its parameters.
+
+### Indexing into Strings
+
+In many other languages, accessing individual characters in a string by
+referencing them by index is a valid and common operation. In Rust, however, if
+we try to access parts of a `String` using indexing syntax, we’ll get an error.
+That is, this code:
+
+```rust,ignore
+let s1 = String::from("hello");
+let h = s1[0];
+```
+
+will result in this error:
+
+```text
+error: the trait bound `std::string::String: std::ops::Index<_>` is not
+satisfied [--explain E0277]
+ |>
+ |> let h = s1[0];
+ |> ^^^^^
+note: the type `std::string::String` cannot be indexed by `_`
+```
+
+The error and the note tell the story: Rust strings don’t support indexing. So
+the follow-up question is, why not? In order to answer that, we have to talk a
+bit about how Rust stores strings in memory.
+
+#### Internal Representation
+
+A `String` is a wrapper over a `Vec`. Let’s take a look at some of our
+properly-encoded UTF-8 example strings from before. First, this one:
+
+```rust
+let len = String::from("Hola").len();
+```
+
+In this case, `len` will be four, which means the `Vec` storing the string
+“Hola” is four bytes long: each of these letters takes one byte when encoded in
+UTF-8. What about this example, though?
+
+```rust
+let len = String::from("Здравствуйте").len();
+```
+
+A person asked how long the string is might say 12. However, Rust’s answer
+is 24. This is the number of bytes that it takes to encode “Здравствуйте” in
+UTF-8, since each Unicode scalar value takes two bytes of storage. Therefore,
+an index into the string’s bytes will not always correlate to a valid Unicode
+scalar value.
+
+To demonstrate, consider this invalid Rust code:
+
+```rust,ignore
+let hello = "Здравствуйте";
+let answer = &hello[0];
+```
+
+What should the value of `answer` be? Should it be `З`, the first letter? When
+encoded in UTF-8, the first byte of `З` is `208`, and the second is `151`, so
+`answer` should in fact be `208`, but `208` is not a valid character on its
+own. Returning `208` is likely not what a person would want if they asked for
+the first letter of this string, but that’s the only data that Rust has at byte
+index 0. Returning the byte value is probably not what people want, even with
+only Latin letters: `&"hello"[0]` would return `104`, not `h`. To avoid
+returning an unexpected value and causing bugs that might not be discovered
+immediately, Rust chooses to not compile this code at all and prevent
+misunderstandings earlier.
+
+#### Bytes and Scalar Values and Grapheme Clusters! Oh my!
+
+This leads to another point about UTF-8: there are really three relevant ways
+to look at strings, from Rust’s perspective: as bytes, scalar values, and
+grapheme clusters (the closest thing to what people would call *letters*).
+
+If we look at the Hindi word “नमस्ते” written in the Devanagari script, it is
+ultimately stored as a `Vec` of `u8` values that looks like this:
+
+```text
+[224, 164, 168, 224, 164, 174, 224, 164, 184, 224, 165, 141, 224, 164, 164,
+224, 165, 135]
+```
+
+That’s 18 bytes, and is how computers ultimately store this data. If we look at
+them as Unicode scalar values, which are what Rust’s `char` type is, those
+bytes look like this:
+
+```text
+['न', 'म', 'स', '्', 'त', 'े']
+```
+
+There are six `char` values here, but the fourth and sixth are not letters,
+they’re diacritics that don’t make sense on their own. Finally, if we look at
+them as grapheme clusters, we’d get what a person would call the four letters
+that make up this word:
+
+```text
+["न", "म", "स्", "ते"]
+```
+
+Rust provides different ways of interpreting the raw string data that computers
+store so that each program can choose the interpretation it needs, no matter
+what human language the data is in.
+
+A final reason Rust does not allow you to index into a `String` to get a
+character is that indexing operations are expected to always take constant time
+(O(1)). It isn’t possible to guarantee that performance with a `String`,
+though, since Rust would have to walk through the contents from the beginning
+to the index to determine how many valid characters there were.
+
+### Slicing Strings
+
+Because it's not clear what the return type of string indexing should be, and
+it is often a bad idea to index into a string, Rust dissuades you from doing so
+by asking you to be more specific if you really need it. The way you can be
+more specific than indexing using `[]` with a single number is using `[]` with
+a range to create a string slice containing particular bytes:
+
+```rust
+let hello = "Здравствуйте";
+
+let s = &hello[0..4];
+```
+
+Here, `s` will be a `&str` that contains the first four bytes of the string.
+Earlier, we mentioned that each of these characters was two bytes, so that
+means that `s` will be “Зд”.
+
+What would happen if we did `&hello[0..1]`? The answer: it will panic at
+runtime, in the same way that accessing an invalid index in a vector does:
+
+```text
+thread 'main' panicked at 'index 0 and/or 1 in `Здравствуйте` do not lie on
+character boundary', ../src/libcore/str/mod.rs:1694
+```
+
+You should use this with caution, since it can cause your program to crash.
+
+### Methods for Iterating Over Strings
+
+Luckily, there are other ways we can access elements in a String.
+
+If we need to perform operations on individual Unicode scalar values, the best
+way to do so is to use the `chars` method. Calling `chars` on “नमस्ते”
+separates out and returns six values of type `char`, and you can iterate over
+the result in order to access each element:
+
+```rust
+for c in "नमस्ते".chars() {
+ println!("{}", c);
+}
+```
+
+This code will print:
+
+```text
+न
+म
+स
+्
+त
+े
+```
+
+The `bytes` method returns each raw byte, which might be appropriate for your
+domain:
+
+```rust
+for b in "नमस्ते".bytes() {
+ println!("{}", b);
+}
+```
+
+This code will print the 18 bytes that make up this `String`, starting with:
+
+```text
+224
+164
+168
+224
+// ... etc
+```
+
+But make sure to remember that valid Unicode scalar values may be made up of
+more than one byte.
+
+Getting grapheme clusters from strings is complex, so this functionality is not
+provided by the standard library. There are crates available on crates.io if
+this is the functionality you need.
+
+### Strings are Not so Simple
+
+To summarize, strings are complicated. Different programming languages make
+different choices about how to present this complexity to the programmer. Rust
+has chosen to make the correct handling of `String` data the default behavior
+for all Rust programs, which does mean programmers have to put more thought
+into handling UTF-8 data upfront. This tradeoff exposes more of the complexity
+of strings than other programming languages do, but this will prevent you from
+having to handle errors involving non-ASCII characters later in your
+development lifecycle.
+
+Let’s switch to something a bit less complex: hash map!
diff --git a/trpl-2nd-edition/ch08-03-hash-maps.md b/trpl-2nd-edition/ch08-03-hash-maps.md
new file mode 100644
index 0000000..a2024de
--- /dev/null
+++ b/trpl-2nd-edition/ch08-03-hash-maps.md
@@ -0,0 +1,272 @@
+## Hash Maps
+
+The last of our common collections is the *hash map*. The type `HashMap`
+stores a mapping of keys of type `K` to values of type `V`. It does this via a
+*hashing function*, which determines how it places these keys and values into
+memory. Many different programming languages support this kind of data
+structure, but often with a different name: hash, map, object, hash table, or
+associative array, just to name a few.
+
+Hash maps are useful for when you want to be able to look up data not by an
+index, as you can with vectors, but by using a key that can be of any type. For
+example, in a game, you could keep track of each team’s score in a hash map
+where each key is a team’s name and the values are each team’s score. Given a
+team name, you can retrieve their score.
+
+We’ll go over the basic API of hash maps in this chapter, but there are many
+more goodies hiding in the functions defined on `HashMap` by the standard
+library. As always, check the standard library documentation for more
+information.
+
+### Creating a New Hash Map
+
+We can create an empty `HashMap` with `new`, and add elements with `insert`.
+Here we’re keeping track of the scores of two teams whose names are Blue and
+Yellow. The Blue team will start with 10 points and the Yellow team starts with
+50:
+
+```rust
+use std::collections::HashMap;
+
+let mut scores = HashMap::new();
+
+scores.insert(String::from("Blue"), 10);
+scores.insert(String::from("Yellow"), 50);
+```
+
+Note that we need to first `use` the `HashMap` from the collections portion of
+the standard library. Of our three common collections, this one is the least
+often used, so it’s not included in the features imported automatically in the
+prelude. Hash maps also have less support from the standard library; there’s no
+built-in macro to construct them, for example.
+
+Just like vectors, hash maps store their data on the heap. This `HashMap` has
+keys of type `String` and values of type `i32`. Like vectors, hash maps are
+homogeneous: all of the keys must have the same type, and all of the values
+must have the same type.
+
+Another way of constructing a hash map is by using the `collect` method on a
+vector of tuples, where each tuple consists of a key and its value. The
+`collect` method gathers up data into a number of collection types, including
+`HashMap`. For example, if we had the team names and initial scores in two
+separate vectors, we can use the `zip` method to create a vector of tuples
+where “Blue” is paired with 10, and so forth. Then we can use the `collect`
+method to turn that vector of tuples into a `HashMap`:
+
+```rust
+use std::collections::HashMap;
+
+let teams = vec![String::from("Blue"), String::from("Yellow")];
+let initial_scores = vec![10, 50];
+
+let scores: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect();
+```
+
+The type annotation `HashMap<_, _>` is needed here because it’s possible to
+`collect` into many different data structures, and Rust doesn’t know which you
+want unless you specify. For the type parameters for the key and value types,
+however, we use underscores and Rust can infer the types that the hash map
+contains based on the types of the data in the vector.
+
+### Hash Maps and Ownership
+
+For types that implement the `Copy` trait, like `i32`, the values are copied
+into the hash map. For owned values like `String`, the values will be moved and
+the hash map will be the owner of those values:
+
+```rust
+use std::collections::HashMap;
+
+let field_name = String::from("Favorite color");
+let field_value = String::from("Blue");
+
+let mut map = HashMap::new();
+map.insert(field_name, field_value);
+// field_name and field_value are invalid at this point
+```
+
+We would not be able to use the bindings `field_name` and `field_value` after
+they have been moved into the hash map with the call to `insert`.
+
+If we insert references to values into the hash map, the values themselves will
+not be moved into the hash map. The values that the references point to must be
+valid for at least as long as the hash map is valid, though. We will talk more
+about these issues in the Lifetimes section of Chapter 10.
+
+### Accessing Values in a Hash Map
+
+We can get a value out of the hash map by providing its key to the `get` method:
+
+```rust
+use std::collections::HashMap;
+
+let mut scores = HashMap::new();
+
+scores.insert(String::from("Blue"), 10);
+scores.insert(String::from("Yellow"), 50);
+
+let team_name = String::from("Blue");
+let score = scores.get(&team_name);
+```
+
+Here, `score` will have the value that’s associated with the Blue team, and the
+result will be `Some(10)`. The result is wrapped in `Some` because `get`
+returns an `Option`; if there’s no value for that key in the hash map, `get`
+will return `None`. The program will need to handle the `Option` in one of the
+ways that we covered in Chapter 6.
+
+We can iterate over each key/value pair in a hash map in a similar manner as we
+do with vectors, using a `for` loop:
+
+```rust
+use std::collections::HashMap;
+
+let mut scores = HashMap::new();
+
+scores.insert(String::from("Blue"), 10);
+scores.insert(String::from("Yellow"), 50);
+
+for (key, value) in &scores {
+ println!("{}: {}", key, value);
+}
+```
+
+This will print each pair, in an arbitrary order:
+
+```text
+Yellow: 50
+Blue: 10
+```
+
+### Updating a Hash Map
+
+While the number of keys and values is growable, each individual key can only
+have one value associated with it at a time. When we want to change the data in
+a hash map, we have to decide how to handle the case when a key already has a
+value assigned. We could choose to replace the old value with the new value,
+completely disregarding the old value. We could choose to keep the old value
+and ignore the new value, and only add the new value if the key *doesn’t*
+already have a value. Or we could combine the old value and the new value.
+Let’s look at how to do each of these!
+
+#### Overwriting a Value
+
+If we insert a key and a value into a hash map, then insert that same key with
+a different value, the value associated with that key will be replaced. Even
+though this following code calls `insert` twice, the hash map will only contain
+one key/value pair because we’re inserting the value for the Blue team’s key
+both times:
+
+```rust
+use std::collections::HashMap;
+
+let mut scores = HashMap::new();
+
+scores.insert(String::from("Blue"), 10);
+scores.insert(String::from("Blue"), 25);
+
+println!("{:?}", scores);
+```
+
+This will print `{"Blue": 25}`. The original value of 10 has been overwritten.
+
+#### Only Insert If the Key Has No Value
+
+It’s common to want to check if a particular key has a value and, if it does
+not, insert a value for it. Hash maps have a special API for this, called
+`entry`, that takes the key we want to check as an argument. The return value
+of the `entry` function is an enum, `Entry`, that represents a value that might
+or might not exist. Let’s say that we want to check if the key for the Yellow
+team has a value associated with it. If it doesn’t, we want to insert the value
+50, and the same for the Blue team. With the entry API, the code for this looks
+like:
+
+```rust
+use std::collections::HashMap;
+
+let mut scores = HashMap::new();
+scores.insert(String::from("Blue"), 10);
+
+scores.entry(String::from("Yellow")).or_insert(50);
+scores.entry(String::from("Blue")).or_insert(50);
+
+println!("{:?}", scores);
+```
+
+The `or_insert` method on `Entry` returns the value for the corresponding
+`Entry` key if it exists, and if not, inserts its argument as the new value for
+this key and returns the modified `Entry`. This is much cleaner than writing
+the logic ourselves, and in addition, plays more nicely with the borrow checker.
+
+This code will print `{"Yellow": 50, "Blue": 10}`. The first call to `entry`
+will insert the key for the Yellow team with the value 50, since the Yellow
+team doesn’t have a value already. The second call to `entry` will not change
+the hash map since the Blue team already has the value 10.
+
+#### Update a Value Based on the Old Value
+
+Another common use case for hash maps is to look up a key’s value then update
+it, based on the old value. For instance, if we wanted to count how many times
+each word appeared in some text, we could use a hash map with the words as keys
+and increment the value to keep track of how many times we’ve seen that word.
+If this is the first time we’ve seen a word, we’ll first insert the value `0`.
+
+```rust
+use std::collections::HashMap;
+
+let text = "hello world wonderful world";
+
+let mut map = HashMap::new();
+
+for word in text.split_whitespace() {
+ let count = map.entry(word).or_insert(0);
+ *count += 1;
+}
+
+println!("{:?}", map);
+```
+
+This will print `{"world": 2, "hello": 1, "wonderful": 1}`. The `or_insert`
+method actually returns a mutable reference (`&mut V`) to the value for this
+key. Here we store that mutable reference in the `count` variable, so in order
+to assign to that value we must first dereference `count` using the asterisk
+(`*`). The mutable reference goes out of scope at the end of the `for` loop, so
+all of these changes are safe and allowed by the borrowing rules.
+
+### Hashing Function
+
+By default, `HashMap` uses a cryptographically secure hashing function that can
+provide resistance to Denial of Service (DoS) attacks. This is not the fastest
+hashing algorithm out there, but the tradeoff for better security that comes
+with the drop in performance is worth it. If you profile your code and find
+that the default hash function is too slow for your purposes, you can switch to
+another function by specifying a different *hasher*. A hasher is a type that
+implements the `BuildHasher` trait. We’ll be talking about traits and how to
+implement them in Chapter 10. You don't necessarily have to implement your own
+hasher from scratch; crates.io has libraries that others have shared that
+provide hashers implementing many common hashing algorithms.
+
+## Summary
+
+Vectors, strings, and hash maps will take you far in programs where you need to
+store, access, and modify data. Here are some exercises you should now be
+equipped to solve:
+
+* Given a list of integers, use a vector and return the mean (average), median
+ (when sorted, the value in the middle position), and mode (the value that
+ occurs most often; a hash map will be helpful here) of the list.
+* Convert strings to Pig Latin, where the first consonant of each word is moved
+ to the end of the word with an added “ay”, so “first” becomes “irst-fay”.
+ Words that start with a vowel get “hay” added to the end instead (“apple”
+ becomes “apple-hay”). Remember about UTF-8 encoding!
+* Using a hash map and vectors, create a text interface to allow a user to add
+ employee names to a department in the company. For example, “Add Sally to
+ Engineering” or “Add Amir to Sales”. Then let the user retrieve a list of all
+ people in a department or all people in the company by department, sorted
+ alphabetically.
+
+The standard library API documentation describes methods these types have that
+will be helpful for these exercises!
+
+We’re getting into more complex programs where operations can fail, which means
+it’s a perfect time to go over error handling next!
diff --git a/trpl-2nd-edition/ch09-00-error-handling.md b/trpl-2nd-edition/ch09-00-error-handling.md
new file mode 100644
index 0000000..3fbaa31
--- /dev/null
+++ b/trpl-2nd-edition/ch09-00-error-handling.md
@@ -0,0 +1,23 @@
+# Error Handling
+
+Rust’s commitment to reliability extends to error handling. Errors are a fact
+of life in software, so Rust has a number of features for handling situations
+in which something goes wrong. In many cases, Rust will require you to
+acknowledge the possibility of an error occurring and take some action before
+your code will compile. This makes your program more robust by ensuring that
+you won’t only discover errors after you’ve deployed your code to production.
+
+Rust groups errors into two major categories: *recoverable* and *unrecoverable*
+errors. Recoverable errors are situations when it’s usually reasonable to
+report the problem to the user and retry the operation, like a file not being
+found. Unrecoverable errors are always symptoms of bugs, like trying to access
+a location beyond the end of an array.
+
+Most languages don’t distinguish between the two kinds of errors, and handle
+both in the same way using mechanisms like exceptions. Rust doesn’t have
+exceptions. Instead, it has the value `Result` for recoverable errors and
+the `panic!` macro that stops execution when it encounters unrecoverable
+errors. This chapter will cover calling `panic!` first, then talk about
+returning `Result` values. Finally, we’ll discuss considerations to take
+into account when deciding whether to try to recover from an error or to stop
+execution.
diff --git a/trpl-2nd-edition/ch09-01-unrecoverable-errors-with-panic.md b/trpl-2nd-edition/ch09-01-unrecoverable-errors-with-panic.md
new file mode 100644
index 0000000..7537329
--- /dev/null
+++ b/trpl-2nd-edition/ch09-01-unrecoverable-errors-with-panic.md
@@ -0,0 +1,179 @@
+## Unrecoverable Errors with `panic!`
+
+Sometimes, bad things happen, and there’s nothing that you can do about it. For
+these cases, Rust has the `panic!` macro. When this macro executes, your
+program will print a failure message, unwind and clean up the stack, and then
+quit. The most common situation this occurs in is when a bug of some kind has
+been detected and it’s not clear to the programmer how to handle the error.
+
+> ### Unwinding the Stack Versus Aborting on Panic
+>
+> By default, when a `panic!` occurs, the program starts
+> *unwinding*, which means Rust walks back up the stack and cleans up the data
+> from each function it encounters, but this walking and cleanup is a lot of
+> work. The alternative is to immediately *abort*, which ends the program
+> without cleaning up. Memory that the program was using will then need to be
+> cleaned up by the operating system. If in your project you need to make the
+> resulting binary as small as possible, you can switch from unwinding to
+> aborting on panic by adding `panic = 'abort'` to the appropriate `[profile]`
+> sections in your *Cargo.toml*. For example, if you want to abort on panic in
+> release mode:
+>
+> ```toml
+> [profile.release]
+> panic = 'abort'
+> ```
+
+Let’s try calling `panic!` with a simple program:
+
+Filename: src/main.rs
+
+```rust,should_panic
+fn main() {
+ panic!("crash and burn");
+}
+```
+
+If you run it, you’ll see something like this:
+
+```text
+$ cargo run
+ Compiling panic v0.1.0 (file:///projects/panic)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.25 secs
+ Running `target/debug/panic`
+thread 'main' panicked at 'crash and burn', src/main.rs:2
+note: Run with `RUST_BACKTRACE=1` for a backtrace.
+error: Process didn't exit successfully: `target/debug/panic` (exit code: 101)
+```
+
+The last three lines contain the error message caused by the call to `panic!`.
+The first line shows our panic message and the place in our source code where
+the panic occurred: *src/main.rs:2* indicates that it’s the second line of our
+*src/main.rs* file.
+
+In this case, the line indicated is part of our code, and if we go to that line
+we see the `panic!` macro call. In other cases, the `panic!` call might be in
+code that our code calls. The filename and line number reported by the error
+message will be someone else’s code where the `panic!` macro is called, not the
+line of our code that eventually led to the `panic!`. We can use the backtrace
+of the functions the `panic!` call came from to figure this out.
+
+### Using a `panic!` Backtrace
+
+Let’s look at another example to see what it’s like when a `panic!` call comes
+from a library because of a bug in our code instead of from our code calling
+the macro directly:
+
+Filename: src/main.rs
+
+```rust,should_panic
+fn main() {
+ let v = vec![1, 2, 3];
+
+ v[100];
+}
+```
+
+We’re attempting to access the hundredth element of our vector, but it only has
+three elements. In this situation, Rust will panic. Using `[]` is supposed to
+return an element, but if you pass an invalid index, there’s no element that
+Rust could return here that would be correct.
+
+Other languages like C will attempt to give you exactly what you asked for in
+this situation, even though it isn’t what you want: you’ll get whatever is at
+the location in memory that would correspond to that element in the vector,
+even though the memory doesn’t belong to the vector. This is called a *buffer
+overread*, and can lead to security vulnerabilities if an attacker can
+manipulate the index in such a way as to read data they shouldn’t be allowed to
+that is stored after the array.
+
+In order to protect your program from this sort of vulnerability, if you try to
+read an element at an index that doesn’t exist, Rust will stop execution and
+refuse to continue. Let’s try it and see:
+
+```text
+$ cargo run
+ Compiling panic v0.1.0 (file:///projects/panic)
+ Finished debug [unoptimized + debuginfo] target(s) in 0.27 secs
+ Running `target/debug/panic`
+thread 'main' panicked at 'index out of bounds: the len is 3 but the index is
+100', /stable-dist-rustc/build/src/libcollections/vec.rs:1362
+note: Run with `RUST_BACKTRACE=1` for a backtrace.
+error: Process didn't exit successfully: `target/debug/panic` (exit code: 101)
+```
+
+This points at a file we didn’t write, *libcollections/vec.rs*. That’s the
+implementation of `Vec` in the standard library. The code that gets run when
+we use `[]` on our vector `v` is in *libcollections/vec.rs*, and that is where
+the `panic!` is actually happening.
+
+The next note line tells us that we can set the `RUST_BACKTRACE` environment
+variable to get a backtrace of exactly what happened to cause the error. Let’s
+try that. Listing 9-1 shows the output:
+
+```text
+$ RUST_BACKTRACE=1 cargo run
+ Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
+ Running `target/debug/panic`
+thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 100', /stable-dist-rustc/build/src/libcollections/vec.rs:1392
+stack backtrace:
+ 1: 0x560ed90ec04c - std::sys::imp::backtrace::tracing::imp::write::hf33ae72d0baa11ed
+ at /stable-dist-rustc/build/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
+ 2: 0x560ed90ee03e - std::panicking::default_hook::{{closure}}::h59672b733cc6a455
+ at /stable-dist-rustc/build/src/libstd/panicking.rs:351
+ 3: 0x560ed90edc44 - std::panicking::default_hook::h1670459d2f3f8843
+ at /stable-dist-rustc/build/src/libstd/panicking.rs:367
+ 4: 0x560ed90ee41b - std::panicking::rust_panic_with_hook::hcf0ddb069e7abcd7
+ at /stable-dist-rustc/build/src/libstd/panicking.rs:555
+ 5: 0x560ed90ee2b4 - std::panicking::begin_panic::hd6eb68e27bdf6140
+ at /stable-dist-rustc/build/src/libstd/panicking.rs:517
+ 6: 0x560ed90ee1d9 - std::panicking::begin_panic_fmt::abcd5965948b877f8
+ at /stable-dist-rustc/build/src/libstd/panicking.rs:501
+ 7: 0x560ed90ee167 - rust_begin_unwind
+ at /stable-dist-rustc/build/src/libstd/panicking.rs:477
+ 8: 0x560ed911401d - core::panicking::panic_fmt::hc0f6d7b2c300cdd9
+ at /stable-dist-rustc/build/src/libcore/panicking.rs:69
+ 9: 0x560ed9113fc8 - core::panicking::panic_bounds_check::h02a4af86d01b3e96
+ at /stable-dist-rustc/build/src/libcore/panicking.rs:56
+ 10: 0x560ed90e71c5 - as core::ops::Index>::index::h98abcd4e2a74c41
+ at /stable-dist-rustc/build/src/libcollections/vec.rs:1392
+ 11: 0x560ed90e727a - panic::main::h5d6b77c20526bc35
+ at /home/you/projects/panic/src/main.rs:4
+ 12: 0x560ed90f5d6a - __rust_maybe_catch_panic
+ at /stable-dist-rustc/build/src/libpanic_unwind/lib.rs:98
+ 13: 0x560ed90ee926 - std::rt::lang_start::hd7c880a37a646e81
+ at /stable-dist-rustc/build/src/libstd/panicking.rs:436
+ at /stable-dist-rustc/build/src/libstd/panic.rs:361
+ at /stable-dist-rustc/build/src/libstd/rt.rs:57
+ 14: 0x560ed90e7302 - main
+ 15: 0x7f0d53f16400 - __libc_start_main
+ 16: 0x560ed90e6659 - _start
+ 17: 0x0 -
+```
+
+Listing 9-1: The backtrace generated by a call to
+`panic!` displayed when the environment variable `RUST_BACKTRACE` is set
+
+That’s a lot of output! Line 11 of the backtrace points to the line in our
+project causing the problem: *src/main.rs*, line four. A backtrace is a list of
+all the functions that have been called to get to this point. Backtraces in
+Rust work like they do in other languages: the key to reading the backtrace is
+to start from the top and read until you see files you wrote. That’s the spot
+where the problem originated. The lines above the lines mentioning your files
+are code that your code called; the lines below are code that called your code.
+These lines might include core Rust code, standard library code, or crates that
+you’re using.
+
+If we don’t want our program to panic, the location pointed to by the first
+line mentioning a file we wrote is where we should start investigating in order
+to figure out how we got to this location with values that caused the panic. In
+our example where we deliberately wrote code that would panic in order to
+demonstrate how to use backtraces, the way to fix the panic is to not try to
+request an element at index 100 from a vector that only contains three items.
+When your code panics in the future, you’ll need to figure out for your
+particular case what action the code is taking with what values that causes the
+panic and what the code should do instead.
+
+We’ll come back to `panic!` and when we should and should not use these methods
+later in the chapter. Next, we’ll now look at how to recover from an error with
+`Result`.
diff --git a/trpl-2nd-edition/ch09-02-recoverable-errors-with-result.md b/trpl-2nd-edition/ch09-02-recoverable-errors-with-result.md
new file mode 100644
index 0000000..17a47b5
--- /dev/null
+++ b/trpl-2nd-edition/ch09-02-recoverable-errors-with-result.md
@@ -0,0 +1,452 @@
+## Recoverable Errors with `Result`
+
+Most errors aren’t serious enough to require the program to stop entirely.
+Sometimes, when a function fails, it’s for a reason that we can easily
+interpret and respond to. For example, if we try to open a file and that
+operation fails because the file doesn’t exist, we might want to create the
+file instead of terminating the process.
+
+Recall from Chapter 2 the section on “[Handling Potential Failure with the
+`Result` Type][handle_failure]” that the `Result` enum is defined
+as having two variants, `Ok` and `Err`, as follows:
+
+[handle_failure]: ch02-00-guessing-game-tutorial.html#handling-potential-failure-with-the-result-type
+
+```rust
+enum Result {
+ Ok(T),
+ Err(E),
+}
+```
+
+The `T` and `E` are generic type parameters; we’ll go into generics in more
+detail in Chapter 10. What you need to know right now is that `T` represents
+the type of the value that will be returned in a success case within the `Ok`
+variant, and `E` represents the type of the error that will be returned in a
+failure case within the `Err` variant. Because `Result` has these generic type
+parameters, we can use the `Result` type and the functions that the standard
+library has defined on it in many different situations where the successful
+value and error value we want to return may differ.
+
+Let’s call a function that returns a `Result` value because the function could
+fail: opening a file, shown in Listing 9-2.
+
+Filename: src/main.rs
+
+```rust
+use std::fs::File;
+
+fn main() {
+ let f = File::open("hello.txt");
+}
+```
+
+Listing 9-2: Opening a file
+
+How do we know `File::open` returns a `Result`? We could look at the standard
+library API documentation, or we could ask the compiler! If we give `f` a type
+annotation of some type that we know the return type of the function is *not*,
+then we try to compile the code, the compiler will tell us that the types don’t
+match. The error message will then tell us what the type of `f` *is*! Let’s try
+it: we know that the return type of `File::open` isn’t of type `u32`, so let’s
+change the `let f` statement to:
+
+```rust,ignore
+let f: u32 = File::open("hello.txt");
+```
+
+Attempting to compile now gives us:
+
+```text
+error[E0308]: mismatched types
+ --> src/main.rs:4:18
+ |
+4 | let f: u32 = File::open("hello.txt");
+ | ^^^^^^^^^^^^^^^^^^^^^^^ expected u32, found enum
+`std::result::Result`
+ |
+ = note: expected type `u32`
+ = note: found type `std::result::Result`
+```
+
+This tells us the return type of the `File::open` function is a `Result`.
+The generic parameter `T` has been filled in here with the type of the success
+value, `std::fs::File`, which is a file handle. The type of `E` used in the
+error value is `std::io::Error`.
+
+This return type means the call to `File::open` might succeed and return to us
+a file handle that we can read from or write to. The function call also might
+fail: for example, the file might not exist, or we might not have permission to
+access the file. The `File::open` function needs to have a way to tell us
+whether it succeeded or failed, and at the same time give us either the file
+handle or error information. This information is exactly what the `Result` enum
+conveys.
+
+In the case where `File::open` succeeds, the value we will have in the variable
+`f` will be an instance of `Ok` that contains a file handle. In the case where
+it fails, the value in `f` will be an instance of `Err` that contains more
+information about the kind of error that happened.
+
+We need to add to the code from Listing 9-2 to take different actions depending
+on the value `File::open` returned. Listing 9-3 shows one way to handle the
+`Result` with a basic tool: the `match` expression that we learned about in
+Chapter 6.
+
+Filename: src/main.rs
+
+```rust,should_panic
+use std::fs::File;
+
+fn main() {
+ let f = File::open("hello.txt");
+
+ let f = match f {
+ Ok(file) => file,
+ Err(error) => {
+ panic!("There was a problem opening the file: {:?}", error)
+ },
+ };
+}
+```
+
+Listing 9-3: Using a `match` expression to handle the
+`Result` variants we might have
+
+Note that, like the `Option` enum, the `Result` enum and its variants have been
+imported in the prelude, so we don’t need to specify `Result::` before the `Ok`
+and `Err` variants in the `match` arms.
+
+Here we tell Rust that when the result is `Ok`, return the inner `file` value
+out of the `Ok` variant, and we then assign that file handle value to the
+variable `f`. After the `match`, we can then use the file handle for reading or
+writing.
+
+The other arm of the `match` handles the case where we get an `Err` value from
+`File::open`. In this example, we’ve chosen to call the `panic!` macro. If
+there’s no file named *hello.txt* in our current directory and we run this
+code, we’ll see the following output from the `panic!` macro:
+
+```text
+thread 'main' panicked at 'There was a problem opening the file: Error { repr:
+Os { code: 2, message: "No such file or directory" } }', src/main.rs:8
+```
+
+### Matching on Different Errors
+
+The code in Listing 9-3 will `panic!` no matter the reason that `File::open`
+failed. What we’d really like to do instead is take different actions for
+different failure reasons: if `File::open` failed because the file doesn’t
+exist, we want to create the file and return the handle to the new file. If
+`File::open` failed for any other reason, for example because we didn’t have
+permission to open the file, we still want to `panic!` in the same way as we
+did in Listing 9-3. Let’s look at Listing 9-4, which adds another arm to the
+`match`:
+
+Filename: src/main.rs
+
+```rust,ignore
+use std::fs::File;
+use std::io::ErrorKind;
+
+fn main() {
+ let f = File::open("hello.txt");
+
+ let f = match f {
+ Ok(file) => file,
+ Err(ref error) if error.kind() == ErrorKind::NotFound => {
+ match File::create("hello.txt") {
+ Ok(fc) => fc,
+ Err(e) => {
+ panic!(
+ "Tried to create file but there was a problem: {:?}",
+ e
+ )
+ },
+ }
+ },
+ Err(error) => {
+ panic!(
+ "There was a problem opening the file: {:?}",
+ error
+ )
+ },
+ };
+}
+```
+
+Listing 9-4: Handling different kinds of errors in
+different ways
+
+The type of the value that `File::open` returns inside the `Err` variant is
+`io::Error`, which is a struct provided by the standard library. This struct
+has a method `kind` that we can call to get an `io::ErrorKind` value.
+`io::ErrorKind` is an enum provided by the standard library that has variants
+representing the different kinds of errors that might result from an `io`
+operation. The variant we’re interested in is `ErrorKind::NotFound`, which
+indicates the file we’re trying to open doesn’t exist yet.
+
+The condition `if error.kind() == ErrorKind::NotFound` is called a *match
+guard*: it’s an extra condition on a `match` arm that further refines the arm’s
+pattern. This condition must be true in order for that arm’s code to get run;
+otherwise, the pattern matching will move on to consider the next arm in the
+`match`. The `ref` in the pattern is needed so that `error` is not moved into
+the guard condition but is merely referenced by it. The reason `ref` is used to
+take a reference in a pattern instead of `&` will be covered in detail in
+Chapter 18. In short, in the context of a pattern, `&` matches a reference and
+gives us its value, but `ref` matches a value and gives us a reference to it.
+
+The condition we want to check in the match guard is whether the value returned
+by `error.kind()` is the `NotFound` variant of the `ErrorKind` enum. If it is,
+we try to create the file with `File::create`. However, since `File::create`
+could also fail, we need to add an inner `match` statement as well! When the
+file can’t be opened, a different error message will be printed. The last arm
+of the outer `match` stays the same so that the program panics on any error
+besides the missing file error.
+
+### Shortcuts for Panic on Error: `unwrap` and `expect`
+
+Using `match` works well enough, but it can be a bit verbose and doesn’t always
+communicate intent well. The `Result` type has many helper methods
+defined on it to do various things. One of those methods, called `unwrap`, is a
+shortcut method that is implemented just like the `match` statement we wrote in
+Listing 9-3. If the `Result` value is the `Ok` variant, `unwrap` will return
+the value inside the `Ok`. If the `Result` is the `Err` variant, `unwrap` will
+call the `panic!` macro for us.
+
+```rust,should_panic
+use std::fs::File;
+
+fn main() {
+ let f = File::open("hello.txt").unwrap();
+}
+```
+
+If we run this code without a *hello.txt* file, we’ll see an error message from
+the `panic!` call that the `unwrap` method makes:
+
+```text
+thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error {
+repr: Os { code: 2, message: "No such file or directory" } }',
+/stable-dist-rustc/build/src/libcore/result.rs:868
+```
+
+There’s another method similar to `unwrap` that lets us also choose the
+`panic!` error message: `expect`. Using `expect` instead of `unwrap` and
+providing good error messages can convey your intent and make tracking down the
+source of a panic easier. The syntax of `expect` looks like this:
+
+```rust,should_panic
+use std::fs::File;
+
+fn main() {
+ let f = File::open("hello.txt").expect("Failed to open hello.txt");
+}
+```
+
+We use `expect` in the same way as `unwrap`: to return the file handle or call
+the `panic!` macro. The error message that `expect` uses in its call to
+`panic!` will be the parameter that we pass to `expect` instead of the default
+`panic!` message that `unwrap` uses. Here’s what it looks like:
+
+```text
+thread 'main' panicked at 'Failed to open hello.txt: Error { repr: Os { code:
+2, message: "No such file or directory" } }',
+/stable-dist-rustc/build/src/libcore/result.rs:868
+```
+
+### Propagating Errors
+
+When writing a function whose implementation calls something that might fail,
+instead of handling the error within this function, you can choose to let your
+caller know about the error so they can decide what to do. This is known as
+*propagating* the error, and gives more control to the calling code where there
+might be more information or logic that dictates how the error should be
+handled than what you have available in the context of your code.
+
+For example, Listing 9-5 shows a function that reads a username from a file. If
+the file doesn’t exist or can’t be read, this function will return those errors
+to the code that called this function:
+
+```rust
+use std::io;
+use std::io::Read;
+use std::fs::File;
+
+fn read_username_from_file() -> Result {
+ let f = File::open("hello.txt");
+
+ let mut f = match f {
+ Ok(file) => file,
+ Err(e) => return Err(e),
+ };
+
+ let mut s = String::new();
+
+ match f.read_to_string(&mut s) {
+ Ok(_) => Ok(s),
+ Err(e) => Err(e),
+ }
+}
+```
+
+Listing 9-5: A function that returns errors to the
+calling code using `match`
+
+Let’s look at the return type of the function first: `Result`. This means that the function is returning a value of the type
+`Result` where the generic parameter `T` has been filled in with the
+concrete type `String`, and the generic type `E` has been filled in with the
+concrete type `io::Error`. If this function succeeds without any problems, the
+caller of this function will receive an `Ok` value that holds a `String` — the
+username that this function read from the file. If this function encounters any
+problems, the caller of this function will receive an `Err` value that holds an
+instance of `io::Error` that contains more information about what the problems
+were. We chose `io::Error` as the return type of this function because that
+happens to be the type of the error value returned from both of the operations
+we’re calling in this function’s body that might fail: the `File::open`
+function and the `read_to_string` method.
+
+The body of the function starts by calling the `File::open` function. Then we
+handle the `Result` value returned with a `match` similar to the `match` in
+Listing 9-3, only instead of calling `panic!` in the `Err` case, we return
+early from this function and pass the error value from `File::open` back to the
+caller as this function’s error value. If `File::open` succeeds, we store the
+file handle in the variable `f` and continue.
+
+Then we create a new `String` in variable `s` and call the `read_to_string`
+method on the file handle in `f` in order to read the contents of the file into
+`s`. The `read_to_string` method also returns a `Result` because it might fail,
+even though `File::open` succeeded. So we need another `match` to handle that
+`Result`: if `read_to_string` succeeds, then our function has succeeded, and we
+return the username from the file that’s now in `s` wrapped in an `Ok`. If
+`read_to_string` fails, we return the error value in the same way that we
+returned the error value in the `match` that handled the return value of
+`File::open`. We don’t need to explicitly say `return`, however, since this is
+the last expression in the function.
+
+The code that calls this code will then handle getting either an `Ok` value
+that contains a username or an `Err` value that contains an `io::Error`. We
+don’t know what the caller will do with those values. If they get an `Err`
+value, they could choose to call `panic!` and crash their program, use a
+default username, or look up the username from somewhere other than a file, for
+example. We don’t have enough information on what the caller is actually trying
+to do, so we propagate all the success or error information upwards for them to
+handle as they see fit.
+
+This pattern of propagating errors is so common in Rust that there is dedicated
+syntax to make this easier: `?`.
+
+### A Shortcut for Propagating Errors: `?`
+
+Listing 9-6 shows an implementation of `read_username_from_file` that has the
+same functionality as it had in Listing 9-5, but this implementation uses the
+question mark operator:
+
+```rust
+use std::io;
+use std::io::Read;
+use std::fs::File;
+
+fn read_username_from_file() -> Result {
+ let mut f = File::open("hello.txt")?;
+ let mut s = String::new();
+ f.read_to_string(&mut s)?;
+ Ok(s)
+}
+```
+
+Listing 9-6: A function that returns errors to the
+calling code using `?`
+
+The `?` placed after a `Result` value is defined to work the exact same way as
+the `match` expressions we defined to handle the `Result` values in Listing
+9-5. If the value of the `Result` is an `Ok`, the value inside the `Ok` will
+get returned from this expression and the program will continue. If the value
+is an `Err`, the value inside the `Err` will be returned from the whole
+function as if we had used the `return` keyword so that the error value gets
+propagated to the caller.
+
+In the context of Listing 9-6, the `?` at the end of the `File::open` call will
+return the value inside an `Ok` to the variable `f`. If an error occurs, `?`
+will return early out of the whole function and give any `Err` value to our
+caller. The same thing applies to the `?` at the end of the `read_to_string`
+call.
+
+The `?` eliminates a lot of boilerplate and makes this function’s
+implementation simpler. We could even shorten this code further by chaining
+method calls immediately after the `?`:
+
+```rust
+use std::io;
+use std::io::Read;
+use std::fs::File;
+
+fn read_username_from_file() -> Result {
+ let mut s = String::new();
+
+ File::open("hello.txt")?.read_to_string(&mut s)?;
+
+ Ok(s)
+}
+```
+
+We’ve moved the creation of the new `String` in `s` to the beginning of the
+function; that part hasn’t changed. Instead of creating a variable `f`, we’ve
+chained the call to `read_to_string` directly onto the result of
+`File::open("hello.txt")?`. We still have a `?` at the end of the
+`read_to_string` call, and we still return an `Ok` value containing the
+username in `s` when both `File::open` and `read_to_string` succeed rather than
+returning errors. The functionality is again the same as in Listing 9-5 and
+Listing 9-6, this is just a different, more ergonomic way to write it.
+
+### `?` Can Only Be Used in Functions That Return `Result`
+
+The `?` can only be used in functions that have a return type of `Result`,
+since it is defined to work in exactly the same way as the `match` expression
+we defined in Listing 9-5. The part of the `match` that requires a return type
+of `Result` is `return Err(e)`, so the return type of the function must be a
+`Result` to be compatible with this `return`.
+
+Let’s look at what happens if we use `?` in the `main` function, which you’ll
+recall has a return type of `()`:
+
+```rust,ignore
+use std::fs::File;
+
+fn main() {
+ let f = File::open("hello.txt")?;
+}
+```
+
+
+
+When we compile this, we get the following error message:
+
+```text
+error[E0308]: mismatched types
+ -->
+ |
+3 | let f = File::open("hello.txt")?;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum
+`std::result::Result`
+ |
+ = note: expected type `()`
+ = note: found type `std::result::Result<_, _>`
+```
+
+This error is pointing out that we have mismatched types: the `main` function
+has a return type of `()`, but the `?` might return a `Result`. In functions
+that don’t return `Result`, when you call other functions that return `Result`,
+you’ll need to use a `match` or one of the `Result` methods to handle it,
+instead of using `?` to potentially propagate the error to the caller.
+
+Now that we’ve discussed the details of calling `panic!` or returning `Result`,
+let’s return to the topic of how to decide which is appropriate to use in which
+cases.
diff --git a/trpl-2nd-edition/ch09-03-to-panic-or-not-to-panic.md b/trpl-2nd-edition/ch09-03-to-panic-or-not-to-panic.md
new file mode 100644
index 0000000..f203a12
--- /dev/null
+++ b/trpl-2nd-edition/ch09-03-to-panic-or-not-to-panic.md
@@ -0,0 +1,246 @@
+## To `panic!` or Not To `panic!`
+
+So how do you decide when you should `panic!` and when you should return
+`Result`? When code panics, there’s no way to recover. You could choose to call
+`panic!` for any error situation, whether there’s a possible way to recover or
+not, but then you’re making the decision for your callers that a situation is
+unrecoverable. When you choose to return a `Result` value, you give your caller
+options, rather than making the decision for them. They could choose to attempt
+to recover in a way that’s appropriate for their situation, or they could
+decide that actually, an `Err` value in this case is unrecoverable, so they can
+call `panic!` and turn your recoverable error into an unrecoverable one.
+Therefore, returning `Result` is a good default choice when you’re defining a
+function that might fail.
+
+There are a few situations in which it’s more appropriate to write code that
+panics instead of returning a `Result`, but they are less common. Let’s discuss
+why it’s appropriate to panic in examples, prototype code, and tests, then
+situations where you as a human can know a method won’t fail that the compiler
+can’t reason about, and conclude with some general guidelines on how to decide
+whether to panic in library code.
+
+### Examples, Prototype Code, and Tests: Perfectly Fine to Panic
+
+When you’re writing an example to illustrate some concept, having robust error
+handling code in the example as well can make the example less clear. In
+examples, it’s understood that a call to a method like `unwrap` that could
+`panic!` is meant as a placeholder for the way that you’d actually like your
+application to handle errors, which can differ based on what the rest of your
+code is doing.
+
+Similarly, the `unwrap` and `expect` methods are very handy when prototyping,
+before you’re ready to decide how to handle errors. They leave clear markers in
+your code for when you’re ready to make your program more robust.
+
+If a method call fails in a test, we’d want the whole test to fail, even if
+that method isn’t the functionality under test. Because `panic!` is how a test
+gets marked as a failure, calling `unwrap` or `expect` is exactly what makes
+sense to do.
+
+### Cases When You Have More Information Than The Compiler
+
+It would also be appropriate to call `unwrap` when you have some other logic
+that ensures the `Result` will have an `Ok` value, but the logic isn’t
+something the compiler understands. You’ll still have a `Result` value that you
+need to handle: whatever operation you’re calling still has the possibility of
+failing in general, even though it’s logically impossible in your particular
+situation. If you can ensure by manually inspecting the code that you’ll never
+have an `Err` variant, it is perfectly acceptable to call `unwrap`. Here’s an
+example:
+
+```rust
+use std::net::IpAddr;
+
+let home = "127.0.0.1".parse::().unwrap();
+```
+
+We’re creating an `IpAddr` instance by parsing a hardcoded string. We can see
+that `127.0.0.1` is a valid IP address, so it’s acceptable to use `unwrap`
+here. However, having a hardcoded, valid string doesn’t change the return type
+of the `parse` method: we still get a `Result` value, and the compiler will
+still make us handle the `Result` as if the `Err` variant is still a
+possibility since the compiler isn’t smart enough to see that this string is
+always a valid IP address. If the IP address string came from a user instead of
+being hardcoded into the program, and therefore *did* have a possibility of
+failure, we’d definitely want to handle the `Result` in a more robust way
+instead.
+
+### Guidelines for Error Handling
+
+It’s advisable to have your code `panic!` when it’s possible that you could end
+up in a bad state—in this context, bad state is when some assumption,
+guarantee, contract, or invariant has been broken, such as when invalid values,
+contradictory values, or missing values are passed to your code—plus one or
+more of the following:
+
+* The bad state is not something that’s *expected* to happen occasionally
+* Your code after this point needs to rely on not being in this bad state
+* There’s not a good way to encode this information in the types you use
+
+If someone calls your code and passes in values that don’t make sense, the best
+thing might be to `panic!` and alert the person using your library to the bug
+in their code so that they can fix it during development. Similarly, `panic!`
+is often appropriate if you’re calling external code that is out of your
+control, and it returns an invalid state that you have no way of fixing.
+
+When a bad state is reached, but it’s expected to happen no matter how well you
+write your code, it’s still more appropriate to return a `Result` rather than
+calling `panic!`. Examples of this include a parser being given malformed data,
+or an HTTP request returning a status that indicates you have hit a rate limit.
+In these cases, you should indicate that failure is an expected possibility by
+returning a `Result` in order to propagate these bad states upwards so that the
+caller can decide how they would like to handle the problem. To `panic!`
+wouldn’t be the best way to handle these cases.
+
+When your code performs operations on values, your code should verify the
+values are valid first, and `panic!` if the values aren’t valid. This is mostly
+for safety reasons: attempting to operate on invalid data can expose your code
+to vulnerabilities. This is the main reason that the standard library will
+`panic!` if you attempt an out-of-bounds array access: trying to access memory
+that doesn’t belong to the current data structure is a common security problem.
+Functions often have *contracts*: their behavior is only guaranteed if the
+inputs meet particular requirements. Panicking when the contract is violated
+makes sense because a contract violation always indicates a caller-side bug,
+and it is not a kind of error you want callers to have to explicitly handle. In
+fact, there’s no reasonable way for calling code to recover: the calling
+*programmers* need to fix the code. Contracts for a function, especially when a
+violation will cause a panic, should be explained in the API documentation for
+the function.
+
+Having lots of error checks in all of your functions would be verbose and
+annoying, though. Luckily, you can use Rust’s type system (and thus the type
+checking the compiler does) to do a lot of the checks for you. If your function
+has a particular type as a parameter, you can proceed with your code’s logic
+knowing that the compiler has already ensured you have a valid value. For
+example, if you have a type rather than an `Option`, your program expects to
+have *something* rather than *nothing*. Your code then doesn’t have to handle
+two cases for the `Some` and `None` variants, it will only have one case for
+definitely having a value. Code trying to pass nothing to your function won’t
+even compile, so your function doesn’t have to check for that case at runtime.
+Another example is using an unsigned integer type like `u32`, which ensures the
+parameter is never negative.
+
+### Creating Custom Types for Validation
+
+Let’s take the idea of using Rust’s type system to ensure we have a valid value
+one step further, and look at creating a custom type for validation. Recall the
+guessing game in Chapter 2, where our code asked the user to guess a number
+between 1 and 100. We actually never validated that the user’s guess was
+between those numbers before checking it against our secret number, only that
+it was positive. In this case, the consequences were not very dire: our output
+of “Too high” or “Too low” would still be correct. It would be a useful
+enhancement to guide the user towards valid guesses, though, and have different
+behavior when a user guesses a number that’s out of range versus when a user
+types, for example, letters instead.
+
+One way to do this would be to parse the guess as an `i32` instead of only a
+`u32`, to allow potentially negative numbers, then add a check for the number
+being in range:
+
+```rust,ignore
+loop {
+ // snip
+
+ let guess: i32 = match guess.trim().parse() {
+ Ok(num) => num,
+ Err(_) => continue,
+ };
+
+ if guess < 1 || guess > 100 {
+ println!("The secret number will be between 1 and 100.");
+ continue;
+ }
+
+ match guess.cmp(&secret_number) {
+ // snip
+}
+```
+
+The `if` expression checks to see if our value is out of range, tells the user
+about the problem, and calls `continue` to start the next iteration of the loop
+and ask for another guess. After the `if` expression, we can proceed with the
+comparisons between `guess` and the secret number knowing that `guess` is
+between 1 and 100.
+
+However, this is not an ideal solution: if it was absolutely critical that the
+program only operated on values between 1 and 100, and it had many functions
+with this requirement, it would be tedious (and potentially impact performance)
+to have a check like this in every function.
+
+Instead, we can make a new type and put the validations in a function to create
+an instance of the type rather than repeating the validations everywhere. That
+way, it’s safe for functions to use the new type in their signatures and
+confidently use the values they receive. Listing 9-8 shows one way to define a
+`Guess` type that will only create an instance of `Guess` if the `new` function
+receives a value between 1 and 100:
+
+```rust
+struct Guess {
+ value: u32,
+}
+
+impl Guess {
+ pub fn new(value: u32) -> Guess {
+ if value < 1 || value > 100 {
+ panic!("Guess value must be between 1 and 100, got {}.", value);
+ }
+
+ Guess {
+ value: value,
+ }
+ }
+
+ pub fn value(&self) -> u32 {
+ self.value
+ }
+}
+```
+
+Listing 9-8: A `Guess` type that will only continue with
+values between 1 and 100
+
+First, we define a struct named `Guess` that has a field named `value` that
+holds a `u32`. This is where the number will be stored.
+
+Then we implement an associated function named `new` on `Guess` that creates
+instances of `Guess` values. The `new` function is defined to have one
+parameter named `value` of type `u32` and to return a `Guess`. The code in the
+body of the `new` function tests `value` to make sure it is between 1 and 100.
+If `value` doesn’t pass this test, we call `panic!`, which will alert the
+programmer who is calling this code that they have a bug they need to fix,
+since creating a `Guess` with a `value` outside this range would violate the
+contract that `Guess::new` is relying on. The conditions in which `Guess::new`
+might panic should be discussed in its public-facing API documentation; we’ll
+cover documentation conventions around indicating the possibility of a `panic!`
+in the API documentation that you create in Chapter 14. If `value` does pass
+the test, we create a new `Guess` with its `value` field set to the `value`
+parameter and return the `Guess`.
+
+Next, we implement a method named `value` that borrows `self`, doesn’t have any
+other parameters, and returns a `u32`. This is a kind of method sometimes
+called a *getter*, since its purpose is to get some data from its fields and
+return it. This public method is necessary because the `value` field of the
+`Guess` struct is private. It’s important that the `value` field is private so
+that code using the `Guess` struct is not allowed to set `value` directly:
+callers *must* use the `Guess::new` function to create an instance of `Guess`,
+which ensures there’s no way for a `Guess` to have a `value` that hasn’t been
+checked by the conditions in the `Guess::new` function.
+
+A function that has a parameter or returns only numbers between 1 and 100 could
+then declare in its signature that it takes or returns a `Guess` rather than a
+`u32`, and wouldn’t need to do any additional checks in its body.
+
+## Summary
+
+Rust’s error handling features are designed to help you write more robust code.
+The `panic!` macro signals that your program is in a state it can’t handle, and
+lets you tell the process to stop instead of trying to proceed with invalid or
+incorrect values. The `Result` enum uses Rust’s type system to indicate that
+operations might fail in a way that your code could recover from. You can use
+`Result` to tell code that calls your code that it needs to handle potential
+success or failure as well. Using `panic!` and `Result` in the appropriate
+situations will make your code more reliable in the face of inevitable problems.
+
+Now that we’ve seen useful ways that the standard library uses generics with
+the `Option` and `Result` enums, let’s talk about how generics work and how you
+can make use of them in your code.
diff --git a/trpl-2nd-edition/ch10-00-generics.md b/trpl-2nd-edition/ch10-00-generics.md
new file mode 100644
index 0000000..0c91bb4
--- /dev/null
+++ b/trpl-2nd-edition/ch10-00-generics.md
@@ -0,0 +1,188 @@
+# Generic Types, Traits, and Lifetimes
+
+Every programming language has tools to deal effectively with duplication of
+concepts; in Rust, one of those tools is *generics*. Generics are abstract
+stand-ins for concrete types or other properties. We can express properties of
+generics, such as their behavior or how they relate to other generics, without
+needing to know when we're writing and compiling the code what will actually be
+in their place.
+
+In the same way that a function takes parameters whose value we don't know in
+order to write code once that will be run on multiple concrete values, we can
+write functions that take parameters of some generic type instead of a concrete
+type like `i32` or `String`. We've already used generics in Chapter 6 with
+`Option`, Chapter 8 with `Vec` and `HashMap`, and Chapter 9 with
+`Result`. In this chapter, we'll explore how to define our own types,
+functions, and methods with generics!
+
+First, we're going to review the mechanics of extracting a function that
+reduces code duplication. Then we'll use the same mechanics to make a generic
+function out of two functions that only differ in the types of their
+parameters. We'll go over using generic types in struct and enum definitions
+too.
+
+After that, we'll discuss *traits*, which are a way to define behavior in a
+generic way. Traits can be combined with generic types in order to constrain a
+generic type to those types that have a particular behavior, rather than any
+type at all.
+
+Finally, we'll discuss *lifetimes*, which are a kind of generic that let us
+give the compiler information about how references are related to each other.
+Lifetimes are the feature in Rust that allow us to borrow values in many
+situations and still have the compiler check that references will be valid.
+
+## Removing Duplication by Extracting a Function
+
+Before getting into generics syntax, let's first review a technique for dealing
+with duplication that doesn't use generic types: extracting a function. Once
+that's fresh in our minds, we'll use the same mechanics with generics to
+extract a generic function! In the same way that you recognize duplicated code
+to extract into a function, you'll start to recognize duplicated code that can
+use generics.
+
+Consider a small program that finds the largest number in a list, shown in
+Listing 10-1:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let numbers = vec![34, 50, 25, 100, 65];
+
+ let mut largest = numbers[0];
+
+ for number in numbers {
+ if number > largest {
+ largest = number;
+ }
+ }
+
+ println!("The largest number is {}", largest);
+# assert_eq!(largest, 100);
+}
+```
+
+Listing 10-1: Code to find the largest number in a list
+of numbers
+
+This code takes a list of integers, stored here in the variable `numbers`. It
+puts the first item in the list in a variable named `largest`. Then it iterates
+through all the numbers in the list, and if the current value is greater than
+the number stored in `largest`, it replaces the value in `largest`. If the
+current value is smaller than the largest value seen so far, `largest` is not
+changed. When all the items in the list have been considered, `largest` will
+hold the largest value, which in this case is 100.
+
+If we needed to find the largest number in two different lists of numbers, we
+could duplicate the code in Listing 10-1 and have the same logic exist in two
+places in the program, as in Listing 10-2:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let numbers = vec![34, 50, 25, 100, 65];
+
+ let mut largest = numbers[0];
+
+ for number in numbers {
+ if number > largest {
+ largest = number;
+ }
+ }
+
+ println!("The largest number is {}", largest);
+
+ let numbers = vec![102, 34, 6000, 89, 54, 2, 43, 8];
+
+ let mut largest = numbers[0];
+
+ for number in numbers {
+ if number > largest {
+ largest = number;
+ }
+ }
+
+ println!("The largest number is {}", largest);
+}
+```
+
+Listing 10-2: Code to find the largest number in *two*
+lists of numbers
+
+While this code works, duplicating code is tedious and error-prone, and means
+we have multiple places to update the logic if we need to change it.
+
+
+
+
+To eliminate this duplication, we can create an abstraction, which in this case
+will be in the form of a function that operates on any list of integers given
+to the function in a parameter. This will increase the clarity of our code and
+let us communicate and reason about the concept of finding the largest number
+in a list independently of the specific places this concept is used.
+
+In the program in Listing 10-3, we've extracted the code that finds the largest
+number into a function named `largest`. This program can find the largest
+number in two different lists of numbers, but the code from Listing 10-1 only
+exists in one spot:
+
+Filename: src/main.rs
+
+```rust
+fn largest(list: &[i32]) -> i32 {
+ let mut largest = list[0];
+
+ for &item in list.iter() {
+ if item > largest {
+ largest = item;
+ }
+ }
+
+ largest
+}
+
+fn main() {
+ let numbers = vec![34, 50, 25, 100, 65];
+
+ let result = largest(&numbers);
+ println!("The largest number is {}", result);
+# assert_eq!(result, 100);
+
+ let numbers = vec![102, 34, 6000, 89, 54, 2, 43, 8];
+
+ let result = largest(&numbers);
+ println!("The largest number is {}", result);
+# assert_eq!(result, 6000);
+}
+```
+
+Listing 10-3: Abstracted code to find the largest number
+in two lists
+
+The function has a parameter, `list`, which represents any concrete slice of
+`i32` values that we might pass into the function. The code in the function
+definition operates on the `list` representation of any `&[i32]`. When we call
+the `largest` function, the code actually runs on the specific values that we
+pass in.
+
+The mechanics we went through to get from Listing 10-2 to Listing 10-3 were
+these steps:
+
+1. We noticed there was duplicate code.
+2. We extracted the duplicate code into the body of the function, and specified
+ the inputs and return values of that code in the function signature.
+3. We replaced the two concrete places that had the duplicated code to call the
+ function instead.
+
+We can use these same steps with generics to reduce code duplication in
+different ways in different scenarios. In the same way that the function body
+is now operating on an abstract `list` instead of concrete values, code using
+generics will operate on abstract types. The concepts powering generics are the
+same concepts you already know that power functions, just applied in different
+ways.
+
+What if we had two functions, one that found the largest item in a slice of
+`i32` values and one that found the largest item in a slice of `char` values?
+How would we get rid of that duplication? Let's find out!
diff --git a/trpl-2nd-edition/ch10-01-syntax.md b/trpl-2nd-edition/ch10-01-syntax.md
new file mode 100644
index 0000000..85ff480
--- /dev/null
+++ b/trpl-2nd-edition/ch10-01-syntax.md
@@ -0,0 +1,448 @@
+## Generic Data Types
+
+Using generics where we usually place types, like in function signatures or
+structs, lets us create definitions that we can use for many different concrete
+data types. Let's take a look at how to define functions, structs, enums, and
+methods using generics, and at the end of this section we'll discuss the
+performance of code using generics.
+
+### Using Generic Data Types in Function Definitions
+
+We can define functions that use generics in the signature of the function
+where the data types of the parameters and return value go. In this way, the
+code we write can be more flexible and provide more functionality to callers of
+our function, while not introducing code duplication.
+
+Continuing with our `largest` function, Listing 10-4 shows two functions
+providing the same functionality to find the largest value in a slice. The
+first function is the one we extracted in Listing 10-3 that finds the largest
+`i32` in a slice. The second function finds the largest `char` in a slice:
+
+Filename: src/main.rs
+
+```rust
+fn largest_i32(list: &[i32]) -> i32 {
+ let mut largest = list[0];
+
+ for &item in list.iter() {
+ if item > largest {
+ largest = item;
+ }
+ }
+
+ largest
+}
+
+fn largest_char(list: &[char]) -> char {
+ let mut largest = list[0];
+
+ for &item in list.iter() {
+ if item > largest {
+ largest = item;
+ }
+ }
+
+ largest
+}
+
+fn main() {
+ let numbers = vec![34, 50, 25, 100, 65];
+
+ let result = largest_i32(&numbers);
+ println!("The largest number is {}", result);
+# assert_eq!(result, 100);
+
+ let chars = vec!['y', 'm', 'a', 'q'];
+
+ let result = largest_char(&chars);
+ println!("The largest char is {}", result);
+# assert_eq!(result, 'y');
+}
+```
+
+Listing 10-4: Two functions that differ only in their
+names and the types in their signatures
+
+Here, the functions `largest_i32` and `largest_char` have the exact same body,
+so it would be nice if we could turn these two functions into one and get rid
+of the duplication. Luckily, we can do that by introducing a generic type
+parameter!
+
+To parameterize the types in the signature of the one function we're going to
+define, we need to create a name for the type parameter, just like how we give
+names for the value parameters to a function. We're going to choose the name
+`T`. Any identifier can be used as a type parameter name, but we're choosing
+`T` because Rust's type naming convention is CamelCase. Generic type parameter
+names also tend to be short by convention, often just one letter. Short for
+"type", `T` is the default choice of most Rust programmers.
+
+When we use a parameter in the body of the function, we have to declare the
+parameter in the signature so that the compiler knows what that name in the
+body means. Similarly, when we use a type parameter name in a function
+signature, we have to declare the type parameter name before we use it. Type
+name declarations go in angle brackets between the name of the function and the
+parameter list.
+
+The function signature of the generic `largest` function we're going to define
+will look like this:
+
+```rust,ignore
+fn largest(list: &[T]) -> T {
+```
+
+We would read this as: the function `largest` is generic over some type `T`. It
+has one parameter named `list`, and the type of `list` is a slice of values of
+type `T`. The `largest` function will return a value of the same type `T`.
+
+Listing 10-5 shows the unified `largest` function definition using the generic
+data type in its signature, and shows how we'll be able to call `largest` with
+either a slice of `i32` values or `char` values. Note that this code won't
+compile yet!
+
+Filename: src/main.rs
+
+```rust,ignore
+fn largest(list: &[T]) -> T {
+ let mut largest = list[0];
+
+ for &item in list.iter() {
+ if item > largest {
+ largest = item;
+ }
+ }
+
+ largest
+}
+
+fn main() {
+ let numbers = vec![34, 50, 25, 100, 65];
+
+ let result = largest(&numbers);
+ println!("The largest number is {}", result);
+
+ let chars = vec!['y', 'm', 'a', 'q'];
+
+ let result = largest(&chars);
+ println!("The largest char is {}", result);
+}
+```
+
+Listing 10-5: A definition of the `largest` function that
+uses generic type parameters but doesn't compile yet
+
+If we try to compile this code right now, we'll get this error:
+
+```text
+error[E0369]: binary operation `>` cannot be applied to type `T`
+ |
+5 | if item > largest {
+ | ^^^^
+ |
+note: an implementation of `std::cmp::PartialOrd` might be missing for `T`
+```
+
+The note mentions `std::cmp::PartialOrd`, which is a *trait*. We're going to
+talk about traits in the next section, but briefly, what this error is saying
+is that the body of `largest` won't work for all possible types that `T` could
+be; since we want to compare values of type `T` in the body, we can only use
+types that know how to be ordered. The standard library has defined the trait
+`std::cmp::PartialOrd` that types can implement to enable comparisons. We'll
+come back to traits and how to specify that a generic type has a particular
+trait in the next section, but let's set this example aside for a moment and
+explore other places we can use generic type parameters first.
+
+
+
+### Using Generic Data Types in Struct Definitions
+
+We can define structs to use a generic type parameter in one or more of the
+struct's fields with the `<>` syntax too. Listing 10-6 shows the definition and
+use of a `Point` struct that can hold `x` and `y` coordinate values of any type:
+
+Filename: src/main.rs
+
+```rust
+struct Point {
+ x: T,
+ y: T,
+}
+
+fn main() {
+ let integer = Point { x: 5, y: 10 };
+ let float = Point { x: 1.0, y: 4.0 };
+}
+```
+
+Listing 10-6: A `Point` struct that holds `x` and `y`
+values of type `T`
+
+The syntax is similar to using generics in function definitions. First, we have
+to declare the name of the type parameter within angle brackets just after the
+name of the struct. Then we can use the generic type in the struct definition
+where we would specify concrete data types.
+
+Note that because we've only used one generic type in the definition of
+`Point`, what we're saying is that the `Point` struct is generic over some type
+`T`, and the fields `x` and `y` are *both* that same type, whatever it ends up
+being. If we try to create an instance of a `Point` that has values of
+different types, as in Listing 10-7, our code won't compile:
+
+Filename: src/main.rs
+
+```rust,ignore
+struct Point {
+ x: T,
+ y: T,
+}
+
+fn main() {
+ let wont_work = Point { x: 5, y: 4.0 };
+}
+```
+
+Listing 10-7: The fields `x` and `y` must be the same
+type because both have the same generic data type `T`
+
+If we try to compile this, we'll get the following error:
+
+```text
+error[E0308]: mismatched types
+ -->
+ |
+7 | let wont_work = Point { x: 5, y: 4.0 };
+ | ^^^ expected integral variable, found
+ floating-point variable
+ |
+ = note: expected type `{integer}`
+ = note: found type `{float}`
+```
+
+When we assigned the integer value 5 to `x`, the compiler then knows for this
+instance of `Point` that the generic type `T` will be an integer. Then when we
+specified 4.0 for `y`, which is defined to have the same type as `x`, we get a
+type mismatch error.
+
+If we wanted to define a `Point` struct where `x` and `y` could have different
+types but still have those types be generic, we can use multiple generic type
+parameters. In listing 10-8, we've changed the definition of `Point` to be
+generic over types `T` and `U`. The field `x` is of type `T`, and the field `y`
+is of type `U`:
+
+Filename: src/main.rs
+
+```rust
+struct Point {
+ x: T,
+ y: U,
+}
+
+fn main() {
+ let both_integer = Point { x: 5, y: 10 };
+ let both_float = Point { x: 1.0, y: 4.0 };
+ let integer_and_float = Point { x: 5, y: 4.0 };
+}
+```
+
+Listing 10-8: A `Point` generic over two types so that
+`x` and `y` may be values of different types
+
+Now all of these instances of `Point` are allowed! You can use as many generic
+type parameters in a definition as you want, but using more than a few gets
+hard to read and understand. If you get to a point of needing lots of generic
+types, it's probably a sign that your code could use some restructuring to be
+separated into smaller pieces.
+
+### Using Generic Data Types in Enum Definitions
+
+Similarly to structs, enums can be defined to hold generic data types in their
+variants. We used the `Option` enum provided by the standard library in
+Chapter 6, and now its definition should make more sense. Let's take another
+look:
+
+```rust
+enum Option {
+ Some(T),
+ None,
+}
+```
+
+In other words, `Option` is an enum generic in type `T`. It has two
+variants: `Some`, which holds one value of type `T`, and a `None` variant that
+doesn't hold any value. The standard library only has to have this one
+definition to support the creation of values of this enum that have any
+concrete type. The idea of "an optional value" is a more abstract concept than
+one specific type, and Rust lets us express this abstract concept without lots
+of duplication.
+
+Enums can use multiple generic types as well. The definition of the `Result`
+enum that we used in Chapter 9 is one example:
+
+```rust
+enum Result {
+ Ok(T),
+ Err(E),
+}
+```
+
+The `Result` enum is generic over two types, `T` and `E`. `Result` has two
+variants: `Ok`, which holds a value of type `T`, and `Err`, which holds a value
+of type `E`. This definition makes it convenient to use the `Result` enum
+anywhere we have an operation that might succeed (and return a value of some
+type `T`) or fail (and return an error of some type `E`). Recall Listing 9-2
+when we opened a file: in that case, `T` was filled in with the type
+`std::fs::File` when the file was opened successfully and `E` was filled in
+with the type `std::io::Error` when there were problems opening the file.
+
+When you recognize situations in your code with multiple struct or enum
+definitions that differ only in the types of the values they hold, you can
+remove the duplication by using the same process we used with the function
+definitions to introduce generic types instead.
+
+### Using Generic Data Types in Method Definitions
+
+Like we did in Chapter 5, we can implement methods on structs and enums that
+have generic types in their definitions. Listing 10-9 shows the `Point`
+struct we defined in Listing 10-6. We've then defined a method named `x` on
+`Point` that returns a reference to the data in the field `x`:
+
+Filename: src/main.rs
+
+```rust
+struct Point {
+ x: T,
+ y: T,
+}
+
+impl Point {
+ fn x(&self) -> &T {
+ &self.x
+ }
+}
+
+fn main() {
+ let p = Point { x: 5, y: 10 };
+
+ println!("p.x = {}", p.x());
+}
+```
+
+Listing 10-9: Implementing a method named `x` on the
+`Point` struct that will return a reference to the `x` field, which is of
+type `T`.
+
+Note that we have to declare `T` just after `impl`, so that we can use it when
+we specify that we're implementing methods on the type `Point`.
+
+Generic type parameters in a struct definition aren't always the same generic
+type parameters you want to use in that struct's method signatures. Listing
+10-10 defines a method `mixup` on the `Point` struct from Listing 10-8.
+The method takes another `Point` as a parameter, which might have different
+types than the `self` `Point` that we're calling `mixup` on. The method creates
+a new `Point` instance that has the `x` value from the `self` `Point` (which is
+of type `T`) and the `y` value from the passed-in `Point` (which is of type
+`W`):
+
+Filename: src/main.rs
+
+```rust
+struct Point {
+ x: T,
+ y: U,
+}
+
+impl Point {
+ fn mixup(self, other: Point) -> Point {
+ Point {
+ x: self.x,
+ y: other.y,
+ }
+ }
+}
+
+fn main() {
+ let p1 = Point { x: 5, y: 10.4 };
+ let p2 = Point { x: "Hello", y: 'c'};
+
+ let p3 = p1.mixup(p2);
+
+ println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
+}
+```
+
+Listing 10-10: Methods that use different generic types
+than their struct's definition
+
+In `main`, we've defined a `Point` that has an `i32` for `x` (with value `5`)
+and an `f64` for `y` (with value `10.4`). `p2` is a `Point` that has a string
+slice for `x` (with value `"Hello"`) and a `char` for `y` (with value `c`).
+Calling `mixup` on `p1` with the argument `p2` gives us `p3`, which will have
+an `i32` for `x`, since `x` came from `p1`. `p3` will have a `char` for `y`,
+since `y` came from `p2`. The `println!` will print `p3.x = 5, p3.y = c`.
+
+Note that the generic parameters `T` and `U` are declared after `impl`, since
+they go with the struct definition. The generic parameters `V` and `W` are
+declared after `fn mixup`, since they are only relevant to the method.
+
+### Performance of Code Using Generics
+
+You may have been reading this section and wondering if there's a run-time cost
+to using generic type parameters. Good news: the way that Rust has implemented
+generics means that your code will not run any slower than if you had specified
+concrete types instead of generic type parameters!
+
+Rust accomplishes this by performing *monomorphization* of code using generics
+at compile time. Monomorphization is the process of turning generic code into
+specific code with the concrete types that are actually used filled in.
+
+What the compiler does is the opposite of the steps that we performed to create
+the generic function in Listing 10-5. The compiler looks at all the places that
+generic code is called and generates code for the concrete types that the
+generic code is called with.
+
+Let's work through an example that uses the standard library's `Option` enum:
+
+```rust
+let integer = Some(5);
+let float = Some(5.0);
+```
+
+When Rust compiles this code, it will perform monomorphization. The compiler
+will read the values that have been passed to `Option` and see that we have two
+kinds of `Option`: one is `i32`, and one is `f64`. As such, it will expand
+the generic definition of `Option` into `Option_i32` and `Option_f64`,
+thereby replacing the generic definition with the specific ones.
+
+The monomorphized version of our code that the compiler generates looks like
+this, with the uses of the generic `Option` replaced with the specific
+definitions created by the compiler:
+
+Filename: src/main.rs
+
+```rust
+enum Option_i32 {
+ Some(i32),
+ None,
+}
+
+enum Option_f64 {
+ Some(f64),
+ None,
+}
+
+fn main() {
+ let integer = Option_i32::Some(5);
+ let float = Option_f64::Some(5.0);
+}
+```
+
+We can write the non-duplicated code using generics, and Rust will compile that
+into code that specifies the type in each instance. That means we pay no
+runtime cost for using generics; when the code runs, it performs just like it
+would if we had duplicated each particular definition by hand. The process of
+monomorphization is what makes Rust's generics extremely efficient at runtime.
diff --git a/trpl-2nd-edition/ch10-02-traits.md b/trpl-2nd-edition/ch10-02-traits.md
new file mode 100644
index 0000000..93c083c
--- /dev/null
+++ b/trpl-2nd-edition/ch10-02-traits.md
@@ -0,0 +1,474 @@
+## Traits: Defining Shared Behavior
+
+Traits allow us to use another kind of abstraction: they let us abstract over
+behavior that types can have in common. A *trait* tells the Rust compiler about
+functionality a particular type has and might share with other types. In
+situations where we use generic type parameters, we can use *trait bounds* to
+specify, at compile time, that the generic type may be any type that implements
+a trait and therefore has the behavior we want to use in that situation.
+
+> Note: *Traits* are similar to a feature often called 'interfaces' in other
+> languages, though with some differences.
+
+### Defining a Trait
+
+The behavior of a type consists of the methods we can call on that type.
+Different types share the same behavior if we can call the same methods on all
+of those types. Trait definitions are a way to group method signatures together
+in order to define a set of behaviors necessary to accomplish some purpose.
+
+For example, say we have multiple structs that hold various kinds and amounts
+of text: a `NewsArticle` struct that holds a news story filed in a particular
+place in the world, and a `Tweet` that can have at most 140 characters in its
+content along with metadata like whether it was a retweet or a reply to another
+tweet.
+
+We want to make a media aggregator library that can display summaries of data
+that might be stored in a `NewsArticle` or `Tweet` instance. The behavior we
+need each struct to have is that it's able to be summarized, and that we can
+ask for that summary by calling a `summary` method on an instance. Listing
+10-11 shows the definition of a `Summarizable` trait that expresses this
+concept:
+
+Filename: lib.rs
+
+```rust
+pub trait Summarizable {
+ fn summary(&self) -> String;
+}
+```
+
+Listing 10-11: Definition of a `Summarizable` trait that
+consists of the behavior provided by a `summary` method
+
+We declare a trait with the `trait` keyword, then the trait's name, in this
+case `Summarizable`. Inside curly braces we declare the method signatures that
+describe the behaviors that types that implement this trait will need to have,
+in this case `fn summary(&self) -> String`. After the method signature, instead
+of providing an implementation within curly braces, we put a semicolon. Each
+type that implements this trait must then provide its own custom behavior for
+the body of the method, but the compiler will enforce that any type that has
+the `Summarizable` trait will have the method `summary` defined for it with
+this signature exactly.
+
+A trait can have multiple methods in its body, with the method signatures
+listed one per line and each line ending in a semicolon.
+
+### Implementing a Trait on a Type
+
+Now that we've defined the `Summarizable` trait, we can implement it on the
+types in our media aggregator that we want to have this behavior. Listing 10-12
+shows an implementation of the `Summarizable` trait on the `NewsArticle` struct
+that uses the headline, the author, and the location to create the return value
+of `summary`. For the `Tweet` struct, we've chosen to define `summary` as the
+username followed by the whole text of the tweet, assuming that tweet content
+is already limited to 140 characters.
+
+Filename: lib.rs
+
+```rust
+# pub trait Summarizable {
+# fn summary(&self) -> String;
+# }
+#
+pub struct NewsArticle {
+ pub headline: String,
+ pub location: String,
+ pub author: String,
+ pub content: String,
+}
+
+impl Summarizable for NewsArticle {
+ fn summary(&self) -> String {
+ format!("{}, by {} ({})", self.headline, self.author, self.location)
+ }
+}
+
+pub struct Tweet {
+ pub username: String,
+ pub content: String,
+ pub reply: bool,
+ pub retweet: bool,
+}
+
+impl Summarizable for Tweet {
+ fn summary(&self) -> String {
+ format!("{}: {}", self.username, self.content)
+ }
+}
+```
+
+Listing 10-12: Implementing the `Summarizable` trait on
+the `NewsArticle` and `Tweet` types
+
+Implementing a trait on a type is similar to implementing methods that aren't
+related to a trait. The difference is after `impl`, we put the trait name that
+we want to implement, then say `for` and the name of the type that we want to
+implement the trait for. Within the `impl` block, we put the method signatures
+that the trait definition has defined, but instead of putting a semicolon after
+each signature, we put curly braces and fill in the method body with the
+specific behavior that we want the methods of the trait to have for the
+particular type.
+
+Once we've implemented the trait, we can call the methods on instances of
+`NewsArticle` and `Tweet` in the same manner that we call methods that aren't
+part of a trait:
+
+```rust,ignore
+let tweet = Tweet {
+ username: String::from("horse_ebooks"),
+ content: String::from("of course, as you probably already know, people"),
+ reply: false,
+ retweet: false,
+};
+
+println!("1 new tweet: {}", tweet.summary());
+```
+
+This will print `1 new tweet: horse_ebooks: of course, as you probably already
+know, people`.
+
+Note that because we've defined the `Summarizable` trait and the `NewsArticle`
+and `Tweet` types all in the same `lib.rs` in Listing 10-12, they're all in the
+same scope. If this `lib.rs` is for a crate we've called `aggregator`, and
+someone else wants to use our crate's functionality plus implement the
+`Summarizable` trait on their `WeatherForecast` struct, their code would need
+to import the `Summarizable` trait into their scope first before they could
+implement it, like in Listing 10-13:
+
+Filename: lib.rs
+
+```rust,ignore
+extern crate aggregator;
+
+use aggregator::Summarizable;
+
+struct WeatherForecast {
+ high_temp: f64,
+ low_temp: f64,
+ chance_of_precipitation: f64,
+}
+
+impl Summarizable for WeatherForecast {
+ fn summary(&self) -> String {
+ format!("The high will be {}, and the low will be {}. The chance of
+ precipitation is {}%.", self.high_temp, self.low_temp,
+ self.chance_of_precipitation)
+ }
+}
+```
+
+Listing 10-13: Bringing the `Summarizable` trait from our
+`aggregator` crate into scope in another crate
+
+This code also assumes `Summarizable` is a public trait, which it is because we
+put the `pub` keyword before `trait` in Listing 10-11.
+
+One restriction to note with trait implementations: we may implement a trait on
+a type as long as either the trait or the type are local to our crate. In other
+words, we aren't allowed to implement external traits on external types. We
+can't implement the `Display` trait on `Vec`, for example, since both `Display`
+and `Vec` are defined in the standard library. We are allowed to implement
+standard library traits like `Display` on a custom type like `Tweet` as part of
+our `aggregator` crate functionality. We could also implement `Summarizable` on
+`Vec` in our `aggregator` crate, since we've defined `Summarizable` there. This
+restriction is part of what's called the *orphan rule*, which you can look up
+if you're interested in type theory. Briefly, it's called the orphan rule
+because the parent type is not present. Without this rule, two crates could
+implement the same trait for the same type, and the two implementations would
+conflict: Rust wouldn't know which implementation to use. Because Rust enforces
+the orphan rule, other people's code can't break your code and vice versa.
+
+### Default Implementations
+
+Sometimes it's useful to have default behavior for some or all of the methods
+in a trait, instead of making every implementation on every type define custom
+behavior. When we implement the trait on a particular type, we can choose to
+keep or override each method's default behavior.
+
+Listing 10-14 shows how we could have chosen to specify a default string for
+the `summary` method of the `Summarize` trait instead of only choosing to only
+define the method signature like we did in Listing 10-11:
+
+Filename: lib.rs
+
+```rust
+pub trait Summarizable {
+ fn summary(&self) -> String {
+ String::from("(Read more...)")
+ }
+}
+```
+
+Listing 10-14: Definition of a `Summarizable` trait with
+a default implementation of the `summary` method
+
+If we wanted to use this default implementation to summarize instances of
+`NewsArticle` instead of defining a custom implementation like we did in
+Listing 10-12, we would specify an empty `impl` block:
+
+```rust,ignore
+impl Summarizable for NewsArticle {}
+```
+
+Even though we're no longer choosing to define the `summary` method on
+`NewsArticle` directly, since the `summary` method has a default implementation
+and we specified that `NewsArticle` implements the `Summarizable` trait, we can
+still call the `summary` method on an instance of `NewsArticle`:
+
+```rust,ignore
+let article = NewsArticle {
+ headline: String::from("Penguins win the Stanley Cup Championship!"),
+ location: String::from("Pittsburgh, PA, USA"),
+ author: String::from("Iceburgh"),
+ content: String::from("The Pittsburgh Penguins once again are the best
+ hockey team in the NHL."),
+};
+
+println!("New article available! {}", article.summary());
+```
+
+This code prints `New article available! (Read more...)`.
+
+Changing the `Summarizable` trait to have a default implementation for
+`summary` does not require us to change anything about the implementations of
+`Summarizable` on `Tweet` in Listing 10-12 or `WeatherForecast` in Listing
+10-13: the syntax for overriding a default implementation is exactly the same
+as the syntax for implementing a trait method that doesn't have a default
+implementation.
+
+Default implementations are allowed to call the other methods in the same
+trait, even if those other methods don't have a default implementation. In this
+way, a trait can provide a lot of useful functionality and only require
+implementers to specify a small part of it. We could choose to have the
+`Summarizable` trait also have an `author_summary` method whose implementation
+is required, then a `summary` method that has a default implementation that
+calls the `author_summary` method:
+
+```rust
+pub trait Summarizable {
+ fn author_summary(&self) -> String;
+
+ fn summary(&self) -> String {
+ format!("(Read more from {}...)", self.author_summary())
+ }
+}
+```
+
+In order to use this version of `Summarizable`, we're only required to define
+`author_summary` when we implement the trait on a type:
+
+```rust,ignore
+impl Summarizable for Tweet {
+ fn author_summary(&self) -> String {
+ format!("@{}", self.username)
+ }
+}
+```
+
+Once we define `author_summary`, we can call `summary` on instances of the
+`Tweet` struct, and the default implementation of `summary` will call the
+definition of `author_summary` that we've provided.
+
+```rust,ignore
+let tweet = Tweet {
+ username: String::from("horse_ebooks"),
+ content: String::from("of course, as you probably already know, people"),
+ reply: false,
+ retweet: false,
+};
+
+println!("1 new tweet: {}", tweet.summary());
+```
+
+This will print `1 new tweet: (Read more from @horse_ebooks...)`.
+
+Note that it is not possible to call the default implementation from an
+overriding implementation.
+
+### Trait Bounds
+
+Now that we've defined traits and implemented those traits on types, we can use
+traits with generic type parameters. We can constrain generic types so that
+rather than being any type, the compiler will ensure that the type will be
+limited to those types that implement a particular trait and thus have the
+behavior that we need the types to have. This is called specifying *trait
+bounds* on a generic type.
+
+For example, in Listing 10-12, we implemented the `Summarizable` trait on the
+types `NewsArticle` and `Tweet`. We can define a function `notify` that calls
+the `summary` method on its parameter `item`, which is of the generic type `T`.
+To be able to call `summary` on `item` without getting an error, we can use
+trait bounds on `T` to specify that `item` must be of a type that implements
+the `Summarizable` trait:
+
+```rust,ignore
+pub fn notify(item: T) {
+ println!("Breaking news! {}", item.summary());
+}
+```
+
+Trait bounds go with the declaration of the generic type parameter, after a
+colon and within the angle brackets. Because of the trait bound on `T`, we can
+call `notify` and pass in any instance of `NewsArticle` or `Tweet`. The
+external code from Listing 10-13 that's using our `aggregator` crate can call
+our `notify` function and pass in an instance of `WeatherForecast`, since
+`Summarizable` is implemented for `WeatherForecast` as well. Code that calls
+`notify` with any other type, like a `String` or an `i32`, won't compile, since
+those types do not implement `Summarizable`.
+
+We can specify multiple trait bounds on a generic type by using `+`. If we
+needed to be able to use display formatting on the type `T` in a function as
+well as the `summary` method, we can use the trait bounds `T: Summarizable +
+Display`. This means `T` can be any type that implements both `Summarizable`
+and `Display`.
+
+For functions that have multiple generic type parameters, each generic has its
+own trait bounds. Specifying lots of trait bound information in the angle
+brackets between a function's name and its parameter list can get hard to read,
+so there's an alternate syntax for specifying trait bounds that lets us move
+them to a `where` clause after the function signature. So instead of:
+
+```rust,ignore
+fn some_function(t: T, u: U) -> i32 {
+```
+
+We can write this instead with a `where` clause:
+
+```rust,ignore
+fn some_function