From 426f3e4ec17e539ae9905ba559411169d303a031 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 11 Jun 2019 17:24:15 -0700 Subject: [PATCH 1/8] Update for markdown changes. --- src/appendix-02-operators.md | 12 +++--- src/appendix-03-derivable-traits.md | 12 +++--- src/ch01-03-hello-cargo.md | 8 ++-- src/ch02-00-guessing-game-tutorial.md | 8 ++-- src/ch03-02-data-types.md | 6 +-- src/ch03-05-control-flow.md | 5 ++- src/ch08-03-hash-maps.md | 5 ++- ...ch09-01-unrecoverable-errors-with-panic.md | 6 +-- src/ch10-02-traits.md | 15 +++---- src/ch10-03-lifetime-syntax.md | 19 +++++---- src/ch11-01-writing-tests.md | 16 +++---- ...improving-error-handling-and-modularity.md | 17 ++++---- ...04-extensible-concurrency-sync-and-send.md | 4 +- src/ch17-02-trait-objects.md | 22 +++++----- src/ch18-01-all-the-places-for-patterns.md | 15 +++---- src/ch19-01-unsafe-rust.md | 33 ++++++++------- src/ch19-03-advanced-traits.md | 42 +++++++++---------- src/ch19-04-advanced-types.md | 16 +++---- ...ch19-05-advanced-functions-and-closures.md | 6 +-- 19 files changed, 137 insertions(+), 130 deletions(-) diff --git a/src/appendix-02-operators.md b/src/appendix-02-operators.md index 41077ba1b5..3bddf322df 100644 --- a/src/appendix-02-operators.md +++ b/src/appendix-02-operators.md @@ -36,7 +36,7 @@ overload that operator is listed. | `-` | `- expr` | Arithmetic negation | `Neg` | | `-` | `expr - expr` | Arithmetic subtraction | `Sub` | | `-=` | `var -= expr` | Arithmetic subtraction and assignment | `SubAssign` | -| `->` | `fn(...) -> type`, \|...\| -> type | Function and closure return type | | +| `->` | `fn(...) -> type`, |...| -> type | Function and closure return type | | | `.` | `expr.ident` | Member access | | | `..` | `..`, `expr..`, `..expr`, `expr..expr` | Right-exclusive range literal | | | `..=` | `..=expr`, `expr..=expr` | Right-inclusive range literal | | @@ -64,10 +64,10 @@ overload that operator is listed. | `@` | `ident @ pat` | Pattern binding | | | `^` | `expr ^ expr` | Bitwise exclusive OR | `BitXor` | | `^=` | `var ^= expr` | Bitwise exclusive OR and assignment | `BitXorAssign` | -| \| | pat \| pat | Pattern alternatives | | -| \| | expr \| expr | Bitwise OR | `BitOr` | -| \|= | var \|= expr | Bitwise OR and assignment | `BitOrAssign` | -| \|\| | expr \|\| expr | Logical OR | | +| | | pat | pat | Pattern alternatives | | +| | | expr | expr | Bitwise OR | `BitOr` | +| |= | var |= expr | Bitwise OR and assignment | `BitOrAssign` | +| || | expr || expr | Logical OR | | | `?` | `expr?` | Error propagation | | ### Non-operator Symbols @@ -90,7 +90,7 @@ locations. | `br"..."`, `br#"..."#`, `br##"..."##`, etc. | Raw byte string literal, combination of raw and byte string literal | | `'...'` | Character literal | | `b'...'` | ASCII byte literal | -| \|...\| expr | Closure | +| |...| expr | Closure | | `!` | Always empty bottom type for diverging functions | | `_` | “Ignored” pattern binding; also used to make integer literals readable | diff --git a/src/appendix-03-derivable-traits.md b/src/appendix-03-derivable-traits.md index 876d4cd8a5..eb49b304d7 100644 --- a/src/appendix-03-derivable-traits.md +++ b/src/appendix-03-derivable-traits.md @@ -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] section in Chapter 4 for more information -on `Copy`. +the stack; no arbitrary code is necessary. See the [“Stack-Only Data: +Copy”][stack-only-data-copy] section 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 @@ -167,9 +167,9 @@ 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] section in Chapter 5. You can customize a few fields of a struct and then +Struct Update +Syntax”][creating-instances-from-other-instances-with-struct-update-syntax] +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 `..Default::default()`. diff --git a/src/ch01-03-hello-cargo.md b/src/ch01-03-hello-cargo.md index 37ca76e490..34428e5f94 100644 --- a/src/ch01-03-hello-cargo.md +++ b/src/ch01-03-hello-cargo.md @@ -13,10 +13,10 @@ using Cargo, adding dependencies will be much easier to do. Because the vast majority of Rust projects use Cargo, the rest of this book assumes that you’re using Cargo too. Cargo comes installed with Rust if you -used the official installers discussed in the [“Installation”] -[installation] section. If you installed Rust through some other -means, check whether Cargo is installed by entering the following into your -terminal: +used the official installers discussed in the +[“Installation”][installation] section. If you installed Rust +through some other means, check whether Cargo is installed by entering the +following into your terminal: ```text $ cargo --version diff --git a/src/ch02-00-guessing-game-tutorial.md b/src/ch02-00-guessing-game-tutorial.md index 7ac6d3da83..f28a158e7c 100644 --- a/src/ch02-00-guessing-game-tutorial.md +++ b/src/ch02-00-guessing-game-tutorial.md @@ -157,10 +157,10 @@ let foo = bar; This line creates a new variable named `foo` and binds it to the value of the `bar` variable. In Rust, variables are immutable by default. We’ll be -discussing this concept in detail in the [“Variables and Mutability”] -[variables-and-mutability] section in Chapter 3. The following -example shows how to use `mut` before the variable name to make a variable -mutable: +discussing this concept in detail in the [“Variables and +Mutability”][variables-and-mutability] section in Chapter 3. +The following example shows how to use `mut` before the variable name to make +a variable mutable: ```rust,ignore let foo = 5; // immutable diff --git a/src/ch03-02-data-types.md b/src/ch03-02-data-types.md index 02fcf5d66b..c093c97c8c 100644 --- a/src/ch03-02-data-types.md +++ b/src/ch03-02-data-types.md @@ -8,9 +8,9 @@ Keep in mind that Rust is a *statically typed* language, which means that it must know the types of all variables at compile time. The compiler can usually infer what type we want to use based on the value and how we use it. In cases when many types are possible, such as when we converted a `String` to a numeric -type using `parse` in the [“Comparing the Guess to the Secret Number”] -[comparing-the-guess-to-the-secret-number] section in Chapter 2, -we must add a type annotation, like this: +type using `parse` in the [“Comparing the Guess to the Secret +Number”][comparing-the-guess-to-the-secret-number] section in +Chapter 2, we must add a type annotation, like this: ```rust let guess: u32 = "42".parse().expect("Not a number!"); diff --git a/src/ch03-05-control-flow.md b/src/ch03-05-control-flow.md index 6d3b46c944..52ce3d5a9f 100644 --- a/src/ch03-05-control-flow.md +++ b/src/ch03-05-control-flow.md @@ -35,8 +35,9 @@ condition. In this case, the condition checks whether or not the variable condition is true is placed immediately after the condition inside curly brackets. Blocks of code associated with the conditions in `if` expressions are sometimes called *arms*, just like the arms in `match` expressions that we -discussed in the [“Comparing the Guess to the Secret Number”] -[comparing-the-guess-to-the-secret-number] section of Chapter 2. +discussed in the [“Comparing the Guess to the Secret +Number”][comparing-the-guess-to-the-secret-number] section of +Chapter 2. Optionally, we can also include an `else` expression, which we chose to do here, to give the program an alternative block of code to execute should diff --git a/src/ch08-03-hash-maps.md b/src/ch08-03-hash-maps.md index d1db52042d..da7772f8fa 100644 --- a/src/ch08-03-hash-maps.md +++ b/src/ch08-03-hash-maps.md @@ -100,8 +100,9 @@ they’ve been moved into the hash map with the call to `insert`. If we insert references to values into the hash map, the values won’t be moved into the hash map. The values that the references point to must be valid for at least as long as the hash map is valid. We’ll talk more about these issues in -the [“Validating References with Lifetimes”] -[validating-references-with-lifetimes] section in Chapter 10. +the [“Validating References with +Lifetimes”][validating-references-with-lifetimes] section in +Chapter 10. ### Accessing Values in a Hash Map diff --git a/src/ch09-01-unrecoverable-errors-with-panic.md b/src/ch09-01-unrecoverable-errors-with-panic.md index 906b8e7f0f..454b78071d 100644 --- a/src/ch09-01-unrecoverable-errors-with-panic.md +++ b/src/ch09-01-unrecoverable-errors-with-panic.md @@ -192,9 +192,9 @@ you’ll need to figure out what action the code is taking with what values to cause the panic and what the code should do instead. We’ll come back to `panic!` and when we should and should not use `panic!` to -handle error conditions in the [“To `panic!` or Not to `panic!`”] -[to-panic-or-not-to-panic] section later in this chapter. Next, -we’ll look at how to recover from an error using `Result`. +handle error conditions in the [“To `panic!` or Not to +`panic!`”][to-panic-or-not-to-panic] section later in this +chapter. Next, we’ll look at how to recover from an error using `Result`. [to-panic-or-not-to-panic]: ch09-03-to-panic-or-not-to-panic.html#to-panic-or-not-to-panic diff --git a/src/ch10-02-traits.md b/src/ch10-02-traits.md index 131f6c1928..8fcf15df01 100644 --- a/src/ch10-02-traits.md +++ b/src/ch10-02-traits.md @@ -480,13 +480,14 @@ error[E0507]: cannot move out of borrowed content The key line in this error is `cannot move out of type [T], a non-copy slice`. With our non-generic versions of the `largest` function, we were only trying to -find the largest `i32` or `char`. As discussed in the [“Stack-Only Data: Copy”] -[stack-only-data-copy] section in Chapter 4, types like `i32` -and `char` that have a known size can be stored on the stack, so they implement -the `Copy` trait. But when we made the `largest` function generic, it became -possible for the `list` parameter to have types in it that don’t implement the -`Copy` trait. Consequently, we wouldn’t be able to move the value out of -`list[0]` and into the `largest` variable, resulting in this error. +find the largest `i32` or `char`. As discussed in the [“Stack-Only Data: +Copy”][stack-only-data-copy] section in Chapter 4, types like +`i32` and `char` that have a known size can be stored on the stack, so they +implement the `Copy` trait. But when we made the `largest` function generic, +it became possible for the `list` parameter to have types in it that don’t +implement the `Copy` trait. Consequently, we wouldn’t be able to move the +value out of `list[0]` and into the `largest` variable, resulting in this +error. To call this code with only those types that implement the `Copy` trait, we can add `Copy` to the trait bounds of `T`! Listing 10-15 shows the complete code of diff --git a/src/ch10-03-lifetime-syntax.md b/src/ch10-03-lifetime-syntax.md index 893d9ba6fc..383a4ec40e 100644 --- a/src/ch10-03-lifetime-syntax.md +++ b/src/ch10-03-lifetime-syntax.md @@ -1,14 +1,15 @@ ## Validating References with Lifetimes -One detail we didn’t discuss in the [“References and Borrowing”] -[references-and-borrowing] section in Chapter 4 is that every -reference in Rust has a *lifetime*, which is the scope for which that reference -is valid. Most of the time, lifetimes are implicit and inferred, just like most -of the time, types are inferred. We must annotate types when multiple types are -possible. In a similar way, we must annotate lifetimes when the lifetimes of -references could be related in a few different ways. Rust requires us to -annotate the relationships using generic lifetime parameters to ensure the -actual references used at runtime will definitely be valid. +One detail we didn’t discuss in the [“References and +Borrowing”][references-and-borrowing] section in Chapter 4 is +that every reference in Rust has a *lifetime*, which is the scope for which +that reference is valid. Most of the time, lifetimes are implicit and +inferred, just like most of the time, types are inferred. We must annotate +types when multiple types are possible. In a similar way, we must annotate +lifetimes when the lifetimes of references could be related in a few different +ways. Rust requires us to annotate the relationships using generic lifetime +parameters to ensure the actual references used at runtime will definitely be +valid. The concept of lifetimes is somewhat different from tools in other programming languages, arguably making lifetimes Rust’s most distinctive feature. Although diff --git a/src/ch11-01-writing-tests.md b/src/ch11-01-writing-tests.md index 6676fdfd7d..b5c645f34c 100644 --- a/src/ch11-01-writing-tests.md +++ b/src/ch11-01-writing-tests.md @@ -105,8 +105,8 @@ reads `1 passed; 0 failed` totals the number of tests that passed or failed. Because we don’t have any tests we’ve marked as ignored, the summary shows `0 ignored`. We also haven’t filtered the tests being run, so the end of the summary shows `0 filtered out`. We’ll talk about ignoring and filtering out -tests in the next section, [“Controlling How Tests Are Run.”] -[controlling-how-tests-are-run] +tests in the next section, [“Controlling How Tests Are +Run.”][controlling-how-tests-are-run] The `0 measured` statistic is for benchmark tests that measure performance. Benchmark tests are, as of this writing, only available in nightly Rust. See @@ -509,12 +509,12 @@ optional arguments to the `assert!`, `assert_eq!`, and `assert_ne!` macros. Any arguments specified after the one required argument to `assert!` or the two required arguments to `assert_eq!` and `assert_ne!` are passed along to the `format!` macro (discussed in Chapter 8 in the [“Concatenation with the `+` -Operator or the `format!` Macro”] -[concatenation-with-the--operator-or-the-format-macro] section), -so you can pass a format string that contains `{}` placeholders and values to -go in those placeholders. Custom messages are useful to document what an -assertion means; when a test fails, you’ll have a better idea of what the -problem is with the code. +Operator or the `format!` +Macro”][concatenation-with-the--operator-or-the-format-macro] +section), so you can pass a format string that contains `{}` placeholders and +values to go in those placeholders. Custom messages are useful to document +what an assertion means; when a test fails, you’ll have a better idea of what +the problem is with the code. For example, let’s say we have a function that greets people by name and we want to test that the name we pass into the function appears in the output: diff --git a/src/ch12-03-improving-error-handling-and-modularity.md b/src/ch12-03-improving-error-handling-and-modularity.md index 5f014d7f98..d26c590049 100644 --- a/src/ch12-03-improving-error-handling-and-modularity.md +++ b/src/ch12-03-improving-error-handling-and-modularity.md @@ -187,14 +187,15 @@ trade-off. > ### The Trade-Offs of Using `clone` > > There’s a tendency among many Rustaceans to avoid using `clone` to fix -> ownership problems because of its runtime cost. In [Chapter 13][ch13], you’ll learn how to use more efficient methods in this type of -> situation. But for now, it’s okay to copy a few strings to continue making -> progress because you’ll make these copies only once and your filename and -> query string are very small. It’s better to have a working program that’s a -> bit inefficient than to try to hyperoptimize code on your first pass. As you -> become more experienced with Rust, it’ll be easier to start with the most -> efficient solution, but for now, it’s perfectly acceptable to call `clone`. +> ownership problems because of its runtime cost. In +> [Chapter 13][ch13], you’ll learn how to use more efficient +> methods in this type of situation. But for now, it’s okay to copy a few +> strings to continue making progress because you’ll make these copies only +> once and your filename and query string are very small. It’s better to have +> a working program that’s a bit inefficient than to try to hyperoptimize code +> on your first pass. As you become more experienced with Rust, it’ll be +> easier to start with the most efficient solution, but for now, it’s +> perfectly acceptable to call `clone`. We’ve updated `main` so it places the instance of `Config` returned by `parse_config` into a variable named `config`, and we updated the code that diff --git a/src/ch16-04-extensible-concurrency-sync-and-send.md b/src/ch16-04-extensible-concurrency-sync-and-send.md index 7ec5d793a7..ff9830e38c 100644 --- a/src/ch16-04-extensible-concurrency-sync-and-send.md +++ b/src/ch16-04-extensible-concurrency-sync-and-send.md @@ -42,8 +42,8 @@ The smart pointer `Rc` is also not `Sync` for the same reasons that it’s no family of related `Cell` types are not `Sync`. The implementation of borrow checking that `RefCell` does at runtime is not thread-safe. The smart pointer `Mutex` is `Sync` and can be used to share access with multiple -threads as you saw in the [“Sharing a `Mutex` Between Multiple Threads”] -[sharing-a-mutext-between-multiple-threads] section. +threads as you saw in the [“Sharing a `Mutex` Between Multiple +Threads”][sharing-a-mutext-between-multiple-threads] section. ### Implementing `Send` and `Sync` Manually Is Unsafe diff --git a/src/ch17-02-trait-objects.md b/src/ch17-02-trait-objects.md index b9342ac231..6145f21c52 100644 --- a/src/ch17-02-trait-objects.md +++ b/src/ch17-02-trait-objects.md @@ -331,17 +331,17 @@ didn’t mean to pass and we should pass a different type or we should implement ### Trait Objects Perform Dynamic Dispatch -Recall in the [“Performance of Code Using Generics”] -[performance-of-code-using-generics] section in Chapter 10 our -discussion on the monomorphization process performed by the compiler when we -use trait bounds on generics: the compiler generates nongeneric implementations -of functions and methods for each concrete type that we use in place of a -generic type parameter. The code that results from monomorphization is doing -*static dispatch*, which is when the compiler knows what method you’re calling -at compile time. This is opposed to *dynamic dispatch*, which is when the -compiler can’t tell at compile time which method you’re calling. In dynamic -dispatch cases, the compiler emits code that at runtime will figure out which -method to call. +Recall in the [“Performance of Code Using +Generics”][performance-of-code-using-generics] section in +Chapter 10 our discussion on the monomorphization process performed by the +compiler when we use trait bounds on generics: the compiler generates +nongeneric implementations of functions and methods for each concrete type +that we use in place of a generic type parameter. The code that results from +monomorphization is doing *static dispatch*, which is when the compiler knows +what method you’re calling at compile time. This is opposed to *dynamic +dispatch*, which is when the compiler can’t tell at compile time which method +you’re calling. In dynamic dispatch cases, the compiler emits code that at +runtime will figure out which method to call. When we use trait objects, Rust must use dynamic dispatch. The compiler doesn’t know all the types that might be used with the code that is using trait diff --git a/src/ch18-01-all-the-places-for-patterns.md b/src/ch18-01-all-the-places-for-patterns.md index f14e0c9ed8..d838532fba 100644 --- a/src/ch18-01-all-the-places-for-patterns.md +++ b/src/ch18-01-all-the-places-for-patterns.md @@ -28,8 +28,9 @@ value can never fail and thus covers every remaining case. A particular pattern `_` will match anything, but it never binds to a variable, so it’s often used in the last match arm. The `_` pattern can be useful when you want to ignore any value not specified, for example. We’ll cover the `_` -pattern in more detail in the [“Ignoring Values in a Pattern”] -[ignoring-values-in-a-pattern] section later in this chapter. +pattern in more detail in the [“Ignoring Values in a +Pattern”][ignoring-values-in-a-pattern] section later in this +chapter. ### Conditional `if let` Expressions @@ -229,11 +230,11 @@ error[E0308]: mismatched types ``` If we wanted to ignore one or more of the values in the tuple, we could use `_` -or `..`, as you’ll see in the [“Ignoring Values in a Pattern”] -[ignoring-values-in-a-pattern] section. If the problem is that -we have too many variables in the pattern, the solution is to make the types -match by removing variables so the number of variables equals the number of -elements in the tuple. +or `..`, as you’ll see in the [“Ignoring Values in a +Pattern”][ignoring-values-in-a-pattern] section. If the problem +is that we have too many variables in the pattern, the solution is to make the +types match by removing variables so the number of variables equals the number +of elements in the tuple. ### Function Parameters diff --git a/src/ch19-01-unsafe-rust.md b/src/ch19-01-unsafe-rust.md index 04ee039f3f..8875a93dc6 100644 --- a/src/ch19-01-unsafe-rust.md +++ b/src/ch19-01-unsafe-rust.md @@ -440,13 +440,14 @@ variable Static variables are similar to constants, which we discussed in the -[“Differences Between Variables and Constants”] -[differences-between-variables-and-constants] section in -Chapter 3. The names of static variables are in `SCREAMING_SNAKE_CASE` by -convention, and we *must* annotate the variable’s type, which is `&'static str` -in this example. Static variables can only store references with the `'static` -lifetime, which means the Rust compiler can figure out the lifetime; we don’t -need to annotate it explicitly. Accessing an immutable static variable is safe. +[“Differences Between Variables and +Constants”][differences-between-variables-and-constants] +section in Chapter 3. The names of static variables are in +`SCREAMING_SNAKE_CASE` by convention, and we *must* annotate the variable’s +type, which is `&'static str` in this example. Static variables can only store +references with the `'static` lifetime, which means the Rust compiler can +figure out the lifetime; we don’t need to annotate it explicitly. Accessing an +immutable static variable is safe. Constants and immutable static variables might seem similar, but a subtle difference is that values in a static variable have a fixed address in memory. @@ -518,15 +519,15 @@ By using `unsafe impl`, we’re promising that we’ll uphold the invariants tha the compiler can’t verify. As an example, recall the `Sync` and `Send` marker traits we discussed in the -[“Extensible Concurrency with the `Sync` and `Send` Traits”] -[extensible-concurrency-with-the-sync-and-send-traits] section -in Chapter 16: the compiler implements these traits automatically if our types -are composed entirely of `Send` and `Sync` types. If we implement a type that -contains a type that is not `Send` or `Sync`, such as raw pointers, and we want -to mark that type as `Send` or `Sync`, we must use `unsafe`. Rust can’t verify -that our type upholds the guarantees that it can be safely sent across threads -or accessed from multiple threads; therefore, we need to do those checks -manually and indicate as such with `unsafe`. +[“Extensible Concurrency with the `Sync` and `Send` +Traits”][extensible-concurrency-with-the-sync-and-send-traits] +section in Chapter 16: the compiler implements these traits automatically if +our types are composed entirely of `Send` and `Sync` types. If we implement a +type that contains a type that is not `Send` or `Sync`, such as raw pointers, +and we want to mark that type as `Send` or `Sync`, we must use `unsafe`. Rust +can’t verify that our type upholds the guarantees that it can be safely sent +across threads or accessed from multiple threads; therefore, we need to do +those checks manually and indicate as such with `unsafe`. ### When to Use Unsafe Code diff --git a/src/ch19-03-advanced-traits.md b/src/ch19-03-advanced-traits.md index 288777057e..c959f231dc 100644 --- a/src/ch19-03-advanced-traits.md +++ b/src/ch19-03-advanced-traits.md @@ -1,9 +1,9 @@ ## Advanced Traits -We first covered traits in the [“Traits: Defining Shared Behavior”] -[traits-defining-shared-behavior] section of Chapter 10, but as -with lifetimes, we didn’t discuss the more advanced details. Now that you know -more about Rust, we can get into the nitty-gritty. +We first covered traits in the [“Traits: Defining Shared +Behavior”][traits-defining-shared-behavior] section of Chapter +10, but as with lifetimes, we didn’t discuss the more advanced details. Now +that you know more about Rust, we can get into the nitty-gritty. ### Specifying Placeholder Types in Trait Definitions with Associated Types @@ -22,10 +22,10 @@ the other features discussed in this chapter. One example of a trait with an associated type is the `Iterator` trait that the standard library provides. The associated type is named `Item` and stands in for the type of the values the type implementing the `Iterator` trait is -iterating over. In [“The `Iterator` Trait and the `next` Method”] -[the-iterator-trait-and-the-next-method] section of Chapter 13, -we mentioned that the definition of the `Iterator` trait is as shown in Listing -19-12. +iterating over. In [“The `Iterator` Trait and the `next` +Method”][the-iterator-trait-and-the-next-method] section of +Chapter 13, we mentioned that the definition of the `Iterator` trait is as +shown in Listing 19-12. ```rust pub trait Iterator { @@ -621,19 +621,19 @@ it within an outline of asterisks. ### Using the Newtype Pattern to Implement External Traits on External Types -In Chapter 10 in the [“Implementing a Trait on a Type”] -[implementing-a-trait-on-a-type] section, we mentioned the -orphan rule that states we’re allowed to implement a trait on a type as long as -either the trait or the type are local to our crate. It’s possible to get -around this restriction using the *newtype pattern*, which involves creating a -new type in a tuple struct. (We covered tuple structs in the [“Using Tuple -Structs without Named Fields to Create Different Types”][tuple-structs] section of Chapter 5.) The tuple struct will have one field and be a -thin wrapper around the type we want to implement a trait for. Then the wrapper -type is local to our crate, and we can implement the trait on the wrapper. -*Newtype* is a term that originates from the Haskell programming language. -There is no runtime performance penalty for using this pattern, and the wrapper -type is elided at compile time. +In Chapter 10 in the [“Implementing a Trait on a +Type”][implementing-a-trait-on-a-type] section, we mentioned +the orphan rule that states we’re allowed to implement a trait on a type as +long as either the trait or the type are local to our crate. It’s possible to +get around this restriction using the *newtype pattern*, which involves +creating a new type in a tuple struct. (We covered tuple structs in the +[“Using Tuple Structs without Named Fields to Create Different +Types”][tuple-structs] section of Chapter 5.) The tuple struct +will have one field and be a thin wrapper around the type we want to implement +a trait for. Then the wrapper type is local to our crate, and we can implement +the trait on the wrapper. *Newtype* is a term that originates from the Haskell +programming language. There is no runtime performance penalty for using this +pattern, and the wrapper type is elided at compile time. As an example, let’s say we want to implement `Display` on `Vec`, which the orphan rule prevents us from doing directly because the `Display` trait and the diff --git a/src/ch19-04-advanced-types.md b/src/ch19-04-advanced-types.md index 97ea1bb17b..e1e46b1ed1 100644 --- a/src/ch19-04-advanced-types.md +++ b/src/ch19-04-advanced-types.md @@ -32,9 +32,9 @@ public API we provide, such as a method to add a name string to the `People` collection; that code wouldn’t need to know that we assign an `i32` ID to names internally. The newtype pattern is a lightweight way to achieve encapsulation to hide implementation details, which we discussed in the [“Encapsulation that -Hides Implementation Details”] -[encapsulation-that-hides-implementation-details] section of -Chapter 17. +Hides Implementation +Details”][encapsulation-that-hides-implementation-details] +section of Chapter 17. ### Creating Type Synonyms with Type Aliases @@ -308,11 +308,11 @@ We can combine `str` with all kinds of pointers: for example, `Box` or `Rc`. In fact, you’ve seen this before but with a different dynamically sized type: traits. Every trait is a dynamically sized type we can refer to by using the name of the trait. In Chapter 17 in the [“Using Trait Objects That -Allow for Values of Different Types”] -[using-trait-objects-that-allow-for-values-of-different-types] -section, we mentioned that to use traits as trait objects, we must put them -behind a pointer, such as `&dyn Trait` or `Box` (`Rc` -would work too). +Allow for Values of Different +Types”][using-trait-objects-that-allow-for-values-of-different-types] section, we mentioned that to use traits as trait objects, we must +put them behind a pointer, such as `&dyn Trait` or `Box` (`Rc` would work too). To work with DSTs, Rust has a particular trait called the `Sized` trait to determine whether or not a type’s size is known at compile time. This trait is diff --git a/src/ch19-05-advanced-functions-and-closures.md b/src/ch19-05-advanced-functions-and-closures.md index a40e222e3d..2955114afc 100644 --- a/src/ch19-05-advanced-functions-and-closures.md +++ b/src/ch19-05-advanced-functions-and-closures.md @@ -152,9 +152,9 @@ fn returns_closure() -> Box i32> { ``` This code will compile just fine. For more about trait objects, refer to the -section [“Using Trait Objects That Allow for Values of Different Types”] -[using-trait-objects-that-allow-for-values-of-different-types] -in Chapter 17. +section [“Using Trait Objects That Allow for Values of Different +Types”][using-trait-objects-that-allow-for-values-of-different-types] in Chapter 17. Next, let’s look at macros! From 027b6014ed349ca5622e54c14969cedeb3a09450 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 15 Jun 2019 15:14:47 -0400 Subject: [PATCH 2/8] Remove warning about paragraph being wrapped weirdly on purpose OBE --- src/ch19-01-unsafe-rust.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ch19-01-unsafe-rust.md b/src/ch19-01-unsafe-rust.md index 8875a93dc6..8605ede6a2 100644 --- a/src/ch19-01-unsafe-rust.md +++ b/src/ch19-01-unsafe-rust.md @@ -437,8 +437,6 @@ fn main() { Listing 19-9: Defining and using an immutable static variable - - Static variables are similar to constants, which we discussed in the [“Differences Between Variables and Constants”][differences-between-variables-and-constants] From b56bc840091a01a2867d578ea24a8864095c904f Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 15 Jun 2019 15:19:03 -0400 Subject: [PATCH 3/8] Add vert to dictionary --- ci/dictionary.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/dictionary.txt b/ci/dictionary.txt index 52f3b6a0db..05f61c0a22 100644 --- a/ci/dictionary.txt +++ b/ci/dictionary.txt @@ -519,6 +519,7 @@ variable's variant's vers versa +vert Versioning visualstudio Vlissides From 2892ef6aa71d9516da56d5acbcc46e79c381ceb9 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 15 Jun 2019 20:33:21 -0400 Subject: [PATCH 4/8] Only match one newline when removing links, not two --- tools/src/bin/remove_links.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/src/bin/remove_links.rs b/tools/src/bin/remove_links.rs index 870088cda5..03c9302b93 100644 --- a/tools/src/bin/remove_links.rs +++ b/tools/src/bin/remove_links.rs @@ -28,7 +28,7 @@ fn main () { }); // Search for the references we need to delete. - let ref_regex = Regex::new(r"\n\[([^\]]+)\]:\s.*\n").unwrap(); + let ref_regex = Regex::new(r"(?m)^\[([^\]]+)\]:\s.*\n").unwrap(); let out = ref_regex.replace_all(&first_pass, |caps: &Captures<'_>| { let capture = caps.at(1).unwrap().to_owned(); From fd18ff0c509d6326b4ec473e10c464a846db85ee Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 15 Jun 2019 20:34:33 -0400 Subject: [PATCH 5/8] Ignore an intra-book link --- src/ch03-02-data-types.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ch03-02-data-types.md b/src/ch03-02-data-types.md index c093c97c8c..228e4316b2 100644 --- a/src/ch03-02-data-types.md +++ b/src/ch03-02-data-types.md @@ -107,7 +107,8 @@ which you’d use `isize` or `usize` is when indexing some sort of collection. > checks for integer overflow that cause your program to *panic* at runtime if > this behavior occurs. Rust uses the term panicking when a program exits with > an error; we’ll discuss panics in more depth in the [“Unrecoverable Errors -> with `panic!`”][unrecoverable-errors-with-panic] section in Chapter 9. +> with `panic!`”][unrecoverable-errors-with-panic] section in +> Chapter 9. > > When you’re compiling in release mode with the `--release` flag, Rust does > *not* include checks for integer overflow that cause panics. Instead, if From 83d8bce4d8ef824f4e00bf8377f91be543a31428 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 15 Jun 2019 20:40:28 -0400 Subject: [PATCH 6/8] Match newlines or space in the ignore comment for when it wraps --- tools/src/bin/remove_links.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/src/bin/remove_links.rs b/tools/src/bin/remove_links.rs index 03c9302b93..b31d7dc615 100644 --- a/tools/src/bin/remove_links.rs +++ b/tools/src/bin/remove_links.rs @@ -14,7 +14,7 @@ fn main () { let mut refs = HashSet::new(); // Capture all links and link references. - let regex = r"\[([^\]]+)\](?:(?:\[([^\]]+)\])|(?:\([^\)]+\)))(?i)"; + let regex = r"\[([^\]]+)\](?:(?:\[([^\]]+)\])|(?:\([^\)]+\)))(?i)"; let link_regex = Regex::new(regex).unwrap(); let first_pass = link_regex.replace_all(&buffer, |caps: &Captures<'_>| { From 4223d38ceda30a39a97f81150add90c29c4b79b2 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 15 Jun 2019 20:43:50 -0400 Subject: [PATCH 7/8] Add an exception for no_mangle, it's an attribute, not a link --- tools/src/bin/link2print.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/src/bin/link2print.rs b/tools/src/bin/link2print.rs index c2dcd56fc4..0d6d2f654a 100644 --- a/tools/src/bin/link2print.rs +++ b/tools/src/bin/link2print.rs @@ -54,6 +54,7 @@ fn parse_links((buffer, ref_map): (String, HashMap)) -> String { if name.starts_with("derive(") || name.starts_with("profile") || name.starts_with("test") || + name.starts_with("no_mangle") || error_code.is_match(&name) { return name } From 9fdcc7f194afdfb745189420b36dbf6427983eb2 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 15 Jun 2019 20:45:17 -0400 Subject: [PATCH 8/8] Add a missing newline after a header --- src/appendix-05-editions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/appendix-05-editions.md b/src/appendix-05-editions.md index 5f95b82584..ac75c4181d 100644 --- a/src/appendix-05-editions.md +++ b/src/appendix-05-editions.md @@ -1,4 +1,5 @@ # Appendix E - Editions + In Chapter 1, you saw that `cargo new` adds a bit of metadata to your *Cargo.toml* file about an edition. This appendix talks about what that means!