Errata

Programming Rust

Errata for Programming Rust, Second Edition

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
ePub
Page n/a
text

Current Copy:
well. If the right number of arguments is present, we putt them in an Arguments struct, and return it. Then we’ll...

Suggested:
"we putt them in an Arguments struct," should be "we put them in an Arguments struct,"





Anonymous  Sep 09, 2021  Nov 05, 2021
ePub
Page n/a
text

Current Copy:
square root of two. When searching the documentation, remember that there pages for both the types themselves, named “f32 (primitive type)” and

Suggested:
should be "remember that there are pages for both the types themselves,"

Anonymous  Sep 09, 2021  Nov 05, 2021
Page ?
Chapter 13 "Utility Traits"

Chapter 13 "Utility Traits" has following sentence:
"Vec<T> and [T: N] implement Borrow<[T]>."

I believe it should be `[T; N]` (semicolon instead of colon).

Note from the Author or Editor:
On page 320, in "Borrow and BorrowMut", we claim that "Vec<T> and [T: N] implement Borrow<[T]>."

The punctuation in "[T: N]" is incorrect. It should be "[T; N]", with a semicolon, not a colon.

Sergei Shirokov  Oct 25, 2021 
Page n/a
text

Typo:

Current Copy:
By using fn pointers in functions that take callbacks, you can restrict a caller to use only these noncapturing closures, gaining some perfomance and flexibility within the code using callbacks at the cost of flexibility for the users of your API.

Suggested:
"gaining some perfomance and flexibility" should be "gaining some performance and flexibility"

Note from the Author or Editor:
On page 345, we referred to "perfomance" gains from using function pointers. That was a spelling error. We meant "performance".

Anonymous  Jan 04, 2022 
Page page 706
near bottom (index)

RefCell type, borrow methid

(instead of method)

Note from the Author or Editor:
The index entry should read "borrow method", not "borrow methid".

Tom  Sep 08, 2022 
Page Expressions Chapter 6, Loops section
Very end of loops section

let strings: Vec<String> = error_messages();

is not declared mutable. Later used as:

