Errata

Programming Rust

Errata for Programming Rust

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
ch4 Ownership
In Rust example after Python and C++ examples, explaining `let t = s;`

This portion should be made clearer, the text reads "So after initializing t, the program’s memory looks like this:" However, the program's memory will never 'look like' anything--as noted in a later paragraph, the program fails to compile. This should be addressed with some comment earlier. Perhaps, after showing the 'equivalent' Rust code, saying something like, "Now, for reasons we will explain for a moment, this code will fail to compile if you're typing it in yourself. However, let's imagine that we could get this code to compile and run..."

Note from the Author or Editor:
The text is okay as it stands; the reader doesn't like the flow we chose. I'll look this over if we do a second edition.

Frederick Kellison-Linn  Nov 22, 2017  Jun 22, 2018
Chapter 2: A Tour of Rust
A Concurrent Mandelbrot Program section

let bounds = parse_pair(&args[2], 'X')
.expect("error parsing image dimensions");
should be
let bounds = parse_pair(&args[2], 'x')
.expect("error parsing image dimensions");

i.e. separator character should be lower-case x to match with example command line.

Note from the Author or Editor:
In Chapter 2, the section titled "A Concurrent Mandelbrot Program", the capitalization of the 'x' in the code example is incorrect on Safari, even though it is correct in the HTML on Atlas and in the PDF. It should be lower-case, but on Safari only it is upper-case.

Jai Sharma  Jan 13, 2018  Aug 30, 2019
Figure 17-1
UTF-8 Subsection

Figure 17-1. The UTF-8 encoding in the Code Point Represented column, third row the value should be 0xxxxyyyyyyzzzzzz, instead of the current 0xxxyyyyyyzzzzzz which is missing an x.

Jai Sharma  Jan 31, 2018  Jun 22, 2018
ch15
first example in "position, rposition, and ExactSizeIterator"

'E' is used, but it appears 'e' was intended.

Current (this assertion fails):

assert_eq!(text.chars().position(|c| c == 'E'), Some(1));

Expected (this assertion succeeds):

assert_eq!(text.chars().position(|c| c == 'e'), Some(1));

Note from the Author or Editor:
Safari is corrupting code examples by capitalizing text at random.

Michael Bolin
Michael Bolin
 
Feb 01, 2018  Aug 30, 2019
ch15
second example in "position, rposition, and ExactSizeIterator"

Current. These do not parse because of the capital B. After fixing that, the first assertion still fails because it is a capital E instead of a lowercase one.

assert_eq!(bytes.iter().rposition(|&c| c == B'E'), Some(4));
assert_eq!(bytes.iter().rposition(|&c| c == B'X'), Some(0));

Expected (lowercasing, as appropriate, and now these assertions work):

assert_eq!(bytes.iter().rposition(|&c| c == b'e'), Some(4));
assert_eq!(bytes.iter().rposition(|&c| c == b'X'), Some(0));

Note from the Author or Editor:
In Chapter 15, the two code examples in the section "position, rposition, and ExactSizeIterator" are incorrect on Safari, but correct in the PDF and MOBI. The letters in single quotes, and the 'b' in front of them should be as follows:
'e', not 'E'
'z', not 'Z'
b'e', not B'E'
b'X' (this one is correct)

But, making Safari accurately reflect the contents of the Atlas HTML should correct this.

Michael Bolin
Michael Bolin
 
Feb 01, 2018  Aug 30, 2019
Chapter 3 - Floating Point Section

The "Floating point" section within chapter 3 has a possible error.

If the intention of the following statement:

assert_eq!(-1.01f64.floor(), -1.0);

is supposed to yield true, then the 2nd argument should be -2.0.


Note from the Author or Editor:
Fixed on master.

James Davis  Feb 20, 2018  Jun 22, 2018
ePub
Page Figure
19-5

In the figure both threads are named "thread 1", whereas the bottom one should be named "thread 2".

Note from the Author or Editor:
Confirmed: in Figure 19-5, the lower thread (horizontal blue bar) should be labeled "thread 2", not "thread 1".

Fixed in 1st and 2nd edition.

Samir Saeedi  Dec 30, 2018  Aug 30, 2019
Utility Traits > Borrow and BorrowMut

