Skip to content

Commit

Permalink
Merge main into unsafe-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskrycho committed Oct 15, 2024
2 parents e63e487 + ec6b1b4 commit c9c119a
Show file tree
Hide file tree
Showing 33 changed files with 432 additions and 303 deletions.
5 changes: 5 additions & 0 deletions ADMIN_TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ occasional maintenance tasks.
To update the `edition = "[year]"` metadata in all the listings' `Cargo.toml`s,
run the `./tools/update-editions.sh` script and commit the changes.

## Update the `edition` in mdBook config

Open `book.toml` and `nostarch/book.toml` and set the `edition` value in the
`[rust]` table to the new edition.

## Release a new version of the listings

We now make `.tar` files of complete projects containing every listing
Expand Down
22 changes: 21 additions & 1 deletion book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,33 @@

[book]
title = "The Rust Programming Language"
authors = ["Steve Klabnik", "Carol Nichols", "Contributions from the Rust Community"]
authors = ["Steve Klabnik", "Carol Nichols", "Chris Krycho", "Contributions from the Rust Community"]

[output.html]
additional-css = ["ferris.css", "theme/2018-edition.css", "theme/semantic-notes.css", "theme/listing.css"]
additional-js = ["ferris.js"]
git-repository-url = "https://github.com/rust-lang/book"

[output.html.redirect]
"ch17-00-oop.html" = "ch18-00-oop.html"
"ch17-01-what-is-oo.html" = "ch18-01-what-is-oo.html"
"ch17-02-trait-objects.html" = "ch18-02-trait-objects.html"
"ch17-03-oo-design-patterns.html" = "ch18-03-oo-design-patterns.html"
"ch18-00-patterns.html" = "ch19-00-patterns.html"
"ch18-01-all-the-places-for-patterns.html" = "ch19-01-all-the-places-for-patterns.html"
"ch18-02-refutability.html" = "ch19-02-refutability.html"
"ch18-03-pattern-syntax.html" = "ch19-03-pattern-syntax.html"
"ch19-00-advanced-features.html" = "ch20-00-advanced-features.html"
"ch19-01-unsafe-rust.html" = "ch20-01-unsafe-rust.html"
"ch19-03-advanced-traits.html" = "ch20-03-advanced-traits.html"
"ch19-04-advanced-types.html" = "ch20-04-advanced-types.html"
"ch19-05-advanced-functions-and-closures.html" = "ch20-05-advanced-functions-and-closures.html"
"ch19-06-macros.html" = "ch20-06-macros.html"
"ch20-00-final-project-a-web-server.html" = "ch21-00-final-project-a-web-server.html"
"ch20-01-single-threaded.html" = "ch21-01-single-threaded.html"
"ch20-02-multithreaded.html" = "ch21-02-multithreaded.html"
"ch20-03-graceful-shutdown-and-cleanup.html" = "ch21-03-graceful-shutdown-and-cleanup.html"

# Do not sync this preprocessor; it is for the HTML renderer only.
[preprocessor.trpl-note]

Expand Down
1 change: 1 addition & 0 deletions ci/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ JoinHandle
Kay's
kinded
Klabnik
Krycho
lang
LastWriteTime
latin
Expand Down
3 changes: 3 additions & 0 deletions nostarch/book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ build-dir = "../tmp"

[preprocessor.trpl-listing]
output-mode = "simple"

[rust]
edition = "2021"
27 changes: 13 additions & 14 deletions nostarch/chapter17.md
Original file line number Diff line number Diff line change
Expand Up @@ -1669,10 +1669,10 @@ The version with `yield_now` is *way* faster!
This means that async can be useful even for compute-bound tasks, depending on
what else your program is doing, because it provides a useful tool for
structuring the relationships between different parts of the program. This is a
form of *cooperative multitasking*, where each future has both the power to
determine when it hands over control via await points. Each future therefore
also has the responsibility to avoid blocking for too long. In some Rust-based
embedded operating systems, this is the *only* kind of multitasking!
form of *cooperative multitasking*, where each future has the power to determine
when it hands over control via await points. Each future therefore also has the
responsibility to avoid blocking for too long. In some Rust-based embedded
operating systems, this is the *only* kind of multitasking!

In real-world code, you won’t usually be alternating function calls with await
points on every single line, of course. While yielding control in this way is
Expand Down Expand Up @@ -2046,7 +2046,7 @@ indicates a message arrived in time; the `Err` variant indicates that the
timeout elapsed before any message arrived. We `match` on that result and either
print the message when we receive it successfully, or print a notice about the
timeout. Finally, notice that we pin the messages after applying the timeout to
them, because the timeout helper produces a future which needs to be pinned to
them, because the timeout helper produces a stream which needs to be pinned to
be polled.

