Skip to content

Commit

Permalink
Backport fixes from NoStarch
Browse files Browse the repository at this point in the history
This is an exhaustive pass in preparation for going the *other* way for
the 2024 Edition print update, i.e. the Third Edition of the print book.
  • Loading branch information
chriskrycho committed Feb 10, 2025
1 parent bd5cb6b commit 2e1b7c7
Show file tree
Hide file tree
Showing 60 changed files with 510 additions and 506 deletions.
1 change: 1 addition & 0 deletions ci/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ grapheme
Grapheme
growable
gzip
handcoded
handoff
hardcode
hardcoded
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fn main() {
let lucky_number = 7; // Im feeling lucky today
let lucky_number = 7; // I'm feeling lucky today
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fn main() {
// Im feeling lucky today
// I'm feeling lucky today
let lucky_number = 7;
}
31 changes: 16 additions & 15 deletions listings/ch04-understanding-ownership/listing-04-04/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
fn main() {
let s1 = gives_ownership(); // gives_ownership moves its return
// value into s1
let s1 = gives_ownership(); // gives_ownership moves its return
// value into s1

let s2 = String::from("hello"); // s2 comes into scope
let s2 = String::from("hello"); // s2 comes into scope

let s3 = takes_and_gives_back(s2); // s2 is moved into
// takes_and_gives_back, which also
// moves its return value into s3
let s3 = takes_and_gives_back(s2); // s2 is moved into
// takes_and_gives_back, which also
// moves its return value into s3
} // Here, s3 goes out of scope and is dropped. s2 was moved, so nothing
// happens. s1 goes out of scope and is dropped.

fn gives_ownership() -> String { // gives_ownership will move its
// return value into the function
// that calls it
fn gives_ownership() -> String { // gives_ownership will move its
// return value into the function
// that calls it

let some_string = String::from("yours"); // some_string comes into scope

some_string // some_string is returned and
// moves out to the calling
// function
some_string // some_string is returned and
// moves out to the calling
// function
}

// This function takes a String and returns one
fn takes_and_gives_back(a_string: String) -> String { // a_string comes into
// scope
// This function takes a String and returns a String.
fn takes_and_gives_back(a_string: String) -> String {
// a_string comes into
// scope

a_string // a_string is returned and moves out to the calling function
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ fn first_word(s: &str) -> &str {
fn main() {
let my_string = String::from("hello world");

// `first_word` works on slices of `String`s, whether partial or whole
// `first_word` works on slices of `String`s, whether partial or whole.
let word = first_word(&my_string[0..6]);
let word = first_word(&my_string[..]);
// `first_word` also works on references to `String`s, which are equivalent
// to whole slices of `String`s
// to whole slices of `String`s.
let word = first_word(&my_string);

let my_string_literal = "hello world";

// `first_word` works on slices of string literals, whether partial or whole
// `first_word` works on slices of string literals, whether partial or
// whole.
let word = first_word(&my_string_literal[0..6]);
let word = first_word(&my_string_literal[..]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ fn main() {
let r1 = &s; // no problem
let r2 = &s; // no problem
println!("{r1} and {r2}");
// variables r1 and r2 will not be used after this point
// Variables r1 and r2 will not be used after this point.

let r3 = &mut s; // no problem
println!("{r3}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ fn dangle() -> &String { // dangle returns a reference to a String
let s = String::from("hello"); // s is a new String

&s // we return a reference to the String, s
} // Here, s goes out of scope, and is dropped. Its memory goes away.
} // Here, s goes out of scope, and is dropped, so its memory goes away.
// Danger!
// ANCHOR_END: here
// ANCHOR_END: here
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// ANCHOR: here
mod front_of_house {
pub mod hosting {
fn add_to_waitlist() {}
}
}

// -- snip --
// ANCHOR_END: here
pub fn eat_at_restaurant() {
// Absolute path
crate::front_of_house::hosting::add_to_waitlist();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// ANCHOR: here
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}

// -- snip --
// ANCHOR_END: here
pub fn eat_at_restaurant() {
// Absolute path
crate::front_of_house::hosting::add_to_waitlist();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ mod back_of_house {
}

pub fn eat_at_restaurant() {
// Order a breakfast in the summer with Rye toast
// Order a breakfast in the summer with Rye toast.
let mut meal = back_of_house::Breakfast::summer("Rye");
// Change our mind about what bread we'd like
// Change our mind about what bread we'd like.
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);

// The next line won't compile if we uncomment it; we're not allowed
// to see or modify the seasonal fruit that comes with the meal
// to see or modify the seasonal fruit that comes with the meal.
// meal.seasonal_fruit = String::from("blueberries");
}
2 changes: 1 addition & 1 deletion listings/ch08-common-collections/listing-08-12/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ fn main() {

let s = data.to_string();

// the method also works on a literal directly:
// The method also works on a literal directly:
let s = "initial contents".to_string();
// ANCHOR_END: here
}
2 changes: 1 addition & 1 deletion listings/ch15-smart-pointers/listing-15-26/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fn main() {
println!("a rc count after changing a = {}", Rc::strong_count(&a));

// Uncomment the next line to see that we have a cycle;
// it will overflow the stack
// it will overflow the stack.
// println!("a next item = {:?}", a.tail());
}
// ANCHOR_END: here
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use quote::quote;
#[proc_macro_derive(HelloMacro)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
// Construct a representation of Rust code as a syntax tree
// that we can manipulate
// that we can manipulate.
let ast = syn::parse(input).unwrap();

// Build the trait implementation
// Build the trait implementation.
impl_hello_macro(&ast)
}
37 changes: 19 additions & 18 deletions src/appendix-03-derivable-traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ that also implement `PartialEq`.
Deriving `PartialOrd` implements the `partial_cmp` method, which returns an
`Option<Ordering>` that will be `None` when the values given don’t produce an
ordering. An example of a value that doesn’t produce an ordering, even though
most values of that type can be compared, is the not-a-number (`NaN`) floating
point value. Calling `partial_cmp` with any floating point number and the `NaN`
floating point value will return `None`.
most values of that type can be compared, is the `NaN` floating point value.
Calling `partial_cmp` with any floating point number and the `NaN` floating
point value will return `None`.

When derived on structs, `PartialOrd` compares two instances by comparing the
value in each field in the order in which the fields appear in the struct
Expand All @@ -111,9 +111,9 @@ a data structure that stores data based on the sort order of the values.

The `Clone` trait allows you to explicitly create a deep copy of a value, and
the duplication process might involve running arbitrary code and copying heap
data. See the [“Ways Variables and Data Interact:
Clone”][ways-variables-and-data-interact-clone]<!-- ignore --> section in
Chapter 4 for more information on `Clone`.
data. See [Variables and Data Interacting with
Clone”][variables-and-data-interacting-with-clone]<!-- ignore --> in Chapter 4
for more information on `Clone`.

Deriving `Clone` implements the `clone` method, which when implemented for the
whole type, calls `clone` on each of the parts of the type. This means all the
Expand All @@ -125,9 +125,9 @@ returned from `to_vec` will need to own its instances, so `to_vec` calls
`clone` on each item. Thus, the type stored in the slice must implement `Clone`.

The `Copy` trait allows you to duplicate a value by only copying bits stored on
the stack; no arbitrary code is necessary. See the [“Stack-Only Data:
Copy”][stack-only-data-copy]<!-- ignore --> section in Chapter 4 for more
information on `Copy`.
the stack; no arbitrary code is necessary. See [“Stack-Only Data:
Copy”][stack-only-data-copy]<!-- ignore --> in Chapter 4 for more information on
`Copy`.

The `Copy` trait doesn’t define any methods to prevent programmers from
overloading those methods and violating the assumption that no arbitrary code
Expand Down Expand Up @@ -166,19 +166,20 @@ meaning all fields or values in the type must also implement `Default` to
derive `Default`.

The `Default::default` function is commonly used in combination with the struct
update syntax discussed in the [“Creating Instances From Other Instances With
Struct Update
Syntax”][creating-instances-from-other-instances-with-struct-update-syntax]<!-- ignore -->
section in Chapter 5. You can customize a few fields of a struct and then
set and use a default value for the rest of the fields by using
update syntax discussed in [“Creating Instances From Other Instances With Struct
Update
Syntax”][creating-instances-from-other-instances-with-struct-update-syntax]<!--
ignore --> in Chapter 5. You can customize a few fields of a struct and then set
and use a default value for the rest of the fields by using
`..Default::default()`.

The `Default` trait is required when you use the method `unwrap_or_default` on
`Option<T>` instances, for example. If the `Option<T>` is `None`, the method
`unwrap_or_default` will return the result of `Default::default` for the type
`T` stored in the `Option<T>`.

[creating-instances-from-other-instances-with-struct-update-syntax]: ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax
[stack-only-data-copy]: ch04-01-what-is-ownership.html#stack-only-data-copy
[ways-variables-and-data-interact-clone]: ch04-01-what-is-ownership.html#ways-variables-and-data-interact-clone
[macros]: ch20-05-macros.html#macros
[creating-instances-from-other-instances-with-struct-update-syntax]: ch05-01-defining-structs.html#creating-instances-from-othThe `Clone` trait allows you to explicitly create a deep copy of a value, and
the duplication process might involve running arbitrary code and copying heap
data. See [Variables and Data Interacting with
Clone”][variables-and-data-interacting-with-clone]<!-- ignore --> in Chapter 4
for more information on `Clone`.
18 changes: 9 additions & 9 deletions src/ch00-00-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ mean both how quickly Rust code can run and the speed at which Rust lets you
write programs. The Rust compiler’s checks ensure stability through feature
additions and refactoring. This is in contrast to the brittle legacy code in
languages without these checks, which developers are often afraid to modify. By
striving for zero-cost abstractions, higher-level features that compile to
lower-level code as fast as code written manually, Rust endeavors to make safe
striving for zero-cost abstractionshigher-level features that compile to
lower-level code as fast as code written manuallyRust endeavors to make safe
code be fast code as well.

The Rust language hopes to support many other users as well; those mentioned
Expand Down Expand Up @@ -157,13 +157,13 @@ more about lifetimes, traits, types, functions, and closures.
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
more reference-like format. Appendix A covers Rust’s keywords, Appendix B
covers Rust’s operators and symbols, Appendix C covers derivable traits
provided by the standard library, Appendix D covers some useful development
tools, and Appendix E explains Rust editions. In Appendix F, you can find
translations of the book, and in Appendix G we’ll cover how Rust is made and
what nightly Rust is.
Finally, some appendixes contain useful information about the language in a more
reference-like format. **Appendix A** covers Rust’s keywords, **Appendix B**
covers Rust’s operators and symbols, **Appendix C** covers derivable traits
provided by the standard library, **Appendix D** covers some useful development
tools, and **Appendix E** explains Rust editions. In **Appendix F**, you can
find translations of the book, and in **Appendix G** we’ll cover how Rust is
made and what nightly Rust is.

There is no wrong way to read this book: if you want to skip ahead, go for it!
You might have to jump back to earlier chapters if you experience any
Expand Down
2 changes: 0 additions & 2 deletions src/ch01-03-hello-cargo.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ name = "hello_cargo"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
```

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 @@ -857,7 +857,7 @@ If `parse` is _not_ able to turn the string into a number, it will return an
`Err` value that contains more information about the error. The `Err` value
does not match the `Ok(num)` pattern in the first `match` arm, but it does
match the `Err(_)` pattern in the second arm. The underscore, `_`, is a
catchall value; in this example, we’re saying we want to match all `Err`
catch-all value; in this example, we’re saying we want to match all `Err`
values, no matter what information they have inside them. So the program will
execute the second arm’s code, `continue`, which tells the program to go to the
next iteration of the `loop` and ask for another guess. So, effectively, the
Expand Down
12 changes: 6 additions & 6 deletions src/ch03-02-data-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ when it’s safe to assume the number is positive, it’s shown with no sign.
Signed numbers are stored using [two’s complement][twos-complement]<!-- ignore
--> representation.

Each signed variant can store numbers from -(2<sup>n - 1</sup>) to 2<sup>n -
1</sup> - 1 inclusive, where _n_ is the number of bits that variant uses. So an
`i8` can store numbers from -(2<sup>7</sup>) to 2<sup>7</sup> - 1, which equals
-128 to 127. Unsigned variants can store numbers from 0 to 2<sup>n</sup> - 1,
so a `u8` can store numbers from 0 to 2<sup>8</sup> - 1, which equals 0 to 255.
Each signed variant can store numbers from (2<sup>n 1</sup>) to 2<sup>n
1</sup> 1 inclusive, where _n_ is the number of bits that variant uses. So an
`i8` can store numbers from (2<sup>7</sup>) to 2<sup>7</sup> 1, which equals
128 to 127. Unsigned variants can store numbers from 0 to 2<sup>n</sup> 1,
so a `u8` can store numbers from 0 to 2<sup>8</sup> 1, which equals 0 to 255.

Additionally, the `isize` and `usize` types depend on the architecture of the
computer your program is running on, which is denoted in the table as “arch”:
Expand Down Expand Up @@ -120,7 +120,7 @@ some sort of collection.
>
> - Wrap in all modes with the `wrapping_*` methods, such as `wrapping_add`.
> - Return the `None` value if there is overflow with the `checked_*` methods.
> - Return the value and a boolean indicating whether there was overflow with
> - Return the value and a Boolean indicating whether there was overflow with
> the `overflowing_*` methods.
> - Saturate at the value’s minimum or maximum values with the `saturating_*`
> methods.
Expand Down
4 changes: 2 additions & 2 deletions src/ch03-04-comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ comment continues until the end of the line. For comments that extend beyond a
single line, you’ll need to include `//` on each line, like this:

```rust
// So were doing something complicated here, long enough that we need
// So we're doing something complicated here, long enough that we need
// multiple lines of comments to do it! Whew! Hopefully, this comment will
// explain whats going on.
// explain what's going on.
```

Comments can also be placed at the end of lines containing code:
Expand Down
2 changes: 1 addition & 1 deletion src/ch06-02-match.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ possibility in order for the code to be valid. Especially in the case of
`None` case, it protects us from assuming that we have a value when we might
have null, thus making the billion-dollar mistake discussed earlier impossible.

### Catch-all Patterns and the `_` Placeholder
### Catch-All Patterns and the `_` Placeholder

Using enums, we can also take special actions for a few particular values, but
for all other values take one default action. Imagine we’re implementing a game
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ optionally one library crate. As a package grows, you can extract parts into
separate crates that become external dependencies. This chapter covers all
these techniques. For very large projects comprising a set of interrelated
packages that evolve together, Cargo provides _workspaces_, which we’ll cover
in the [“Cargo Workspaces”][workspaces]<!-- ignore --> section in Chapter 14.
in [“Cargo Workspaces”][workspaces]<!-- ignore --> in Chapter 14.

We’ll also discuss encapsulating implementation details, which lets you reuse
code at a higher level: once you’ve implemented an operation, other code can
Expand Down
19 changes: 9 additions & 10 deletions src/ch07-01-packages-and-crates.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ The first parts of the module system we’ll cover are packages and crates.

A _crate_ is the smallest amount of code that the Rust compiler considers at a
time. Even if you run `rustc` rather than `cargo` and pass a single source code
file (as we did all the way back in the “Writing and Running a Rust Program”
section of Chapter 1), the compiler considers that file to be a crate. Crates
can contain modules, and the modules may be defined in other files that get
compiled with the crate, as we’ll see in the coming sections.
file (as we did all the way back in “Writing and Running a Rust Program” in
Chapter 1), the compiler considers that file to be a crate. Crates can contain
modules, and the modules may be defined in other files that get compiled with
the crate, as we’ll see in the coming sections.

A crate can come in one of two forms: a binary crate or a library crate.
_Binary crates_ are programs you can compile to an executable that you can run,
such as a command-line program or a server. Each must have a function called
such as a command line program or a server. Each must have a function called
`main` that defines what happens when the executable runs. All the crates we’ve
created so far have been binary crates.

Expand All @@ -23,17 +23,16 @@ Most of the time when Rustaceans say “crate”, they mean library crate, and t
use “crate” interchangeably with the general programming concept of a “library”.

The _crate root_ is a source file that the Rust compiler starts from and makes
up the root module of your crate (we’ll explain modules in depth in the
[“Defining Modules to Control Scope and Privacy”][modules]<!-- ignore -->
section).
up the root module of your crate (we’ll explain modules in depth in [“Defining
Modules to Control Scope and Privacy”][modules]<!-- ignore -->).

A _package_ is a bundle of one or more crates that provides a set of
functionality. A package contains a _Cargo.toml_ file that describes how to
build those crates. Cargo is actually a package that contains the binary crate
for the command-line tool you’ve been using to build your code. The Cargo
for the command line tool you’ve been using to build your code. The Cargo
package also contains a library crate that the binary crate depends on. Other
projects can depend on the Cargo library crate to use the same logic the Cargo
command-line tool uses. A package can contain as many binary crates as you
command line tool uses. A package can contain as many binary crates as you
like, but at most only one library crate. A package must contain at least one
crate, whether that’s a library or binary crate.

Expand Down
Loading

0 comments on commit 2e1b7c7

Please sign in to comment.