Wrong, currently in print: String implements AsRef<&str>
Correct: String implements AsRef<str>

Note from the Author or Editor:
Fixed in 1st and 2nd edition.

Anonymous  Mar 21, 2019  Aug 30, 2019
chapter 11
Middle of the chapter (I'm reading the book on safarionline)

trait WriteHtml {
fn write_html(&mut self, &HtmlDocument) -> io::Result<()>;
}

I think the code above should've been written like this:

/// Trait for values to which you can send HTML.
trait WriteHtml {
fn write_html(&mut self, html: &HtmlDocument) -> io::Result<()>;
}

Note from the Author or Editor:
Fixed in current text. No further changes needed.

Jingjing Duan  Dec 07, 2019 
ch2
Code block for `escape_time`

In the listing of the `escape_time` function, there is a line `z = z*z + c;`. In the previous listings, similar lines were formatted with a space around the asterisk, i.e. as `z = z * z + c;`.

Frederick Kellison-Linn  Nov 20, 2017  Jun 22, 2018
ch3 Tuples
after 3rd code snippet

"in Chapter 2, we need to pass" -> "in Chapter 2, we needed to pass"

Frederick Kellison-Linn  Nov 20, 2017  Jun 22, 2018
16
Chapter 16 Vect<T> section

let mut buffer = vec![0u8; 1024]; // 1024 zeroed-out bytes
The variable name 'buffer' in the above code snippet doesn't match the one in figure 16-1 which uses 'buf' instead.

Note from the Author or Editor:
In Figure 16-1, at the top right, "buf" should be changed to "buffer".

Jai Sharma  Jan 24, 2018  Jun 22, 2018
Printed
Page 17, 161-
First para if "A Simple Web Server", and probably most of chapter "Crates and modules"

The book doesn't distinguish between packages and crates. On p17 "A Simple Web Server", it states

"A Rust package, whether a library or an executable, is called a crate"

However, in a discussion on rust-lang github https://github.com/rust-lang/cargo/issues/3380, they do distinguish between packages and crates.

This distinction doesn't appear to be used in the chapter "Crates and modules" starting on p161 either.

I don't have a recommendation here, as I don't understand what the truth of the matter is. However, there does appear to be a contradiction.

Note from the Author or Editor:
To be completely honest, the distinction drawn in that github issue is not one we were aware of when writing the book at all. (Since it wasn't even explained in the cargo docs, maybe we get a pass?) The book uses the term 'package' in the generic sense of 'a grouping of code', but if 'package' is actually Rust terminology, then we should rephrase the text in the book to respect that.

We'll fix this in the second edition, but not the first. Filed as issue #425.

Joel  Aug 17, 2019 
Printed
Page 18
code snippet

In the code snippet, in the HTML of the page being served, both the inputs have name "n". That seems to be a typo. Input's name is used to refer to the element and its value; two inputs on the form having the same name is a bug. Also, the gcd function written earlier has two parameters named n and m, so it only makes sense for the inputs to have the same names: n and m.

Note from the Author or Editor:
Although this use of <input> names is contrary to recommended practice on the web, the doubled name is deliberate, the program actually does work as written, and the code is shorter because of it. However, many people have complained about it, so this section will probably need to be reworked anyway.

Filed as issue #420, to be fixed in 2nd edition.

owlish  Feb 03, 2019 
Printed
Page 42
Code block

The function `parse_pair` has a bug. Indices on Strings in Rust correspond to byte offsets, but the String data is stored as UTF8. Thus, some characters are more than one byte. Indexing to a non-character boundary will panic (abort the program).

The code uses `&s[index+1..]`. It should instead use `&s[index + separator.len_utf8()]`.

This bug came up in an online Rust users forum:
https://users.rust-lang.org/t/something-wrong-in-function/51847

I am not an owner of the book and there is a language barrier at play, so please note that I am uncertain which formats have the bug / which format corresponds to page 42.

Note from the Author or Editor:
Thanks for pointing this out. It's true that the function will panic if `separator` is not an ASCII character. I think I'd rather document that restriction than complicate the code.

Anonymous  Nov 24, 2020 
Printed
Page 51
3rd para

On p50 it says floating point literals are inferred as f64 if both are possible. On p51 it then says
`println!("{}", (2.0).sqrt())` won't compile. These are contradictory. Both f32 and f64 are possible here, so it should infer f64 by the previous page's logic. Thus one of the pages is incorrect.

Moreover, this is reported as a bug against the compiler - see https://github.com/rust-lang/rust/issues/24124, which leads me to believe a compiler bug is being presented as expected, even logical, behaviour.

Note from the Author or Editor:
It's true that it's been reported as a bug, but no Rust team member has confirmed that it's unintended behavior. I think the text is just unclear as to why this doesn't work. I certainly didn't intend to present it as particularly logical.

Addressed in 2nd edition; won't fix in 1st.

Anonymous  Jan 28, 2019 
PDF
Page 55,470
7rd paragraph

"write_bitmap" should be changed to "write_image".

Note from the Author or Editor:
Fixed on master.

Sungmann Cho  Apr 29, 2018  Jun 22, 2018
Printed
Page 74
Caption of Figure 4-2

"A Vec 32 ..." should be "A Vec<32> ...".

Note from the Author or Editor:
We have a fix for this.

Glyn Normington  Jan 18, 2018  Jun 22, 2018
Mobi
Page 85
That's not page 85 (Kindle doesn't give me page numbers), but Kindle location

The book says

Supplemental material (code examples, exercises, etc.) is available for download at https://github.com/oreillymedia/programming_rust

Going there gives a 404. Searching https://github.com/oreillymedia for "rust" gives no repos.

Note from the Author or Editor:
This is on page xviii of the print book. The URL should be changed to: https://github.com/ProgrammingRust

(Note: When this was reported, the URL in the book was broken. Readers would see a 404 Not Found. Now they'll see a README that links to the correct URL, which is not so bad. Still worth fixing.)

Yarrow Angelweed  Dec 03, 2017  Jun 22, 2018
PDF
Page 88
2nd to last paragraph

"i32 with pretensions" should be "u32 with pretensions"

Note from the Author or Editor:
Fixed on master.

Joe Gilray  Mar 04, 2018  Jun 22, 2018
PDF
Page 111
bottom code example

The book says that the example in the "Distinct Lifetime Parameters" section does not compile. But it compiles just fine on the stable compiler in Rust playground.

I think the argument is incorrect. On page 112 the book says: "We assign r = s.x , requiring 'a to enclose r ’s lifetime." I think that's backward. I think 'a must be no larger than r's scope, which is easily satisfied with a lifetime which simply includes the whole inner scope.

Note from the Author or Editor:
The reader is correct: the book says that code doesn't compile, but it does with recent versions of Rust. This is because the borrow checker has been improved: despite its scope `r` is never actually used beyond the lifetime of `y`, so the borrow checker concludes that the lifetime of the two references in `S` does not actually extend too far to be safe.

We have tests that check that the examples in the book actually fail with the errors we claim that they should, and those tests alerted us to these problems a while ago. They will be fixed in the second edition, currently in progress.

themulhern  Apr 08, 2019 
Printed
Page 113
First paragraph

"In the simplest case, if your function doesn't return any references (or other types that require lifetime parameters), then you never need to write out the lifetimes for your parameters."

This code that mutates a struct, but doesn't return anything, doesn't compile ...
```
fn main() {
let mut s = S {x: &0};
println!("{}", s.x);
func(&1, &mut s);
println!("{}", s.x);
}

struct S<'a> {
x: &'a i32
}

fn func(i: &i32, s: &mut S) {
s.x = i;
}
```
but does if I add lifetime paramaters to func:
```
fn func<'a>(i: &'a i32, s: &mut S<'a>) {
s.x = i;
}
```

Note from the Author or Editor:
The reader is correct - the text is wrong. For the assignment of `i` to `s.x` to be safe, `i`'s lifetime must enclose that of `s`.

I think actually characterizing the exact circumstances under which you can get away with omitting all your lifetime parameters is not actually helpful; people should just know that it's sometimes possible to omit them, and Rust will let you know when they're needed. So I've just dropped the qualifying phrase about return value types.

Fixed in 1st and 2nd edition.

Joel  May 12, 2019  Aug 30, 2019
PDF
Page 119
C++ code snippet

File& operator=(const File &rhs) {
close(descriptor);
descriptor = dup(rhs.descriptor);
}

The operator must return *this:

File& operator=(const File &rhs) {
close(descriptor);
descriptor = dup(rhs.descriptor);
return *this;
}

Note from the Author or Editor:
Reader is correct. We will fix in HTML.

Andrei  Feb 08, 2018  Jun 22, 2018
Printed
Page 138
Second paragraph of "Assignment" section

"As described in Chapter 4, assignment moves values of noncopyable types, rather than implicitly copying them."

I find this sentence confusing. It could imply "there are places where noncopyable types can be copied, but assignment isn't one of them", whereas I think the intention is for "rather than implicitly copy them" to contrast noncopyable with copyable types. Perhaps something along the lines of

"As described in Chapter 4, assignment moves values of noncopyable types, and implicitly copies values of copyable types."

Note from the Author or Editor:
I guess I agree that the qualifying phrase 'rather than implicitly copying them' is confusing, as it's referring to copying a non-copyable value, with 'implicitly' suggesting that there's some secret way to do it anyway. There isn't. I'll try to rephrase this.

Fixed in 1st edition and 2nd edition.

Joel  Aug 04, 2019  Aug 30, 2019
Printed
Page 164
Table in section "Build Profiles"

The Cargo.toml section used for the command line "cargo build" is [profile.dev] instead of [profile.debug]

Note from the Author or Editor:
Fixed on master.

Stefan Achatz  Feb 12, 2018  Jun 22, 2018
PDF
Page 195
The last sentence of the 2nd paragraph.

The last sentence "Suppose we have a struct representing a monster in a game" of the 2nd paragraph seems to be out of context. It looks like some codes related to the monster should be presented, but what is actually presented is the broom struct for "The Sorcerer’s Apprentice".

Note from the Author or Editor:
Well, the idea here was that, in the context of the Sorcerer's Apprentice story, the broom really is a sort of monster. But yes, if you're not expecting it the transition is a bit abrupt. I've added a little comment to the code that will hopefully make it clearer.

This should be fixed in the 1st and 2nd editions.

Sungmann Cho  Sep 15, 2018  Aug 30, 2019
Printed
Page 205
3rd paragraph

It says "PartialCmp", while the correct name of the trait is PartialOrd.

Note from the Author or Editor:
"PartialCmp" should be changed to "PartialOrd".

Ulrik Sverdrup (bluss)  Jan 26, 2018  Jun 22, 2018
Printed
Page 206
3rd paragraph

The book says: "There's a problem: a File has to be mut".

The type shared-reference-to-File implements Read/Write, so it does not need to be mutable to be used for reading or writing. It is not obvious or elegant, but it works.

Note from the Author or Editor:
The reader is correct, but the information he's citing is so obscure that I don't think this will affect the effectiveness of the explanation in the book in practice. (If you know enough to notice the problem the reader pointed out, you definitely don't need to read that part of the book.)

Since fixing this will require a significant rephrasing of the section, we'll leave this for a second edition.

Ulrik Sverdrup (bluss)  Jan 26, 2018  Jun 22, 2018
Printed
Page 228
Figure 10-7

The pattern in fig 10-7 seems to have a typo: "&Point3d { x, y, x }" should be "&Point3d { x, y, z }".

Jussi Kukkonen  Mar 04, 2018  Jun 22, 2018
Printed
Page 261
2nd paragraph

Duplication of word in first sentence: "that that".

Note from the Author or Editor:
Fixed on master.

Andre Richter  Mar 05, 2018  Jun 22, 2018
ePub
Page 268
last paragraph

The statement "All of Rust’s numeric types implement std:: ops:: Neg, for the unary negation operator -;" probably is incorrect. My understanding is that the unary negation operator is implemented only for signed types, and that it is not implemented for the unsigned integer types u8, u16, u32, u64, u128, and usize because these types cannot represent negative numbers.

Note from the Author or Editor:
This is at the top of page 269 in my copy. "All of Rust's numeric types" should read "All of Rust's signed numeric types".

Tom Phinney  Jan 27, 2018  Jun 22, 2018
PDF
Page 269
2nd code snippet

The code snippet is described as "how we might write a generic implementation of negation for Complex values". The code shown uses two generic type parameters T and O. However, there's no need to use two as using two suggests that the example is a mixed-type operation with a different output type. It seems better to use a simpler example.

I was able to implement Neg for my own custom type with just one type parameter. The source code of the num-complex crate also uses just one type parameter T when implementing Neg for Complex<T>. See https://github.com/rust-num/num-complex/blob/0a381f37cb9dda65b74584f3fbed6460dcb80893/src/lib.rs#L684 for reference.

Note from the Author or Editor:
I agree: throughout the chapter we don't worry about mixed-type operations, comparisons, and so on, and we'd just explained why a fully generic `Add` implementation wasn't really worthwhile, so there's no reason to break the pattern here.

The fully-generic `Add` implementation can also be simplified; it really needs only two type parameters, not three.

The text isn't incorrect, just not as simple as it could be, so this can wait to be fixed in the 2nd edition.

Michael Galero  Oct 26, 2018 
ePub
Page 269
Code between 1st and 2nd paragraph

In the last line of code, 'assert_eq!(r + &1009, 1729)', it looks like we are in danger of checking equality between references to integer values, i.e. &factorial(6) and &1009, and the integer value 1729. Instead, the '+' operator seems to be able to is deference up to 1 time, to add the referred-to values and return the answer as a value, so that the assert_eq! works with operands of the same type. I don't think the deferencing behaviour of the '+' operator had previously been mentioned in the text. Minor point, but it did take a bit of thinking to figure out. Thanks for a great book!

Duane  Nov 21, 2017  Jun 22, 2018
PDF
Page 273

code fragment

where Rhs: ?Sized

this does not appear in the previous code.
In p.272, we have

trait PartialEq<Rhs: ?Sized = Self> {

instead.

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
Printed
Page 306
First code example

In this code example:

fn sort_by_statistic(cities: &mut Vec<City>, stat: Statistic {
cities.sort_by_key(|city| -city.get_statistic(stat));
}

and this similar one on the following page:

fn start_sorting_thread(mut cities: Vec<City>, stat: Statistic)
-> thread::JoinHandle<Vec<City>>
{
let key_fn = move |city: &City| -> i64 { -city.get_statistic(stat) };
thread::spawn(move || {
cities.sort_by_key(key_fn);
cities
})
}

regardless of how the "stat" variable is captured by the closure, it should be passed by reference
to city.get_statistic. I think this code could not pass the borrow checker unless Statistic was a
copyable type, but the context of these examples and the discussion on page 307 implies that
Statistic is not Copy.

Note from the Author or Editor:
Thank you for the report. Statistic was Copy in my head (my test code is like this: <https://gist.github.com/jorendorff/c04b6a2b56db051e0493de13acb77df0#file-closures-rs-L81-L86>) but you're right, the text then talks about the closure borrowing or gaining ownership of it, when for Copy types Rust would be happy to just copy the thing instead.

The easiest fix is to make Statistic non-Copy and fix up all the code. Better, rework the example, replacing Statistic with something concrete enough that readers can intuitively guess it's not Copy.

Will fix in 2nd edition, but not 1st.

Tim Crews  Nov 05, 2018 
PDF
Page 330
Last paragraph, first sentence

The sentence "The iterator map returns is, of course, itself a candidate for further adaptation." should be "What the iterator map returns is, of course, itself a candidate for further adaptation.". That is, it should have a "What" in the beginning of the sentence.

Note from the Author or Editor:
This isn't right: in the suggested correction, the subject of 'returns' is 'the iterator `map`' - but `map` is not an iterator, it is an adaptor method that returns an iterator. But I've edited the sentence to read:

The iterator that `map` returns is, of course, itself a candidate for further adaptation.

I think this should be clearer.

Fixed in 1st and 2nd editions.

Michael Galero  Nov 11, 2018  Aug 30, 2019
PDF
Page 354
the first paragraph

'And like collect, you’ll need to specify the return type: the preceding example writes out the type of living and nonliving, and lets type inference choose the right type parameters for the call.'

The type of 'nonliving' is not wrote out in the code. I think this is confusing.

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
Page 354
4th paragraph (after the listing of the partition signature)

The explanation of the partition signature mentions the return type's trait bounds to implement std::default::Extend, whereas it should be std::iter::Extend.

Note from the Author or Editor:
`std::default::Extend` is indeed wrong. We've fixed it for future printings.

Christopher Mühl  May 20, 2024 
PDF
Page 368
last line of the last bullet point

The correct return type of split_last() is Option<(&T, &[T])>, and not Option<(&[T], &T)> that's in the book.

Note from the Author or Editor:
The reader is correct. This is fixed in the first and second editions.

Michael Galero  Oct 03, 2018  Aug 30, 2019
PDF
Page 375
Page 375(353) ch15 End of section 'Building Collections: collect and FromIterator'

let args = std::env::args().collect::<String>();
->
let args = std::env::args().collect::<Vec<String>>();

Note from the Author or Editor:
That's right: near the top of page 353, the line that reads

let args = std::env::args().collect::<String>();

should read

let args = std::env::args().collect::<Vec<String>>();

Yisheng XU  Nov 28, 2017  Jan 05, 2018
PDF
Page 378
Figure 16-5 and Figure 16.6

1. page 379 description of figure 16-6
2. page 378 description of figure 16-5
`dark gray regions are unused`

should be `dark blue regions are unused`?

and in figure 16-5, the unused regions are not filled with dark blue

Also, most figures about memory layout are blue-colored, except figure 11-1

Note from the Author or Editor:
Indeed, the dark and light areas in Figure 16.5 seem incorrect. We'll send you an exact description of what needs to be changed.

Yisheng Xu  Nov 30, 2017  Jun 22, 2018
PDF
Page 378
the last paragraph

'Dark gray regions are unused.'

There are no 'dark gray regions' in Fig. 16-5.

And, the diagram shown in 16-5 is quite different from typical hash table implementation. I believe some more explanation is required.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
Printed
Page 381
Bullet point after second paragraph

Text refers to btree_map.split_at but it should be btree_map.split_off (BTreeMap has no split_at method).

Note from the Author or Editor:
Confirmed. On p. 415,

btree_map.split_at(&key)

should have been

btree_map.split_off(&key)

The index entry should also be updated.

Tyson Nottingham  Jul 05, 2020 
PDF
Page 395
the first paragraph

'These all draw their definitions from Unicode, as shown in Table 17-0.'

The table below is missing caption and table number.
and I believe the table number 17-0 is strange.

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
PDF
Page 398
"Creating String Values" section, bullet points

The list enumerates "a few common ways to create String values". It's a little strange that the list doesn't include `String::from` and `format!`.

Note from the Author or Editor:
Fair; those are both quite common ways of creating strings. I'll fix this in the second edition.

Left unfixed in 1st edition.

Michael Galero  Oct 03, 2018 
Printed
Page 400
Code snippet above second paragraph from the bottom of the page

let parenthetical = "(".to_string() + string + ")";

will produce: expected &str, found struct `std::string::String`

It should instead be: let parenthetical = "(".to_string() + &string + ")";

Note from the Author or Editor:
Fixed on master.

Petros Angelatos  Feb 03, 2018  Jun 22, 2018
PDF
Page 408
in the middle.

'as we did for the `Complex` type earlier in the book:'

I could not find the same code in other sections.

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
PDF
Page 409
the first sentence

'as do the functions like [T]::binary_search.'

I seems that binary_search method is not using Borrow Trait.

https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
PDF
Page 410
the last paragraph

"The nub of the problem is that sometimes the return value of `name` should be..."


The function name is 'get_name', not 'name'.

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
PDF
Page 434
4th paragraph

reader.read_to_end returns type of io::Result<usize> rather than io::Result<()>.

Note from the Author or Editor:
The sentence "Returns io::Result<()>." should be changed to: "Returns an `io::Result<usize>`, the number of bytes read."

HoNooD  Jan 22, 2018  Jun 22, 2018
PDF
Page 463
4th paragraph from back

"The closure we passed to spawn has a return type of io::Result<()>. because that’s what process_files returns."

The first period should be a comma instead.

HoNooD  Feb 01, 2018  Jun 22, 2018
PDF
Page 476
2nd paragraph

The paragraph describes that "all the work [...] is done by the function make_single_file_index". However, there's no make_single_file_index function call in the code being described in the previous page (page 475). It seems it's referring to `InMemoryIndex::from_single_document` function call that returns the index. Perhaps the code has changed but the paragraph wasn't updated.

Note from the Author or Editor:
Yes - this will be fixed in both the first and second editions.

Michael Galero  Oct 03, 2018  Aug 30, 2019
PDF
Page 490
Title of sub sub section

'Multi-producer Channels Using Mutexes'


'Multi-producer' should be 'Multi-consumer'

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
PDF
Page 491
figure

The Figure 19-11 is missing caption

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
Printed
Page 512
code snippet, top of the page

In the unit test, when the variable 'hand_coded_value' is assigned, I think there is an .into_iter() missing before .collect().

Note from the Author or Editor:
The reader is correct, the code should read .into_iter().collect().

We didn't catch the problem because, although our tests for the book do verify that compilation fails at the attempt to expand the `json!` macro, as the text claims, that means the test never gets as far as actually compiling the rest of the code, where the type error would come to light.

This is fixed in the 1st and 2nd editions.

Jerry  Sep 18, 2018  Aug 30, 2019
PDF
Page 522
Just above Figure 20-4

'This feature supports extending the #[derive] attribute to handle custom traits, as shown in Figure 20-4.'


'custom traits' should be 'custom derives'.

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
PDF
Page 531
the second to last paragraph

'But the comment above the definition of the Ascii type says, “Nothing in this module permits the introduction of non-ASCII bytes into an Ascii value.” '

I could not find this comment in this book.


Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
PDF
Page 543
the last sentence of the third paragraph

'Rust infers that the reference’s lifetime must be the RefWithFlag’s argument, which is just what we want: that’s the lifetime of the reference we started with.'

I could not really understand
'RefWithFlag’s argument'.
Do you mean '
RefWithFlag::new''s argument . ?

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
PDF
Page 543
l. -5

' How should Rust know that any restrictions apply to pab’s lifetime?'

'pab' should be 'ptr_and_bit'.

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
PDF
Page 543
last line

'If you omit the _marker field, Rust ...'

'_marker' should be 'behaves_like'.

Note from the Author or Editor:
Fixed on master.

HIDEMOTO NAKADA  Apr 30, 2018  Jun 22, 2018
PDF
Page 547
Figure 21-2

5 8 in the figure should be 8 5, since they are capacity and length.

HIDEMOTO NAKADA  May 01, 2018  Jun 22, 2018
Printed
Page 549
First bullet point

The book states: "After calling `read`, you must treat `*src` as uninitialized memory." However, the Rust language documentation says that `read` "leaves the memory in `src` unchanged" (see https://doc.rust-lang.org/std/ptr/fn.read.html).

It is not clear that `read` has any special "magic" causing the read-from memory to be treated as uninitialized. (For instance, reading from a type that implements `Drop` doesn't prevent that value from being dropped: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e99b12f481d74340fbfd13b9580f94d2 )

Note from the Author or Editor:
The text is not entirely correct. It's true that, in general, `std::ptr::read` should be treated as leaving the source uninitialized, but if the referent type is `Copy`, this is not true.

However, the text probably needs to be clarified. The reader was left with the impression that the book believes `std::ptr::read` modifies the memory somehow (it does not), and from their phrasing ("causing ... to be treated") I'm guessing that it wasn't clear that it's the *programmer* who must treat the memory as uninitialized, and that Rust itself isn't treating it any differently.

Will fix in 2nd edition. Filed as issue #424.

Kyle Strand  Apr 22, 2019 
Mobi
Page 17115
Figure 17-2

(I only used mobi file so I'm not sure the page number in PDF or printed book)
In the figure, '寂' is explained like (sabi: rust).
But it's wrong.
'寂' means lonely.
The correct translation of rust is '錆'.

Note from the Author or Editor:
The Japanese character is correct in the PDF and in the HTML. There must be some problem in the production of the MOBI file.

Anonymous  Feb 21, 2018  Jun 22, 2018