Filename: src/main.rs
Expand Down Expand Up @@ -2507,7 +2507,7 @@ it is not yet ready.

### Pinning and the Pin and Unpin Traits

When we introduced the idea of pinning, while working on Listing 17-17, we ran
When we introduced the idea of pinning while working on Listing 17-17, we ran
into a very gnarly error message. Here is the relevant part of it again:

```
Expand Down Expand Up @@ -2535,12 +2535,11 @@ For more information about an error, try `rustc --explain E0277`.

When we read this error message carefully, it not only tells us that we need to
pin the values, but also tells us why pinning is required. The `trpl::join_all`
function returns a struct called `JoinAll`. That struct, in turn, is generic
over a type `F`, which is constrained to implement the `Future` trait. Finally,
directly awaiting a Future requires that the future in question implement the
`Unpin` trait. That’s a lot! But we can understand it, if we dive a little
further into how the `Future` type actually works, in particular around
*pinning*.
function returns a struct called `JoinAll`. That struct is generic over a type
`F`, which is constrained to implement the `Future` trait. Finally, directly
awaiting a Future requires that the future in question implement the `Unpin`
trait. That’s a lot! But we can understand it, if we dive a little further into
how the `Future` type actually works, in particular around *pinning*.

Let’s look again at the definition of `Future`:

Expand Down Expand Up @@ -2943,9 +2942,9 @@ threads *and* tasks, and therefore futures.

As a default way of thinking about which to use when:

* If the task is *very parallelizable*, such as processing a bunch of data where
* If the work is *very parallelizable*, such as processing a bunch of data where
each part can be processed separately, threads are a better choice.
* If the task is *very concurrent*, such as handling messages from a bunch of
* If the work is *very concurrent*, such as handling messages from a bunch of
different sources which may come in a different intervals or different rates,
async is a better choice.

Expand Down
21 changes: 11 additions & 10 deletions packages/mdbook-trpl-listing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ impl<'e> ListingState<'e> {
) -> Result<(), String> {
// We do not *keep* the version constructed here, just temporarily
// construct it so the HTML parser, which expects properly closed tags
// to parse it as a *tag* rather than a *weird text node*, which accept
// to parse it as a *tag* rather than a *weird text node*, will accept
// it and provide a useful view of it.
let to_parse = tag.to_owned().to_string() + "</Listing>";
let listing = Dom::parse(&to_parse)
Expand All @@ -212,21 +212,22 @@ impl<'e> ListingState<'e> {
.try_fold(ListingBuilder::new(), |builder, (key, maybe_value)| {
match (key.as_str(), maybe_value) {
("number", Some(value)) => Ok(builder.with_number(value)),
("number", None) => {
Err(String::from("number attribute without value"))
}

("caption", Some(value)) => Ok(builder.with_caption(value)),
("caption", None) => {
Err(String::from("caption attribute without value"))
}

("file-name", Some(value)) => {
Ok(builder.with_file_name(value))
}
("file-name", None) => {
Err(String::from("file-name attribute without value"))

(attr @ "file-name", None)
| (attr @ "caption", None)
| (attr @ "number", None) => {
Err(format!("Missing value for attribute: '{attr}'"))
}

_ => Ok(builder), // TODO: error on extra attrs?
(attr, _) => {
Err(format!("Unsupported attribute name: '{attr}'"))
}
}
})?
.build();
Expand Down
103 changes: 103 additions & 0 deletions packages/mdbook-trpl-listing/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,108 @@ fn main() {}
);
}

#[test]
fn with_unsupported_attr_name() {
let result = rewrite_listing(
"<Listing invalid-attr>
```rust
fn main() {}
```
</Listing>",
Mode::Default,
);

assert_eq!(
result,
Err(String::from("Unsupported attribute name: 'invalid-attr'"))
)
}

#[test]
fn with_unsupported_attr_name_with_arg() {
let result = rewrite_listing(
r#"<Listing invalid-attr="123">
```rust
fn main() {}
```
</Listing>"#,
Mode::Default,
);

assert_eq!(
result,
Err(String::from("Unsupported attribute name: 'invalid-attr'"))
)
}

#[cfg(test)]
mod missing_value {
use super::*;

#[test]
fn for_number() {
let result = rewrite_listing(
r#"<Listing number>
```rust
fn main() {}
```
</Listing>"#,
Mode::Default,
);

assert_eq!(
result,
Err(String::from("Missing value for attribute: 'number'"))
)
}

#[test]
fn for_caption() {
let result = rewrite_listing(
r#"<Listing caption>
```rust
fn main() {}
```
</Listing>"#,
Mode::Default,
);

assert_eq!(
result,
Err(String::from("Missing value for attribute: 'caption'"))
)
}

#[test]
fn for_file_name() {
let result = rewrite_listing(
r#"<Listing file-name>
```rust
fn main() {}
```
</Listing>"#,
Mode::Default,
);

assert_eq!(
result,
Err(String::from("Missing value for attribute: 'file-name'"))
)
}
}

#[test]
fn missing_value() {}

#[cfg(test)]
mod config;
2 changes: 1 addition & 1 deletion src/appendix-02-operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ hierarchy to an item.
| Symbol | Explanation |
|--------|-------------|
| `ident::ident` | Namespace path |
| `::path` | Path relative to the crate root (i.e., an explicitly absolute path) |
| `::path` | Path relative to the extern prelude, where all other crates are rooted (i.e., an explicitly absolute path including crate name) |
| `self::path` | Path relative to the current module (i.e., an explicitly relative path). |
| `super::path` | Path relative to the parent of the current module |
| `type::ident`, `<type as trait>::ident` | Associated constants, functions, and types |
Expand Down
10 changes: 6 additions & 4 deletions src/ch06-01-defining-an-enum.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ only know what *kind* it is. Given that you just learned about structs in
Chapter 5, you might be tempted to tackle this problem with structs as shown in
Listing 6-1.

<Listing number="6-1" caption="Storing the data and `IpAddrKind` variant of an IP address using a `struct`">

```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-01/src/main.rs:here}}
```

<span class="caption">Listing 6-1: Storing the data and `IpAddrKind` variant of
an IP address using a `struct`</span>
</Listing>

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
Expand Down Expand Up @@ -140,12 +141,13 @@ more about bringing types into scope 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.

<Listing number="6-2" caption="A `Message` enum whose variants each store different amounts and types of values">

```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-02/src/main.rs:here}}
```

<span class="caption">Listing 6-2: A `Message` enum whose variants each store
different amounts and types of values</span>
</Listing>

This enum has four variants with different types:

Expand Down
15 changes: 9 additions & 6 deletions src/ch06-02-match.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ function that takes an unknown US coin and, in a similar way as the counting
machine, determines which coin it is and returns its value in cents, as shown
in Listing 6-3.

<Listing number="6-3" caption="An enum and a `match` expression that has the variants of the enum as its patterns">

```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-03/src/main.rs:here}}
```

<span class="caption">Listing 6-3: An enum and a `match` expression that has
the variants of the enum as its patterns</span>
</Listing>

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
Expand Down Expand Up @@ -75,12 +76,13 @@ designs, so only quarters have this extra value. We can add this information to
our `enum` by changing the `Quarter` variant to include a `UsState` value
stored inside it, which we’ve done in Listing 6-4.

<Listing number="6-4" caption="A `Coin` enum in which the `Quarter` variant also holds a `UsState` value">

```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-04/src/main.rs:here}}
```

<span class="caption">Listing 6-4: A `Coin` enum in which the `Quarter` variant
also holds a `UsState` value</span>
</Listing>

Let’s imagine that a friend 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
Expand Down Expand Up @@ -119,12 +121,13 @@ operations.
This function is very easy to write, thanks to `match`, and will look like
Listing 6-5.

<Listing number="6-5" caption="A function that uses a `match` expression on an `Option<i32>`">

```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:here}}
```

<span class="caption">Listing 6-5: A function that uses a `match` expression on
an `Option<i32>`</span>
</Listing>

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
Expand Down
5 changes: 3 additions & 2 deletions src/ch06-03-if-let.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ program in Listing 6-6 that matches on an `Option<u8>` value in the
`config_max` variable but only wants to execute code if the value is the `Some`
variant.

<Listing number="6-6" caption="A `match` that only cares about executing code when the value is `Some`">

```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-06/src/main.rs:here}}
```

<span class="caption">Listing 6-6: A `match` that only cares about executing
code when the value is `Some`</span>
</Listing>

If the value is `Some`, we print out the value in the `Some` variant by binding
the value to the variable `max` in the pattern. We don’t want to do anything
Expand Down
Loading

0 comments on commit c9c119a

Please sign in to comment.