for rs in &mut strings { ......

the point at hand was clearly demonstrated. But minor error nevertheless

Note from the Author or Editor:
Naaol is correct. The last code block in the section should have an extra line, showing the vector declared as mut:

let mut strings = error_messages();
for rs in &mut strings { // the type of rs is &mut String
rs.push('\n'); // add a newline to each string
}

Naaol Shupare  Jun 02, 2023 
Page n/a
text

Current Copy
slice_a.swap(&mut slice_b)
Swaps the entire contents of slice_a and slice_b.
slice_a and slice_b must be the same length.

Suggested
slice_a.swap_with_slice(&mut slice_b)
Swaps the entire contents of slice_a and slice_b.
slice_a and slice_b must be the same length.

Note from the Author or Editor:
That's right: the name of the method that swaps the content of two slices is `swap_with_slice`, not `swap`. The error will be fixed for future printings.

Wilson Kuo  Oct 08, 2023 
Printed
Page "Debugging Macros", p. 610
First paragraph

The book says to add "-Z unstable-options --pretty expanded" to the rustc command line.

This used to work, but it doesn't anymore. The option is now spelled "-Z unstable-options -Z unpretty=expanded".

Alternatively, "cargo install cargo-expand" installs a new cargo subcommand that does this for you: "cargo expand".

Jason Orendorff
 
Apr 05, 2024 
Printed
Page "Doc-Tests", p. 202
First paragraph

Near the end of the section on doc-tests, the book says:

> If the code isn't even expected to compile, use `ignore` instead of `no_run`.

This is a mistake because "ignored" tests are only ignored by default. If you do `cargo test --ignored`, Cargo runs them all. The non-compiling code will then fail.

Probably the best thing to do is mark fake Rust code that isn't expected to compile as "text".

Jason Orendorff
 
Apr 05, 2024 
Page p414, map.clear() section
end of the second to last paragraph

from the official documentation: docs.rs/string/latest/string/struct.String.html#impl-Borrow%3Cstr%3E

`String` actually implements `Borrow<str>`, not `Borrow<&str>`, and as “Borrow and BorrowMut” on page 316 also said it implemented `Borrow<str>`.

Note from the Author or Editor:
In explaining that `HashMap::get()` and friends are generic, the book incorrectly states that `String` implements `Borrow<&str>`. It actually implements `Borrow<str>`.

Ron Lu  Jun 23, 2024 
Chapter 3. Expressions > Why Rust Has loop > 11th Paragraph

std::process:exit() -> std::process::exit()

Note from the Author or Editor:
Change "std::process:exit()" to "std::process::exit()" (adding one colon) in the Expressions chapter.

Sungmann Cho  Sep 06, 2020  Jun 11, 2021
Chapter 2 Safari
Chapter 2

In chapter 2 under "Concurrent Mandelbrot Program", it says:

To use it, we must add the following line to our Cargo.toml file:

crossbeam = "0.2"

but then later when it shows the whole Cargo.toml it shows 0.8:

[dependencies]
num = "0.4"
image = "0.13"
crossbeam = "0.8"

Note from the Author or Editor:
This has been corrected.

Vince  May 12, 2021  Jun 11, 2021
preface
Navigating This Book, 4th paragraph

The paragraph describes the remaining chapters of the book but omits chapter 20 on asynchronous programming.

Note from the Author or Editor:
This has been fixed.

Anonymous  May 23, 2021  Jun 11, 2021
Chapter 2
6th code block in "A Concurrent Mandelbrot Program"

The crossbeam dependency is added with version constraint = "0.2", this leads to a compilation error, because the closure to spawner.spawn has 0 arguments in crossbeam 0.2, but the code is written for crossbeam 0.8 which expects 1 argument.

Note from the Author or Editor:
Fixed in current text.

Joeri Samson  May 25, 2021  Jun 11, 2021
Chapter 2
First code block for "Mapping from Pixels to Complex Numbers"

The test for pixel_to_point uses a size where bounds.0 and bounds.1 are both 100, and the width and height are both 2. The result is that this test passes when a copy/paste error leads to code like this: ` im: upper_left.im - pixel.1 as f64 * height / bounds.0 as f64`, it also passes when you would use the width instead of height in that formula, but that's more likely to become a warning because height would be unused in pixel_to_point.

A test that catches this might be something like:
assert_eq!(pixel_to_point((100, 200), (25, 150),
Complex { re: -1.0, im: 0.0 },
Complex { re: 1.0, im: -1.0 }),
Complex { re: -0.5, im: -0.75 });

Which catches both of these separately and both of these made together.

Note from the Author or Editor:
This is a great suggestion. I think you meant (25, 175). I'll see if we can squeeze this in.

Joeri Samson  May 25, 2021  Jun 11, 2021
Page 6
Section "rustup and Cargo" in Chapter 2: A Tour of Rust

There was three command line examples which displays the version of the new installed rust tools cargo, rustc and rustdoc.
All commands print out the version "1.49.0" released in Dec. 2020 but this version does not support the Rust edition 2021, it only support edition 2018. All examples in this book use edition 2021.
The first Rust version which support edition 2021 is 1.56. (2021-10-04).

Note from the Author or Editor:
Thomas is correct. The book is focused on Rust 1.56.0. Future printings of the Second Edition will reflect that here.

Thomas  Jan 22, 2022 
Page 14
Bottom paragraph

"Unlike C and C++, which require main to return zero if the program finished successfully, or a nonzero exit status if something went wrong, Rust assumes that if main returns at all, the program finished successfully."

This is in fact not required in C++, as per the C++ standard:

eel.is/c++draft/basic.start.main#5

Note from the Author or Editor:
It's true: although running off the end of any ordinary non-void function is undefined behavior in C++, running off the end of `main()` is specially permitted by the language standard.

We have changed the text to avoid the incorrect implication that returning from main is "required" in C++.

Bart Louwers  Oct 02, 2022 
Page 18
Code doesn't compile

So the section 'Serving Pages to the Web' in Chapter 2 on page 18 gives me the following error:
cookie.set_expires(time::now() - Duration::days(365));
| ^ no implementation for `Tm - chrono::Duration`
|
= help: the trait `Sub<chrono::Duration>` is not implemented for `Tm`
= help: the following other types implement trait `Sub<Rhs>`:
<Tm as Sub<time::Duration>>
<Tm as Sub>
_____
The compiler doesn't even reach my code, so it must be an issue with dependencies.
Based on this Reddit post, other people are getting the same error:
Search for reddit and working_through_programming_rust_2nd_edition_got to see it.

Note from the Author or Editor:
We regret the inconvenience. It's no longer possible to build `actix-web 1.0.8` (the version we used when writing this example), because one of its dependencies (`chrono`) released a breaking change without bumping its minor version number, in violation of semver rules.

However, for security reasons, building with old versions of Web frameworks is a bad idea anyway. Actix is actively maintained and much newer versions exist. They are *almost* backward-compatible enough to support the example code in the book, but not quite.

To build the example today, update Cargo.toml to `actix-web = "4"` and put the following code in main.rs: https://gist.github.com/jorendorff/adaedcfb1d8ff80b6032b70607f4d820

The most significant change is that Actix now requires `main` and the two handler functions to be `async fn`s. See chapter 20 for more about async code.

Scott  Oct 30, 2023 
Printed
Page 20
Last paragraph, 1st sentence

“401 BAD REQUEST” => “400 BAD REQUEST”

xehpuk  Jul 31, 2021  Nov 05, 2021
Page 33
2nd code block

In the write_image fn, there's a call of encoder.encode with &pixels als the 1st param. pixels is already a slice, so no need to borrow (clippy::needless_borrow).

Note from the Author or Editor:
On page 33, in "Writing Image Files", in the code of `fn write_image`, we originally wrote `encoder.encode(&pixels, ...)`. The `&` is superfluous because `pixels` is already a reference.

The first argument should be simply `pixels`, not `&pixels`.

xehpuk  Aug 02, 2021 
Page 35, 36
final paragraph

At page page 35, the book makes the user write `if args.len() != 5` in order to prevent the program from running in case the wrong amount of arguments is passed to the terminal.
Afterwards, at page 36, it asks the user to run `time .\target\release\mandelbrot mandel.png 4300x3000 -1.20,0.30 -1.0,0.20` to verify that the program is running correctly (and check how long it takes to run).

The issue is that - at least on Windows - when you use commas in the terminal, they are considered separators. This means that `time .\target\release\mandelbrot mandel1.png 4000x3000 -1.20,0.35 -1.0,0.20` gets separated as `[".\target\release\mandelbrot", "mandel.png", "4000x3000", "-1.20", "0.35" , "-1.0", "0.20"]` (length 7, hence not allowed) instead of being separated as `[".\target\release\mandelbrot", "mandel.png", "4000x3000", "-1.20,0.35" , "-1.0,0.20"]` (length 5).

My solution to this was simply to `':'` as a separator of the pairs, rather than `','`

Best,

Alex

Note from the Author or Editor:
The command shown in the book to run the Mandelbrot program does not work on Windows.

To run the program on Windows, start PowerShell and run the command like this:

measure-command { .\target\release\mandelbrot mandel.png 4000x3000 -1.20,0.35 -1,0.20 }

(Note: `Measure-Command` is the PowerShell equivalent of the `time` command in Unix shells. Comma characters are special in cmd.exe, but in PowerShell they are passed through to the Rust program as desired.)

Alex Camilleri  Jul 18, 2022 
Page 37
legend of Figure 2-6

It reads “parallel” but this is the result of the nonconcurrent version from page 35.

Note from the Author or Editor:
The caption for Figure 2-6 should just say "Results from the Mandelbrot program"; the word "parallel" is there by mistake.

xehpuk  Aug 02, 2021 
Page 38f.
2nd line of code block

rows_per_band is supposed to be rounded upward, but it isn't really.
With bounds.1 set to e.g. 64 (a multiple of threads), this would result in 9 instead of 8.
This should work: let rows_per_band = (bounds.1 as f32 / threads as f32).ceil() as usize;

Note from the Author or Editor:
The number of rows per band can be 1 larger than an even split. We deliberately kept it simple; the imprecision has no impact on the program's performance or correctness.

Since Rust 1.73.0, there's a method for division rounding up, so this could be written `let rows_per_band = bounds.1.div_ceil(threads);`. The method wasn't stable at the time the second edition was published; in older versions of Rust, the typical way to write this would be `let rows_per_band = (bounds.1 + threads - 1) / threads;`.

xehpuk  Aug 02, 2021 
Page 45
code block, middle of page

When attempting to write the output, if an error occurs the message contains args.filename, which is the input file, not the output file.

match fs::write(&args.output, &data) {
Ok(_) => {},
Err(e) => {
eprintln!("{} failed to write to file '{}': {:?}", "Error:".red().bold(), args.filename, e);
std::process::exit(1);
}
};

should instead be

match fs::write(&args.output, &data) {
Ok(_) => {},
Err(e) => {
eprintln!("{} failed to write to file '{}': {:?}", "Error:".red().bold(), args.output, e);
std::process::exit(1);
}
};

Note from the Author or Editor:
On page 45, in the large code block showing `fn main`, there are two similar `eprintln!()` statements that report errors. Each one includes a filename in the error message, but the second prints the wrong filename.

The use of `args.filename` that appears after the call to `fs::write(&args.output, &data)` is incorrect. It should be `args.output` instead. We regret the error.

Andrew Ring  Jan 19, 2022 
Page 47
code block, upper half of page

When attempting to write the output, if an error occurs the message contains args.filename, which is the input file, not the output file.

eprintln!("{} failed to write to file '{}': {:?}", "Error:".red().bold(), args.filename, e);

should instead be

eprintln!("{} failed to write to file '{}': {:?}", "Error:".red().bold(), args.output, e);

Note from the Author or Editor:
On page 47, the first line of the page mentions `args.filename`. This is the wrong filename. It should be `args.output` instead.

Andrew Ring  Jan 19, 2022 
Page 47
2nd half

The book instructs the user to create a file via the echo command, using `echo "Hello, world" > test.txt`

When done in Windows (via cmd or PowerShell) this will result in the file getting a UTF-16 with BOM encoding.

Consequently, when running `cargo run "world" "Rust" test.txt test-modified.txt`, the program fails, with the error

```
error: failed to read from file '.\test.txt': Error { kind: InvalidData, message: "stream did not contain valid UTF-8" }
error: process didn't exit successfully: `target\debug\quickreplace.exe world Rust .\test.txt .\test-modified.txt` (exit code: 1)
```

The workaround is to create the file from outside the terminal.

Note from the Author or Editor:
We think the command will work on all new Windows machines since about May 2019. Older versions of cmd.exe and PowerShell default to UTF-16; newer versions default to UTF-8.

Creating the file with Notepad will certainly work. Another possible workaround is to use the PowerShell command `Set-Content -Path .\test.txt -Value 'Hello, world' -Encoding UTF8NoBOM`.

(Separately, in cmd.exe `ECHO "Hello, world" > file.txt` includes the quotes in the file. But at least that won't cause any trouble for Rust.)

Alex Camilleri  Jul 27, 2022 
Page 60
5th paragraph

Hello!

In the fifth paragraph on page 60, there is the first sentence:

"When searching the documentation, remember there pages ..."

Which is missing an 'are', as it should be:

"When searching the documentation, remember there are pages ..."

That's it. I'm liking the book very much, thanks!

Note from the Author or Editor:
On page 60, we wrote "remember that there pages".

It should say "remember that there are pages".

Kris van Rens  Dec 08, 2021 
PDF
Page 60
7th paragraph

“f64 (primitive type) => “f64 (primitive type)"

Sungmann Cho  Jun 28, 2021  Nov 05, 2021
Printed
Page 73
3rd paragraph, 1st sentence

“String literals” (two spaces) => “String literals”

xehpuk  Aug 03, 2021  Nov 05, 2021
Printed
Page 134
Precedence and Associativity, first sentence

"Table 6-1 summarizes of Rust expression syntax." => "Table 6-1 summarizes Rust's expression syntax."

Anonymous  Aug 15, 2021  Nov 05, 2021
Page 134
Precedence and Associativity

The text reads "Operators are listed in order of precedence." But that would imply that Multiplication was higher precedence than Division because it is higher in the order. It should say "Operators are grouped in order of precedence." to be accurate.

Note from the Author or Editor:
The language describing the table is imprecise.

Some operators have the same precedence. For example, `*` `/` and `%` all have the same precedence. The horizontal lines in Table 6-1 separate operators with different precedence, dividing the operators into groups. The groups are arranged from highest precedence to lowest. Within each group, there's no particular significance to the order the operators are listed.

Peter Jurgensen  Jul 02, 2024 
Printed
Page 152
Assignment, third paragraph

"The full list is given in Table 6-1, at the end of this chapter", but the table starts on page 135 at the beginning of the chapter.

Anonymous  Aug 15, 2021  Nov 05, 2021
Printed
Page 163
println!() code block

“failed to lookup” => “failed to look up”

xehpuk  Aug 07, 2021  Nov 05, 2021
Page 178
last paragraph

two functions in this example -> three functions in this example

Note from the Author or Editor:
On page 178, in "Modules", the text refers to "the two functions in this example". A careful count of the functions in the example reveals that there are three of them. The text should say "the three functions in this example".

Sungmann Cho  Aug 23, 2021 
Page 196
1st paragraph

Instead of
`cargo test -- --no-capture`
it should be
`cargo test -- --nocapture`

See `cargo test -- --help`

Note from the Author or Editor:
On page 196, the command-line option that causes Cargo not to capture test output is incorrect. We wrote "--no-capture". The correct option is "--nocapture". There is no hyphen between "no" and "capture".

Martin  Nov 06, 2022 
Page 239
Bottom

Chapter 10

"Naturally, this assignment transfers ownership of jupiter_node and mercury_node to their new parent node."

s/jupiter_node/jupiter_tree/
s/mercury_node/mercury_tree/

Note from the Author or Editor:
The text refers to `jupiter_node` and `mercury_node`, but the variables are actually named `jupiter_tree` and `mercury_tree`.

Joe Bowbeer  Jun 15, 2024 
Page 246
4th paragraph

"so slice patters"

s/patters/patterns/

Joe Bowbeer  Jun 16, 2024 
PDF
Page 249
8th paragraph

iit's unpacking -> it's unpacking

Sungmann Cho  Jun 28, 2021  Nov 05, 2021
Page 257
Trait Object Layout

At the very beginning of section: "Trait Object Layout"

Should the quoted text "In memory, a trait object is a fat pointer" be "In memory, a reference to trait object is a fat pointer"? I think that would be more accurate.

Note from the Author or Editor:
This is correct. At the time we wrote this, it was common to use "trait object" to refer to the reference itself, but the terminology has evolved over time and now "trait object" refers to the referent. We'll update the text in the next edition of the book.

Joshua Tang  Jan 27, 2023 
PDF
Page 263
1st paragraph

tthe -> the

Sungmann Cho  Jul 01, 2021  Nov 05, 2021
Page 266
Last sentence

I don't understand the meaning of the sentence. It's exactly the same syntax as used in the example above, with `str` instead of `char`.

Note from the Author or Editor:
On page 269, in "Traits and Other People's Types", we wrote "Of course, you can add this trait to types, too, ...". A word is missing in that sentence; it should begin "Of course, you can add this trait to other types, too, ...".

xehpuk  Aug 22, 2021 
Page 270
1st paragraph, 2nd sentence

The sentence says that `Creature` is a subtrait and supertrait of `Visible`, while the latter is the supertrait.

Note from the Author or Editor:
On page 270, in "Subtraits", we wrote: "...we say that `Creature` is a subtrait of `Visible`, and that `Creature` is `Visible`’s supertrait."

The second half of the sentence should say, "...and that `Visible` is `Creature`'s supertrait." We got it backwards.

xehpuk  Aug 22, 2021 
Page 306
Last paragraph.

The following is incorrect or requires more clarification since the `Box` is sized and makes it possible to invoke a method:

"...nor can you invoke a method on a `Box<dyn Write>`..."

Given the presented comparison between sized and unsized types, the correction would be:

"...nor can you invoke a method on a `dyn Write...`"

Note from the Author or Editor:
This remark is accurate. We've changed the text to say `dyn Write` rather than `Box<dyn Write>`.

Anonymous  Feb 02, 2024 
Page 310
First sentence of the second to last paragraph

The following text

> The deref and deref_mut methods take a &Self reference and return a
&Self::Target reference.

should be changed to

The deref method takes a &Self reference and returns a
&Self::Target reference, while deref_mut takes a &mut Self and returns a &mut Self::Target.

Note from the Author or Editor:
It's true, `Deref` uses shared references and `DerefMut` uses `mut` references. We will update the book.

Yang Shuai  Aug 20, 2021 
Page 332
Two paragraphs before the section "Closure Performance"

"a closure is callable, but it's not a fn"

Suggested: "a closure is a callable, but it's not an fn if it captures from its environment"

Note from the Author or Editor:
In the chapter on closures, we wrote "a closure is callable, but it's not a `fn`." It should read "a closure is callable, but it's not necessarily a `fn`; a closure can be used as a `fn` only if it doesn't capture any variables."

Note that a closure that doesn't capture any variables still has its own type, distinct from all other `fn` types and closure types, as the subsequent text explains. But Rust lets you pass such a closure to places where a function pointer is expected, automatically converting the (zero-sized) closure to a (word-sized) function pointer.

Jorge Rinaldi  Aug 22, 2022 
Page 378
Code block in try_fold and try_rfold section

While not a compile error, this line has an unnecessary ‘&’ reference:

Ok(sum + u64::from_str(&line?.trim())?)

This probably should be:

Ok(sum + u64::from_str(line?.trim())?)

Note from the Author or Editor:
Yes, the `&` in that line of code is superfluous and should be removed:

Ok(sum + u64::from_str(line?.trim())?)

Pete Kazmier  Sep 13, 2021 
Page 402
slice.rsplit(is_sep), slice.rsplit_mut(is_sep)

The description for these methods refers to slice and slice_mut as analogous methods when in fact they are called split and split_mut (which are covered immediately above on the same page).

Note from the Author or Editor:
On page 402, where we describe `slice.rsplit` and `rsplit_mut`, we say that these two methods are "Just like `slice` and `slice_mut`, but start at the end of the slice."

It should read "Just like `split` and `split_mut`, but start at the end of the slice."

D Patrick  Sep 17, 2021 
Page 431
Bottom table, last column

In the table 17-2, in the row of ch.is_ascii_digit(), there is a formatting issue in the 'Examples' cell on the right. The example "!'-'.is_ascii_digit()" is formatted as regular text, while it should be a fixed-width font.

Note from the Author or Editor:
In Table 17-2, one of the examples illustrating `is_ascii_digit` is shown in a variable-width font.

There is not in fact anything special about this example. All of the examples should be in the fixed-width font we use for code.

Kris van Rens  Jan 20, 2022 
PDF
Page 442
6th paragraph

Returnsan -> Returns an

Sungmann Cho  Jul 04, 2021  Nov 05, 2021
Page 452-456
Tables 17-4, 17-5, 17-6, 17-7

Some formatted strings which have minimum widths applied are displayed with fewer spaces than should actually be output.

For example (from table 17-4), format!("{:8.2} km/s", 11.186) should result in " 11.19 km/s" (prefixed with 3 spaces) but is shown with just a single space at the beginning.

This seems to be consistent across all examples that would require more than one consecutive space in the output.

Note from the Author or Editor:
What an embarrassing error! We have tests for almost everything in the book, including these tables, but they failed to detect this problem. The important spaces here were stripped due to a tooling issue; the "source code" of the book is correct. It slipped past our human reviewers as well.

We've fixed it for future printings.

D Patrick  Sep 20, 2021 
Page 485
io::stdin() section

It is no longer necessary to split the `io::stdin()` call from a `lock()` call, and likewise for `io::stdout(), io::stderr()`. The following compiles fine on the Rust playground:

```
use std::io::{stdin, BufRead};

fn main() {
let lines = stdin().lock().lines();
for line in lines {
println!("{}", line.unwrap())
}
}```

Note from the Author or Editor:
That's right, the paragraph about `io::stdin().lock()` not working is no longer correct. We've removed that paragraph and tightened up some example code that can take advantage of `io::stdin().lock()`.

Anonymous  Nov 19, 2022 
PDF
Page 492
last paragraph

wha tever -> whatever

Sungmann Cho  Jul 09, 2021  Nov 05, 2021
Page 550
Figure 20-2 and 2nd paragraph

`async_std::block_on` -> `async_std::task::block_on`

Note from the Author or Editor:
On page 548, in "Calling Async Functions from Synchronous Code: block_on", Figure 20-2 and the accompanying text refer to `async_std::block_on`.

The actual name of the function is `async_std::task::block_on`.

Sungmann Cho  Jan 31, 2024 
Printed
Page 606
Table 21-1

On page 606, in Table 21-1, the last three rows of the table are incorrect.

We listed `$( ... ),?` and `$( ... );?` as matching "0 or 1 times, separated by commas" or semicolons. Clearly that doesn't make sense. There is no such syntax in Rust. The last two rows of the table should be deleted.

The last remaining row, `$( ... )?`, should be labeled "Match 0 or 1 times" (deleting the words "with no separator").

Thanks to Sofiane Akermoun for reporting this issue.

Jason Orendorff
 
Apr 08, 2024 
Page 642
1st paragraph after bullet points

"the offset_from method gives the distance between two pointers in bytes"

The distance indicated by offset_from<T>(self, origin: *const T) is NOT in bytes, but in units of T.

Note from the Author or Editor:
On page 640, in "Raw Pointers", we wrote that "the `offset_from` method gives the distance between two pointers in bytes, though we're responsible for [...]".

This is wrong. The distance returned is the number of elements, not the number of bytes.

The text should read "the `offset_from` method gives the number of elements between two pointers, though we're responsible for [...]".

Tom  Jun 22, 2022 
Page 642
Penultimate paragraph

'In "A Safe Interface to libgit2" on page 681 later in this chapter,'

That section was moved to a separate "Foreign Functions" chapter.

Note from the Author or Editor:
The words "later in this chapter" should have been removed.

Rob Montroy  May 13, 2024 
PDF
Page 663
1st paragraph

missing opening double quote

Sungmann Cho  Jul 11, 2021  Nov 05, 2021
Page 688
Second to last parag

The text in the book is "The RefWithFlag example earlier in this chapter", but the RefWithFlag example was introduced one chapter before - in Chapter 22 about unsafe code.

so
"The RefWithFlag example earlier in this chapter" -> "The RefWithFlag example earlier in the previous chapter"

Pavel Shirshov  May 29, 2022 
Page 693
Index -> Symbols -> "=> operator"

The index lists the "=>" operator with page 152, but this page/section is for "Arithmethic, Bitwise, Comparison, and Logical Operators". The correct page should be 141 which talks about "if and match" (page 140 ff.).

Note from the Author or Editor:
This index entry should appear under ">= operator", not "=> operator". We've fixed it for future printings and added an entry for "=> symbol", as follows:

=> symbol
in macros, 602, 616
in match expressions, 141, 241
> operator, 152, 297
>= operator, 152, 297

Anonymous  Jul 24, 2022 
Page 714
About the Authors

s/renderiing/rendering/

Note from the Author or Editor:
The word "rendering" was misspelled in Jim's bio.

Joe Bowbeer  Jun 26, 2024