Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various fixes #238

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion quizzes/async-03-more-futures.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion quizzes/ch04-02-references-sec2-perms.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ prompt.prompt = """
Consider the permissions in the following program:

```aquascope,permissions,stepper,boundaries
fn get_first(v: &Vec<String>) -> &str {
fn get_first(v: &Vec<String>) -> &String {
&v[0]
}

Expand Down
2 changes: 1 addition & 1 deletion quizzes/ch13-02-iterators.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
```
Expand Down
2 changes: 1 addition & 1 deletion src/appendix-03-derivable-traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]<!-- ignore --> section of Chapter 19.
[“Macros”][macros]<!-- ignore --> section of Chapter 20.

### `Debug` for Programmer Output

Expand Down
8 changes: 4 additions & 4 deletions src/ch00-00-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/ch01-02-hello-world.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion src/ch02-00-guessing-game-tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 0 additions & 10 deletions src/ch04-02-references-and-borrowing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>, 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
Expand Down
4 changes: 2 additions & 2 deletions src/ch04-03-fixing-ownership-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -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>) -> String {
# name.push(String::from("Esq."));`{}`
# name.push(String::from("Esq."));
# let full = name.join(" ");
# full
#}
Expand Down Expand Up @@ -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}}

Expand Down
5 changes: 2 additions & 3 deletions src/ch05-01-defining-structs.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]<!-- ignore --> 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]<!-- ignore --> 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]<!-- ignore --> section would apply.

Expand Down
2 changes: 1 addition & 1 deletion src/ch08-01-vectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]<!-- ignore --> for all of the many
Expand Down
2 changes: 1 addition & 1 deletion src/ch09-02-recoverable-errors-with-result.md
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ allows the use of the `?` operator on `Result` values.</span>

The `Box<dyn Error>` type is a *trait object*, which we’ll talk about in the
[“Using Trait Objects that Allow for Values of Different
Types”][trait-objects]<!-- ignore --> section in Chapter 17. For now, you can
Types”][trait-objects]<!-- ignore --> section in Chapter 18. For now, you can
read `Box<dyn Error>` to mean “any kind of error.” Using `?` on a `Result`
value in a `main` function with the error type `Box<dyn Error>` is allowed
because it allows any `Err` value to be returned early. Even though the body of
Expand Down
2 changes: 1 addition & 1 deletion src/ch09-03-to-panic-or-not-to-panic.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]<!-- ignore --> section of Chapter 17.
as Types”][encoding]<!-- ignore --> 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
Expand Down
2 changes: 1 addition & 1 deletion src/ch10-02-traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]<!--
ignore --> section of Chapter 17.
ignore --> section of Chapter 18.

### Using Trait Bounds to Conditionally Implement Methods

Expand Down
2 changes: 1 addition & 1 deletion src/ch10-03-lifetime-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/ch12-00-an-io-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Our `grep` project will combine a number of concepts you’ve learned so far:
* Writing tests ([Chapter 11][ch11]<!-- ignore -->)

We’ll also briefly introduce closures, iterators, and trait objects, which
[Chapter 13][ch13]<!-- ignore --> and [Chapter 17][ch17]<!-- ignore --> will
[Chapter 13][ch13]<!-- ignore --> and [Chapter 18][ch18]<!-- ignore --> will
cover in detail.

[ch7]: ch07-00-managing-growing-projects-with-packages-crates-and-modules.html
Expand All @@ -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
4 changes: 2 additions & 2 deletions src/ch12-03-improving-error-handling-and-modularity.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<dyn Error>` (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]<!-- ignore -->. For now, just
We’ll cover trait objects in [Chapter 18][ch18]<!-- ignore -->. For now, just
know that `Box<dyn Error>` 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
Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion src/ch13-02-iterators.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/ch14-02-publishing-to-crates-io.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions src/ch15-01-box.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]<!--
ignore --> just to that topic. So what you learn here you’ll apply again in
Chapter 17!
Chapter 18!

### Using a `Box<T>` to Store Data on the Heap

Expand Down Expand Up @@ -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<T>` type is a smart pointer because it implements the `Deref` trait,
which allows `Box<T>` values to be treated like references. When a `Box<T>`
Expand Down
2 changes: 1 addition & 1 deletion src/ch15-02-deref.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/ch15-05-interior-mutability.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/ch16-02-message-passing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

Expand Down
6 changes: 3 additions & 3 deletions src/ch16-04-extensible-concurrency-sync-and-send.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand Down Expand Up @@ -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
Expand All @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion src/ch17-01-futures-and-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

<Listing number="17-2" file-name="src/main.rs" caption="Chaining with the `await` keyword">
Expand Down
2 changes: 1 addition & 1 deletion src/ch17-04-streams.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Listing 17-31.

<Listing number="17-31" caption="Successfully using an iterator as the basis for a stream" file-name="src/main.rs">

```rust,ignore,does_not_compile
```rust
{{#rustdoc_include ../listings/ch17-async-await/listing-17-31/src/main.rs}}
```

Expand Down
2 changes: 1 addition & 1 deletion src/ch18-02-trait-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>` 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]<!-- ignore -->) 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
Expand Down
2 changes: 1 addition & 1 deletion src/ch18-03-oo-design-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]<!-- ignore --> section in Chapter 19).
repetition (see the [“Macros”][macros]<!-- ignore --> 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.
Expand Down
2 changes: 1 addition & 1 deletion src/ch20-00-advanced-features.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
Loading
Loading