From fc8a8fcf9fae26e837d07dca8b982ea07fee6ace Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Tue, 31 Dec 2024 21:58:59 -0600 Subject: [PATCH 1/9] Clarify sentence in 5.1. Fixes #119 --- src/ch05-01-defining-structs.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ch05-01-defining-structs.md b/src/ch05-01-defining-structs.md index 38107a8d66..d8085d7633 100644 --- a/src/ch05-01-defining-structs.md +++ b/src/ch05-01-defining-structs.md @@ -189,12 +189,11 @@ many fields as we want in any order, regardless of the order of the fields in the struct’s definition. Note that the struct update syntax uses `=` like an assignment; this is -because it moves the data, just as we saw in the ["What Is Ownership?"][move] section. In this example, we can no -longer use `user1` after creating `user2` because the `String` in the +because it moves the data, just as we saw in the ["What Is Ownership?"][move] section. In this example, after creating `user2`, `user1` is partially invalidated because the `String` in the `username` field of `user1` was moved into `user2`. If we had given `user2` new `String` values for both `email` and `username`, and thus only used the `active` and `sign_in_count` values from `user1`, then `user1` would still be -valid after creating `user2`. The types of `active` and `sign_in_count` are +fully valid after creating `user2`. The types of `active` and `sign_in_count` are types that implement the `Copy` trait, so the behavior we discussed in the [“Copying vs. Moving Out of a Collection”][copy] section would apply. From 5bb80018dbfe5feeff3e4f0c673860f709801e49 Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Tue, 31 Dec 2024 21:59:20 -0600 Subject: [PATCH 2/9] Fix aquascope diagram --- src/ch04-03-fixing-ownership-errors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch04-03-fixing-ownership-errors.md b/src/ch04-03-fixing-ownership-errors.md index 756131dd06..ce89450dc4 100644 --- a/src/ch04-03-fixing-ownership-errors.md +++ b/src/ch04-03-fixing-ownership-errors.md @@ -79,7 +79,7 @@ This program is rejected by the borrow checker because `name` is an immutable re ```aquascope,interpreter,shouldFail,horizontal #fn stringify_name_with_title(name: &Vec) -> String { -# name.push(String::from("Esq."));`{}` +# name.push(String::from("Esq.")); # let full = name.join(" "); # full #} From 73532591841c262a89196d12363d9fb156eaed4d Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Tue, 31 Dec 2024 22:15:26 -0600 Subject: [PATCH 3/9] Fix typo in async. Fixes #220 --- src/ch17-01-futures-and-syntax.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch17-01-futures-and-syntax.md b/src/ch17-01-futures-and-syntax.md index 13f6cc4f3d..1d3cfb85ad 100644 --- a/src/ch17-01-futures-and-syntax.md +++ b/src/ch17-01-futures-and-syntax.md @@ -123,7 +123,7 @@ Notice that Rust’s `await` keyword goes after the expression you are awaiting, not before it. That is, it is a *postfix keyword*. This may be different from what you might be used to if you have used async in other languages. Rust chose this because it makes chains of methods much nicer to work with. As a result, we -can change the body of `page_url_for` to chain the `trpl::get` and `text` +can change the body of `page_title` to chain the `trpl::get` and `text` function calls together with `await` between them, as shown in Listing 17-2: From c9f03b7f09a581e4d300cfad9846efa97b93b022 Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Tue, 31 Dec 2024 22:26:22 -0600 Subject: [PATCH 4/9] Change &str to &String. Fixes #225 --- quizzes/ch04-02-references-sec2-perms.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quizzes/ch04-02-references-sec2-perms.toml b/quizzes/ch04-02-references-sec2-perms.toml index 803ef2a77c..6a70a8e481 100644 --- a/quizzes/ch04-02-references-sec2-perms.toml +++ b/quizzes/ch04-02-references-sec2-perms.toml @@ -31,7 +31,7 @@ prompt.prompt = """ Consider the permissions in the following program: ```aquascope,permissions,stepper,boundaries -fn get_first(v: &Vec) -> &str { +fn get_first(v: &Vec) -> &String { &v[0] } From cc5ea2f2d85725b9376897de1823b35dd2d8da80 Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Tue, 31 Dec 2024 22:30:39 -0600 Subject: [PATCH 5/9] Clarify iterator question. Fixes #230 --- quizzes/ch13-02-iterators.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quizzes/ch13-02-iterators.toml b/quizzes/ch13-02-iterators.toml index ec5b0d2e85..b4f3e98b00 100644 --- a/quizzes/ch13-02-iterators.toml +++ b/quizzes/ch13-02-iterators.toml @@ -19,7 +19,7 @@ Lazy generally means "does not do work until asked", and iterators do not perfor id = "19eac65e-44ad-4349-9632-47bdbb519d46" type = "MultipleChoice" prompt.prompt = """ -True/false: these two code snippets are semantically equivalent. +True/false: these two code snippets are semantically equivalent where `iter` is an iterator. Snippet 1: ``` From b0122bce38b86bbe76446efae2540dae36b930fc Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Tue, 31 Dec 2024 22:31:57 -0600 Subject: [PATCH 6/9] Fix Chapter reference. Fixes #231 --- src/ch02-00-guessing-game-tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch02-00-guessing-game-tutorial.md b/src/ch02-00-guessing-game-tutorial.md index 83a456d247..bfa588e8af 100644 --- a/src/ch02-00-guessing-game-tutorial.md +++ b/src/ch02-00-guessing-game-tutorial.md @@ -614,7 +614,7 @@ fits that arm’s pattern. Rust takes the value given to `match` and looks through each arm’s pattern in turn. Patterns and the `match` construct are powerful Rust features: they let you express a variety of situations your code might encounter and they make sure you handle them all. These features will be -covered in detail in Chapter 6 and Chapter 18, respectively. +covered in detail in Chapter 6 and Chapter 19, respectively. Let’s walk through an example with the `match` expression we use here. Say that the user has guessed 50 and the randomly generated secret number this time is From c318fb4d2bd166a556af9957eea2679683257f5d Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Tue, 31 Dec 2024 22:34:17 -0600 Subject: [PATCH 7/9] Fix async question. Fixes #233 --- quizzes/async-03-more-futures.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quizzes/async-03-more-futures.toml b/quizzes/async-03-more-futures.toml index d1875580c5..c12f933ddf 100644 --- a/quizzes/async-03-more-futures.toml +++ b/quizzes/async-03-more-futures.toml @@ -4,7 +4,7 @@ prompt.prompt = """ Given a function `sleep(d)` that sleeps for the given duration, consider this function: ```rust -let futs: Vec<_> = [1, 2, 3].iter().map(|n| async { +let futs: Vec<_> = [1, 2, 3].iter().map(|n| async move { sleep(Duration::from_secs(5)).await; n + 1 }).collect(); From 33894972e43c7c6579224d2d35b01b6bdcd32401 Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Tue, 31 Dec 2024 22:35:33 -0600 Subject: [PATCH 8/9] Incorrect does_not_compile. Fixes #234. --- src/ch17-04-streams.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch17-04-streams.md b/src/ch17-04-streams.md index c13017be77..ef8e115076 100644 --- a/src/ch17-04-streams.md +++ b/src/ch17-04-streams.md @@ -93,7 +93,7 @@ Listing 17-31. -```rust,ignore,does_not_compile +```rust {{#rustdoc_include ../listings/ch17-async-await/listing-17-31/src/main.rs}} ``` From cb4124fae89f1cfb72635cae4f44c3c20017efcb Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Tue, 31 Dec 2024 22:41:42 -0600 Subject: [PATCH 9/9] Fix a bunch of chapter references. Fixes #226 --- src/appendix-03-derivable-traits.md | 2 +- src/ch00-00-introduction.md | 8 ++++---- src/ch01-02-hello-world.md | 2 +- src/ch04-02-references-and-borrowing.md | 10 ---------- src/ch04-03-fixing-ownership-errors.md | 2 +- src/ch08-01-vectors.md | 2 +- src/ch09-02-recoverable-errors-with-result.md | 2 +- src/ch09-03-to-panic-or-not-to-panic.md | 2 +- src/ch10-02-traits.md | 2 +- src/ch10-03-lifetime-syntax.md | 2 +- src/ch12-00-an-io-project.md | 4 ++-- src/ch12-03-improving-error-handling-and-modularity.md | 4 ++-- src/ch13-02-iterators.md | 2 +- src/ch14-02-publishing-to-crates-io.md | 2 +- src/ch15-01-box.md | 6 +++--- src/ch15-02-deref.md | 2 +- src/ch15-05-interior-mutability.md | 2 +- src/ch16-02-message-passing.md | 2 +- src/ch16-04-extensible-concurrency-sync-and-send.md | 6 +++--- src/ch18-02-trait-objects.md | 2 +- src/ch18-03-oo-design-patterns.md | 2 +- src/ch20-00-advanced-features.md | 2 +- src/ch20-04-advanced-types.md | 4 ++-- src/ch20-06-macros.md | 2 +- src/ch21-01-single-threaded.md | 2 +- src/ch21-02-multithreaded.md | 4 ++-- src/ch21-03-graceful-shutdown-and-cleanup.md | 2 +- 27 files changed, 37 insertions(+), 47 deletions(-) diff --git a/src/appendix-03-derivable-traits.md b/src/appendix-03-derivable-traits.md index e7e529ea5e..60376dc014 100644 --- a/src/appendix-03-derivable-traits.md +++ b/src/appendix-03-derivable-traits.md @@ -34,7 +34,7 @@ The list of derivable traits provided in this appendix is not comprehensive: libraries can implement `derive` for their own traits, making the list of traits you can use `derive` with truly open-ended. Implementing `derive` involves using a procedural macro, which is covered in the -[“Macros”][macros] section of Chapter 19. +[“Macros”][macros] section of Chapter 20. ### `Debug` for Programmer Output diff --git a/src/ch00-00-introduction.md b/src/ch00-00-introduction.md index 12632aa0bf..8de76777d7 100644 --- a/src/ch00-00-introduction.md +++ b/src/ch00-00-introduction.md @@ -143,15 +143,15 @@ traits that enable their functionality. In Chapter 16, we’ll walk through different models of concurrent programming and talk about how Rust helps you to program in multiple threads fearlessly. -Chapter 17 looks at how Rust idioms compare to object-oriented programming +Chapter 18 looks at how Rust idioms compare to object-oriented programming principles you might be familiar with. -Chapter 18 is a reference on patterns and pattern matching, which are powerful -ways of expressing ideas throughout Rust programs. Chapter 19 contains a +Chapter 19 is a reference on patterns and pattern matching, which are powerful +ways of expressing ideas throughout Rust programs. Chapter 20 contains a smorgasbord of advanced topics of interest, including unsafe Rust, macros, and more about lifetimes, traits, types, functions, and closures. -In Chapter 20, we’ll complete a project in which we’ll implement a low-level +In Chapter 21, we’ll complete a project in which we’ll implement a low-level multithreaded web server! Finally, some appendices contain useful information about the language in a diff --git a/src/ch01-02-hello-world.md b/src/ch01-02-hello-world.md index 72ba7b1602..1badc45e5e 100644 --- a/src/ch01-02-hello-world.md +++ b/src/ch01-02-hello-world.md @@ -125,7 +125,7 @@ First, Rust style is to indent with four spaces, not a tab. Second, `println!` calls a Rust macro. If it had called a function instead, it would be entered as `println` (without the `!`). We’ll discuss Rust macros in -more detail in Chapter 19. For now, you just need to know that using a `!` +more detail in Chapter 20. For now, you just need to know that using a `!` means that you’re calling a macro instead of a normal function and that macros don’t always follow the same rules as functions. diff --git a/src/ch04-02-references-and-borrowing.md b/src/ch04-02-references-and-borrowing.md index 798f89e785..eea9f6121d 100644 --- a/src/ch04-02-references-and-borrowing.md +++ b/src/ch04-02-references-and-borrowing.md @@ -392,16 +392,6 @@ This snippet introduces a new kind of permission, the flow permission @Perm{flow Unlike the @Perm{read}@Perm{write}@Perm{own} permissions, @Perm{flow} does not change throughout the body of a function. A reference has the @Perm{flow} permission if it's allowed to be used (that is, to *flow*) in a particular expression. For example, let's say we change `first` to a new function `first_or` that includes a `default` parameter: -```aquascope,permissions,boundaries,showFlows,shouldFail -fn first_or(strings: &Vec, default: &String) -> &String { - if strings.len() > 0 { - &strings[0]`{}` - } else { - default`{}` - } -} -``` - This function no longer compiles, because the expressions `&strings[0]` and `default` lack the necessary @Perm{flow} permission to be returned. But why? Rust gives the following error: ```text diff --git a/src/ch04-03-fixing-ownership-errors.md b/src/ch04-03-fixing-ownership-errors.md index ce89450dc4..4c90a10391 100644 --- a/src/ch04-03-fixing-ownership-errors.md +++ b/src/ch04-03-fixing-ownership-errors.md @@ -444,7 +444,7 @@ unsafe { *x += *y; } // DO NOT DO THIS unless you know what you're doing! #} ``` -Unsafe code is sometimes necessary to work around the limitations of the borrow checker. As a general strategy, let's say the borrow checker rejects a program you think is actually safe. Then you should look for standard library functions (like `split_at_mut`) that contain `unsafe` blocks which solve your problem. We will discuss unsafe code further in [Chapter 19][unsafe]. For now, just be aware that unsafe code is how Rust implements certain otherwise-impossible patterns. +Unsafe code is sometimes necessary to work around the limitations of the borrow checker. As a general strategy, let's say the borrow checker rejects a program you think is actually safe. Then you should look for standard library functions (like `split_at_mut`) that contain `unsafe` blocks which solve your problem. We will discuss unsafe code further in [Chapter 20][unsafe]. For now, just be aware that unsafe code is how Rust implements certain otherwise-impossible patterns. {{#quiz ../quizzes/ch04-03-fixing-ownership-errors-sec2-safety.toml}} diff --git a/src/ch08-01-vectors.md b/src/ch08-01-vectors.md index d4b6d8824f..2bbcd21044 100644 --- a/src/ch08-01-vectors.md +++ b/src/ch08-01-vectors.md @@ -287,7 +287,7 @@ at compile time that every possible case is handled, as discussed in Chapter 6. If you don’t know the exhaustive set of types a 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. +object, which we’ll cover in Chapter 18. Now that we’ve discussed some of the most common ways to use vectors, be sure to review [the API documentation][vec-api] for all of the many diff --git a/src/ch09-02-recoverable-errors-with-result.md b/src/ch09-02-recoverable-errors-with-result.md index c73093e10f..f4d0d8efb8 100644 --- a/src/ch09-02-recoverable-errors-with-result.md +++ b/src/ch09-02-recoverable-errors-with-result.md @@ -509,7 +509,7 @@ allows the use of the `?` operator on `Result` values. The `Box` type is a *trait object*, which we’ll talk about in the [“Using Trait Objects that Allow for Values of Different -Types”][trait-objects] section in Chapter 17. For now, you can +Types”][trait-objects] section in Chapter 18. For now, you can read `Box` to mean “any kind of error.” Using `?` on a `Result` value in a `main` function with the error type `Box` is allowed because it allows any `Err` value to be returned early. Even though the body of diff --git a/src/ch09-03-to-panic-or-not-to-panic.md b/src/ch09-03-to-panic-or-not-to-panic.md index 28c28a0720..9e25402cf4 100644 --- a/src/ch09-03-to-panic-or-not-to-panic.md +++ b/src/ch09-03-to-panic-or-not-to-panic.md @@ -78,7 +78,7 @@ more of the following: rather than checking for the problem at every step. * There’s not a good way to encode this information in the types you use. We’ll work through an example of what we mean in the [“Encoding States and Behavior - as Types”][encoding] section of Chapter 17. + as Types”][encoding] section of Chapter 18. If someone calls your code and passes in values that don’t make sense, it’s best to return an error if you can so the user of the library can decide what diff --git a/src/ch10-02-traits.md b/src/ch10-02-traits.md index 7a607eadd7..bbc444bc6f 100644 --- a/src/ch10-02-traits.md +++ b/src/ch10-02-traits.md @@ -327,7 +327,7 @@ around how the `impl Trait` syntax is implemented in the compiler. We’ll cover how to write a function with this behavior in the [“Using Trait Objects That Allow for Values of Different Types”][using-trait-objects-that-allow-for-values-of-different-types] section of Chapter 17. +ignore --> section of Chapter 18. ### Using Trait Bounds to Conditionally Implement Methods diff --git a/src/ch10-03-lifetime-syntax.md b/src/ch10-03-lifetime-syntax.md index 261cbf160a..4dabbd0e3c 100644 --- a/src/ch10-03-lifetime-syntax.md +++ b/src/ch10-03-lifetime-syntax.md @@ -623,7 +623,7 @@ that this flexible code won’t have any dangling references. And all of this analysis happens at compile time, which doesn’t affect runtime performance! Believe it or not, there is much more to learn on the topics we discussed in -this chapter: Chapter 17 discusses trait objects, which are another way to use +this chapter: Chapter 18 discusses trait objects, which are another way to use traits. There are also more complex scenarios involving lifetime annotations that you will only need in very advanced scenarios; for those, you should read the [Rust Reference][reference]. But next, you’ll learn how to write tests in diff --git a/src/ch12-00-an-io-project.md b/src/ch12-00-an-io-project.md index 951fcb9d44..97a63506a2 100644 --- a/src/ch12-00-an-io-project.md +++ b/src/ch12-00-an-io-project.md @@ -38,7 +38,7 @@ Our `grep` project will combine a number of concepts you’ve learned so far: * Writing tests ([Chapter 11][ch11]) We’ll also briefly introduce closures, iterators, and trait objects, which -[Chapter 13][ch13] and [Chapter 17][ch17] will +[Chapter 13][ch13] and [Chapter 18][ch18] will cover in detail. [ch7]: ch07-00-managing-growing-projects-with-packages-crates-and-modules.html @@ -47,4 +47,4 @@ cover in detail. [ch10]: ch10-00-generics.html [ch11]: ch11-00-testing.html [ch13]: ch13-00-functional-features.html -[ch17]: ch18-00-oop.html +[ch18]: ch18-00-oop.html diff --git a/src/ch12-03-improving-error-handling-and-modularity.md b/src/ch12-03-improving-error-handling-and-modularity.md index 64fe188b52..bf2b7c35bd 100644 --- a/src/ch12-03-improving-error-handling-and-modularity.md +++ b/src/ch12-03-improving-error-handling-and-modularity.md @@ -381,7 +381,7 @@ returned the unit type, `()`, and we keep that as the value returned in the For the error type, we used the *trait object* `Box` (and we’ve brought `std::error::Error` into scope with a `use` statement at the top). -We’ll cover trait objects in [Chapter 17][ch17]. For now, just +We’ll cover trait objects in [Chapter 18][ch18]. For now, just know that `Box` means the function will return a type that implements the `Error` trait, but we don’t have to specify what particular type the return value will be. This gives us flexibility to return error values that @@ -490,5 +490,5 @@ write some tests! [ch9-custom-types]: ch09-03-to-panic-or-not-to-panic.html#creating-custom-types-for-validation [ch9-error-guidelines]: ch09-03-to-panic-or-not-to-panic.html#guidelines-for-error-handling [ch9-result]: ch09-02-recoverable-errors-with-result.html -[ch17]: ch18-00-oop.html +[ch18]: ch18-00-oop.html [ch9-question-mark]: ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator diff --git a/src/ch13-02-iterators.md b/src/ch13-02-iterators.md index 744013138a..29f63ebbbe 100644 --- a/src/ch13-02-iterators.md +++ b/src/ch13-02-iterators.md @@ -66,7 +66,7 @@ pub trait Iterator { Notice this definition uses some new syntax: `type Item` and `Self::Item`, which are defining an *associated type* with this trait. We’ll talk about -associated types in depth in Chapter 19. For now, all you need to know is that +associated types in depth in Chapter 20. For now, all you need to know is that this code says implementing the `Iterator` trait requires that you also define an `Item` type, and this `Item` type is used in the return type of the `next` method. In other words, the `Item` type will be the type returned from the diff --git a/src/ch14-02-publishing-to-crates-io.md b/src/ch14-02-publishing-to-crates-io.md index 95e868d23c..aafd91a221 100644 --- a/src/ch14-02-publishing-to-crates-io.md +++ b/src/ch14-02-publishing-to-crates-io.md @@ -66,7 +66,7 @@ authors commonly use in their documentation: returned can be helpful to callers so they can write code to handle the different kinds of errors in different ways. * **Safety**: If the function is `unsafe` to call (we discuss unsafety in - Chapter 19), there should be a section explaining why the function is unsafe +20), there should be a section explaining why the function is unsafe and covering the invariants that the function expects callers to uphold. Most documentation comments don’t need all of these sections, but this is a diff --git a/src/ch15-01-box.md b/src/ch15-01-box.md index dd6f8f2513..58386af077 100644 --- a/src/ch15-01-box.md +++ b/src/ch15-01-box.md @@ -23,10 +23,10 @@ time because the data is copied around on the stack. To improve performance in this situation, we can store the large amount of data on the heap in a box. Then, only the small amount of pointer data is copied around on the stack, while the data it references stays in one place on the heap. The third case is -known as a *trait object*, and Chapter 17 devotes an entire section, [“Using +known as a *trait object*, and Chapter 18 devotes an entire section, [“Using Trait Objects That Allow for Values of Different Types,”][trait-objects] just to that topic. So what you learn here you’ll apply again in -Chapter 17! +Chapter 18! ### Using a `Box` to Store Data on the Heap @@ -242,7 +242,7 @@ other special capabilities, like those we’ll see with the other smart pointer types. They also don’t have the performance overhead that these special capabilities incur, so they can be useful in cases like the cons list where the indirection is the only feature we need. We’ll look at more use cases for boxes -in Chapter 17, too. +in Chapter 18, too. The `Box` type is a smart pointer because it implements the `Deref` trait, which allows `Box` values to be treated like references. When a `Box` diff --git a/src/ch15-02-deref.md b/src/ch15-02-deref.md index bb6943884a..af860a88b4 100644 --- a/src/ch15-02-deref.md +++ b/src/ch15-02-deref.md @@ -148,7 +148,7 @@ contains an implementation of `Deref` to add to the definition of `MyBox`: The `type Target = T;` syntax defines an associated type for the `Deref` trait to use. Associated types are a slightly different way of declaring a generic parameter, but you don’t need to worry about them for now; we’ll cover -them in more detail in Chapter 19. +them in more detail in Chapter 20. We fill in the body of the `deref` method with `&self.0` so `deref` returns a reference to the value we want to access with the `*` operator; recall from the diff --git a/src/ch15-05-interior-mutability.md b/src/ch15-05-interior-mutability.md index 791958ef5c..a6ef14e85e 100644 --- a/src/ch15-05-interior-mutability.md +++ b/src/ch15-05-interior-mutability.md @@ -6,7 +6,7 @@ action is disallowed by the borrowing rules. To mutate data, the pattern uses `unsafe` code inside a data structure to bend Rust’s usual rules that govern mutation and borrowing. Unsafe code indicates to the compiler that we’re checking the rules manually instead of relying on the compiler to check them -for us; we will discuss unsafe code more in Chapter 19. +for us; we will discuss unsafe code more in Chapter 20. We can use types that use the interior mutability pattern only when we can ensure that the borrowing rules will be followed at runtime, even though the diff --git a/src/ch16-02-message-passing.md b/src/ch16-02-message-passing.md index 95f617d028..372c3b233f 100644 --- a/src/ch16-02-message-passing.md +++ b/src/ch16-02-message-passing.md @@ -57,7 +57,7 @@ receiver. The abbreviations `tx` and `rx` are traditionally used in many fields for *transmitter* and *receiver* respectively, so we name our variables as such to indicate each end. We’re using a `let` statement with a pattern that destructures the tuples; we’ll discuss the use of patterns in `let` statements -and destructuring in Chapter 18. For now, know that using a `let` statement +and destructuring in Chapter 19. For now, know that using a `let` statement this way is a convenient approach to extract the pieces of the tuple returned by `mpsc::channel`. diff --git a/src/ch16-04-extensible-concurrency-sync-and-send.md b/src/ch16-04-extensible-concurrency-sync-and-send.md index 95d5fd3e07..17daab9972 100644 --- a/src/ch16-04-extensible-concurrency-sync-and-send.md +++ b/src/ch16-04-extensible-concurrency-sync-and-send.md @@ -28,7 +28,7 @@ compiled. Any type composed entirely of `Send` types is automatically marked as `Send` as well. Almost all primitive types are `Send`, aside from raw pointers, which -we’ll discuss in Chapter 19. +we’ll discuss in Chapter 20. ### Allowing Access from Multiple Threads with `Sync` @@ -59,7 +59,7 @@ marker traits, they don’t even have any methods to implement. They’re just useful for enforcing invariants related to concurrency. Manually implementing these traits involves implementing unsafe Rust code. -We’ll talk about using unsafe Rust code in Chapter 19; for now, the important +We’ll talk about using unsafe Rust code in Chapter 20; for now, the important information is that building new concurrent types not made up of `Send` and `Sync` parts requires careful thought to uphold the safety guarantees. [“The Rustonomicon”][nomicon] has more information about these guarantees and how to @@ -68,7 +68,7 @@ uphold them. ## Summary This isn’t the last you’ll see of concurrency in this book: the whole next -chapter focuses on async programming, and the project in Chapter 20 will use the +chapter focuses on async programming, and the project in Chapter 21 will use the concepts in this chapter in a more realistic situation than the smaller examples discussed here. diff --git a/src/ch18-02-trait-objects.md b/src/ch18-02-trait-objects.md index 6f6bf59c5a..33ed0709e4 100644 --- a/src/ch18-02-trait-objects.md +++ b/src/ch18-02-trait-objects.md @@ -45,7 +45,7 @@ implementing our specified trait and a table used to look up trait methods on that type at runtime. We create a trait object by specifying some sort of pointer, such as a `&` reference or a `Box` smart pointer, then the `dyn` keyword, and then specifying the relevant trait. (We’ll talk about the reason -trait objects must use a pointer in Chapter 19 in the section [“Dynamically +trait objects must use a pointer in Chapter 20 in the section [“Dynamically Sized Types and the `Sized` Trait.”][dynamically-sized]) We can use trait objects in place of a generic or concrete type. Wherever we use a trait object, Rust’s type system will ensure at compile time that any value diff --git a/src/ch18-03-oo-design-patterns.md b/src/ch18-03-oo-design-patterns.md index 09421873d6..d6a5ae8391 100644 --- a/src/ch18-03-oo-design-patterns.md +++ b/src/ch18-03-oo-design-patterns.md @@ -366,7 +366,7 @@ and `approve` methods on `Post`. Both methods delegate to the implementation of the same method on the value in the `state` field of `Option` and set the new value of the `state` field to the result. If we had a lot of methods on `Post` that followed this pattern, we might consider defining a macro to eliminate the -repetition (see the [“Macros”][macros] section in Chapter 19). +repetition (see the [“Macros”][macros] section in Chapter 20). By implementing the state pattern exactly as it’s defined for object-oriented languages, we’re not taking as full advantage of Rust’s strengths as we could. diff --git a/src/ch20-00-advanced-features.md b/src/ch20-00-advanced-features.md index a0db41fde4..3e612d2af2 100644 --- a/src/ch20-00-advanced-features.md +++ b/src/ch20-00-advanced-features.md @@ -1,7 +1,7 @@ # Advanced Features By now, you’ve learned the most commonly used parts of the Rust programming -language. Before we do one more project in Chapter 20, we’ll look at a few +language. Before we do one more project in Chapter 21, we’ll look at a few aspects of the language you might run into every once in a while, but may not use every day. You can use this chapter as a reference for when you encounter any unknowns. The features covered here are useful in very specific situations. diff --git a/src/ch20-04-advanced-types.md b/src/ch20-04-advanced-types.md index 18111afc4f..5ba56d783a 100644 --- a/src/ch20-04-advanced-types.md +++ b/src/ch20-04-advanced-types.md @@ -34,7 +34,7 @@ internally. The newtype pattern is a lightweight way to achieve encapsulation to hide implementation details, which we discussed in the [“Encapsulation that Hides Implementation Details”][encapsulation-that-hides-implementation-details] -section of Chapter 17. +section of Chapter 18. ### Creating Type Synonyms with Type Aliases @@ -245,7 +245,7 @@ types behind a pointer of some kind. We can combine `str` with all kinds of pointers: for example, `Box` or `Rc`. In fact, you’ve seen this before but with a different dynamically sized type: traits. Every trait is a dynamically sized type we can refer to by -using the name of the trait. In Chapter 17 in the [“Using Trait Objects That +using the name of the trait. In Chapter 18 in the [“Using Trait Objects That Allow for Values of Different Types”][using-trait-objects-that-allow-for-values-of-different-types] section, we mentioned that to use traits as trait objects, we must diff --git a/src/ch20-06-macros.md b/src/ch20-06-macros.md index 68a3762809..57b28d3e1c 100644 --- a/src/ch20-06-macros.md +++ b/src/ch20-06-macros.md @@ -106,7 +106,7 @@ one arm. Valid pattern syntax in macro definitions is different than the pattern syntax -covered in Chapter 18 because macro patterns are matched against Rust code +covered in Chapter 19 because macro patterns are matched against Rust code structure rather than values. For example, declarative macros can match against expressions (`expr`), types (`ty`), and even entire items (`item`). Let's walk through what the pattern pieces in Listing 19-28 mean; for the full macro pattern syntax, see the [Rust diff --git a/src/ch21-01-single-threaded.md b/src/ch21-01-single-threaded.md index b474d926fe..e3ecafe5eb 100644 --- a/src/ch21-01-single-threaded.md +++ b/src/ch21-01-single-threaded.md @@ -441,7 +441,7 @@ contain only the code that differs between the two cases Now the `if` and `else` blocks only return the appropriate values for the status line and filename in a tuple; we then use destructuring to assign these two values to `status_line` and `filename` using a pattern in the `let` -statement, as discussed in Chapter 18. +statement, as discussed in Chapter 19. The previously duplicated code is now outside the `if` and `else` blocks and uses the `status_line` and `filename` variables. This makes it easier to see diff --git a/src/ch21-02-multithreaded.md b/src/ch21-02-multithreaded.md index 62572ef92e..09cc9d6677 100644 --- a/src/ch21-02-multithreaded.md +++ b/src/ch21-02-multithreaded.md @@ -546,7 +546,7 @@ Let’s finally implement the `execute` method on `ThreadPool`. We’ll also cha `Job` from a struct to a type alias for a trait object that holds the type of closure that `execute` receives. As discussed in the [“Creating Type Synonyms with Type Aliases”][creating-type-synonyms-with-type-aliases] -section of Chapter 19, type aliases allow us to make long types shorter for +section of Chapter 20, type aliases allow us to make long types shorter for ease of use. Look at Listing 20-19. Filename: src/lib.rs @@ -658,7 +658,7 @@ thread run them. > multiple instances of the same request sequentially for caching reasons. This > limitation is not caused by our web server. -After learning about the `while let` loop in Chapter 18, you might be wondering +After learning about the `while let` loop in Chapter 19, you might be wondering why we didn’t write the worker thread code as shown in Listing 20-21. Filename: src/lib.rs diff --git a/src/ch21-03-graceful-shutdown-and-cleanup.md b/src/ch21-03-graceful-shutdown-and-cleanup.md index e07b5379d6..c15fa00e9c 100644 --- a/src/ch21-03-graceful-shutdown-and-cleanup.md +++ b/src/ch21-03-graceful-shutdown-and-cleanup.md @@ -90,7 +90,7 @@ The following changes will do so: {{#rustdoc_include ../listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs:here}} ``` -As discussed in Chapter 17, the `take` method on `Option` takes the `Some` +As discussed in Chapter 18, the `take` method on `Option` takes the `Some` variant out and leaves `None` in its place. We’re using `if let` to destructure the `Some` and get the thread; then we call `join` on the thread. If a worker’s thread is already `None`, we know that worker has already had its thread