From f86181ea0e97177b08f4c31e428fd03cb1b883bf Mon Sep 17 00:00:00 2001 From: funkill2 Date: Wed, 27 Nov 2024 04:00:17 +0300 Subject: [PATCH] update original --- .../listing-20-08/src/main.rs | 2 +- .../listing-20-09/src/main.rs | 6 +- .../listing-20-10/src/main.rs | 15 +--- .../output.txt | 0 .../listing-20-11/src/main.rs | 19 ++-- .../listing-20-12/Cargo.lock | 2 +- .../listing-20-12/Cargo.toml | 2 +- .../listing-20-12/src/lib.rs | 5 -- .../listing-20-12/src/main.rs | 9 ++ .../listing-20-13/src/lib.rs | 6 +- .../listing-20-14/src/lib.rs | 3 + .../src/main.rs | 0 .../src/lib.rs | 0 .../listing-20-16/src/main.rs | 31 ------- .../listing-20-17/src/main.rs | 9 +- .../listing-20-18/src/main.rs | 2 - .../listing-20-19/output.txt | 6 +- .../listing-20-19/src/main.rs | 35 +++++--- .../listing-20-20/output.txt | 19 +--- .../listing-20-20/src/main.rs | 4 +- .../listing-20-21/output.txt | 19 +++- .../listing-20-21/src/main.rs | 2 +- .../output.txt | 6 +- .../listing-20-22/src/main.rs | 32 ++++--- .../listing-20-23/src/main.rs | 21 +++-- .../listing-20-24/Cargo.lock | 2 +- .../listing-20-24/Cargo.toml | 2 +- .../listing-20-24/src/main.rs | 22 +++-- .../listing-20-25/src/main.rs | 8 +- .../Cargo.lock | 2 +- .../Cargo.toml | 2 +- .../listing-20-26/src/main.rs | 18 ++++ .../listing-20-28/Cargo.lock | 2 +- .../listing-20-28/Cargo.toml | 2 +- .../src/main.rs | 0 .../listing-20-29/Cargo.lock | 6 ++ .../listing-20-29/Cargo.toml | 6 ++ .../src/lib.rs | 0 .../Cargo.lock | 0 .../Cargo.toml | 0 .../src/main.rs | 0 .../hello_macro/Cargo.lock | 0 .../hello_macro/Cargo.toml | 0 .../hello_macro/hello_macro_derive/Cargo.lock | 0 .../hello_macro/hello_macro_derive/Cargo.toml | 0 .../hello_macro/hello_macro_derive/src/lib.rs | 0 .../hello_macro/src/lib.rs | 0 .../hello_macro/src/main.rs | 0 .../hello_macro/Cargo.lock | 0 .../hello_macro/Cargo.toml | 0 .../hello_macro/hello_macro_derive/Cargo.lock | 0 .../hello_macro/hello_macro_derive/Cargo.toml | 0 .../hello_macro/hello_macro_derive/src/lib.rs | 0 .../hello_macro/src/lib.rs | 0 .../hello_macro/src/main.rs | 0 rustbook-en/src/ch01-01-installation.md | 9 ++ rustbook-en/src/ch03-02-data-types.md | 3 +- rustbook-en/src/ch06-03-if-let.md | 4 +- rustbook-en/src/ch17-05-traits-for-async.md | 14 +-- rustbook-en/src/ch20-01-unsafe-rust.md | 76 ++++++++++------ rustbook-en/src/ch20-03-advanced-traits.md | 88 +++++++++---------- rustbook-en/src/ch20-04-advanced-types.md | 24 ++--- ...ch20-05-advanced-functions-and-closures.md | 6 +- rustbook-en/src/ch20-06-macros.md | 48 +++++----- 64 files changed, 324 insertions(+), 275 deletions(-) rename rustbook-en/listings/ch20-advanced-features/{listing-20-10 => listing-20-11}/output.txt (100%) delete mode 100644 rustbook-en/listings/ch20-advanced-features/listing-20-12/src/lib.rs create mode 100644 rustbook-en/listings/ch20-advanced-features/listing-20-12/src/main.rs create mode 100644 rustbook-en/listings/ch20-advanced-features/listing-20-14/src/lib.rs rename rustbook-en/listings/ch20-advanced-features/{listing-20-14 => listing-20-15}/src/main.rs (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-15 => listing-20-16}/src/lib.rs (100%) delete mode 100644 rustbook-en/listings/ch20-advanced-features/listing-20-16/src/main.rs rename rustbook-en/listings/ch20-advanced-features/{listing-20-18 => listing-20-22}/output.txt (73%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-27 => listing-20-26}/Cargo.lock (81%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-27 => listing-20-26}/Cargo.toml (69%) create mode 100644 rustbook-en/listings/ch20-advanced-features/listing-20-26/src/main.rs rename rustbook-en/listings/ch20-advanced-features/{listing-20-27 => listing-20-28}/src/main.rs (100%) create mode 100644 rustbook-en/listings/ch20-advanced-features/listing-20-29/Cargo.lock create mode 100644 rustbook-en/listings/ch20-advanced-features/listing-20-29/Cargo.toml rename rustbook-en/listings/ch20-advanced-features/{listing-20-28 => listing-20-29}/src/lib.rs (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-30 => listing-20-31}/Cargo.lock (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-30 => listing-20-31}/Cargo.toml (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-30 => listing-20-31}/src/main.rs (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-31 => listing-20-32}/hello_macro/Cargo.lock (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-31 => listing-20-32}/hello_macro/Cargo.toml (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-31 => listing-20-32}/hello_macro/hello_macro_derive/Cargo.lock (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-31 => listing-20-32}/hello_macro/hello_macro_derive/Cargo.toml (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-31 => listing-20-32}/hello_macro/hello_macro_derive/src/lib.rs (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-31 => listing-20-32}/hello_macro/src/lib.rs (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-31 => listing-20-32}/hello_macro/src/main.rs (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-33 => listing-20-34}/hello_macro/Cargo.lock (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-33 => listing-20-34}/hello_macro/Cargo.toml (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-33 => listing-20-34}/hello_macro/hello_macro_derive/Cargo.lock (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-33 => listing-20-34}/hello_macro/hello_macro_derive/Cargo.toml (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-33 => listing-20-34}/hello_macro/hello_macro_derive/src/lib.rs (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-33 => listing-20-34}/hello_macro/src/lib.rs (100%) rename rustbook-en/listings/ch20-advanced-features/{listing-20-33 => listing-20-34}/hello_macro/src/main.rs (100%) diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-08/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-08/src/main.rs index 8b56630c9..90c183ade 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-08/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-08/src/main.rs @@ -1,4 +1,4 @@ -extern "C" { +unsafe extern "C" { fn abs(input: i32) -> i32; } diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-09/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-09/src/main.rs index fda5179af..7d77d51e4 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-09/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-09/src/main.rs @@ -1,5 +1,7 @@ -static HELLO_WORLD: &str = "Hello, world!"; +unsafe extern "C" { + safe fn abs(input: i32) -> i32; +} fn main() { - println!("name is: {HELLO_WORLD}"); + println!("Absolute value of -3 according to C: {}", abs(-3)); } diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-10/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-10/src/main.rs index 360e3548f..fda5179af 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-10/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-10/src/main.rs @@ -1,16 +1,5 @@ -static mut COUNTER: u32 = 0; - -/// SAFETY: Calling this from more than a single thread at a time is undefined -/// behavior, so you *must* guarantee you only call it from a single thread at -/// a time. -unsafe fn add_to_count(inc: u32) { - COUNTER += inc; -} +static HELLO_WORLD: &str = "Hello, world!"; fn main() { - unsafe { - // SAFETY: This is only called from a single thread in `main`. - add_to_count(3); - println!("COUNTER: {}", COUNTER); - } + println!("name is: {HELLO_WORLD}"); } diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-10/output.txt b/rustbook-en/listings/ch20-advanced-features/listing-20-11/output.txt similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-10/output.txt rename to rustbook-en/listings/ch20-advanced-features/listing-20-11/output.txt diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-11/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-11/src/main.rs index 885c1aa1d..360e3548f 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-11/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-11/src/main.rs @@ -1,9 +1,16 @@ -unsafe trait Foo { - // methods go here -} +static mut COUNTER: u32 = 0; -unsafe impl Foo for i32 { - // method implementations go here +/// SAFETY: Calling this from more than a single thread at a time is undefined +/// behavior, so you *must* guarantee you only call it from a single thread at +/// a time. +unsafe fn add_to_count(inc: u32) { + COUNTER += inc; } -fn main() {} +fn main() { + unsafe { + // SAFETY: This is only called from a single thread in `main`. + add_to_count(3); + println!("COUNTER: {}", COUNTER); + } +} diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-12/Cargo.lock b/rustbook-en/listings/ch20-advanced-features/listing-20-12/Cargo.lock index b1977d01e..497817bf2 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-12/Cargo.lock +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-12/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] -name = "traits-example" +name = "unsafe-example" version = "0.1.0" diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-12/Cargo.toml b/rustbook-en/listings/ch20-advanced-features/listing-20-12/Cargo.toml index 52395a587..3e8a29201 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-12/Cargo.toml +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-12/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "traits-example" +name = "unsafe-example" version = "0.1.0" edition = "2021" diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-12/src/lib.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-12/src/lib.rs deleted file mode 100644 index dbe04620e..000000000 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-12/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub trait Iterator { - type Item; - - fn next(&mut self) -> Option; -} diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-12/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-12/src/main.rs new file mode 100644 index 000000000..885c1aa1d --- /dev/null +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-12/src/main.rs @@ -0,0 +1,9 @@ +unsafe trait Foo { + // methods go here +} + +unsafe impl Foo for i32 { + // method implementations go here +} + +fn main() {} diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-13/src/lib.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-13/src/lib.rs index 7c9479c5b..dbe04620e 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-13/src/lib.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-13/src/lib.rs @@ -1,3 +1,5 @@ -pub trait Iterator { - fn next(&mut self) -> Option; +pub trait Iterator { + type Item; + + fn next(&mut self) -> Option; } diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-14/src/lib.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-14/src/lib.rs new file mode 100644 index 000000000..7c9479c5b --- /dev/null +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-14/src/lib.rs @@ -0,0 +1,3 @@ +pub trait Iterator { + fn next(&mut self) -> Option; +} diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-14/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-15/src/main.rs similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-14/src/main.rs rename to rustbook-en/listings/ch20-advanced-features/listing-20-15/src/main.rs diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-15/src/lib.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-16/src/lib.rs similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-15/src/lib.rs rename to rustbook-en/listings/ch20-advanced-features/listing-20-16/src/lib.rs diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-16/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-16/src/main.rs deleted file mode 100644 index d854e287d..000000000 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-16/src/main.rs +++ /dev/null @@ -1,31 +0,0 @@ -// ANCHOR: here -trait Pilot { - fn fly(&self); -} - -trait Wizard { - fn fly(&self); -} - -struct Human; - -impl Pilot for Human { - fn fly(&self) { - println!("This is your captain speaking."); - } -} - -impl Wizard for Human { - fn fly(&self) { - println!("Up!"); - } -} - -impl Human { - fn fly(&self) { - println!("*waving arms furiously*"); - } -} -// ANCHOR_END: here - -fn main() {} diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-17/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-17/src/main.rs index 3df65a7ce..d854e287d 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-17/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-17/src/main.rs @@ -1,3 +1,4 @@ +// ANCHOR: here trait Pilot { fn fly(&self); } @@ -25,10 +26,6 @@ impl Human { println!("*waving arms furiously*"); } } - -// ANCHOR: here -fn main() { - let person = Human; - person.fly(); -} // ANCHOR_END: here + +fn main() {} diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-18/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-18/src/main.rs index fa01c09cc..3df65a7ce 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-18/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-18/src/main.rs @@ -29,8 +29,6 @@ impl Human { // ANCHOR: here fn main() { let person = Human; - Pilot::fly(&person); - Wizard::fly(&person); person.fly(); } // ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-19/output.txt b/rustbook-en/listings/ch20-advanced-features/listing-20-19/output.txt index b6e283f20..d7e315bfa 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-19/output.txt +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-19/output.txt @@ -1,5 +1,7 @@ $ cargo run Compiling traits-example v0.1.0 (file:///projects/traits-example) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.54s + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.46s Running `target/debug/traits-example` -A baby dog is called a Spot +This is your captain speaking. +Up! +*waving arms furiously* diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-19/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-19/src/main.rs index 44affe0ee..fa01c09cc 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-19/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-19/src/main.rs @@ -1,21 +1,36 @@ -trait Animal { - fn baby_name() -> String; +trait Pilot { + fn fly(&self); } -struct Dog; +trait Wizard { + fn fly(&self); +} + +struct Human; + +impl Pilot for Human { + fn fly(&self) { + println!("This is your captain speaking."); + } +} -impl Dog { - fn baby_name() -> String { - String::from("Spot") +impl Wizard for Human { + fn fly(&self) { + println!("Up!"); } } -impl Animal for Dog { - fn baby_name() -> String { - String::from("puppy") +impl Human { + fn fly(&self) { + println!("*waving arms furiously*"); } } +// ANCHOR: here fn main() { - println!("A baby dog is called a {}", Dog::baby_name()); + let person = Human; + Pilot::fly(&person); + Wizard::fly(&person); + person.fly(); } +// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-20/output.txt b/rustbook-en/listings/ch20-advanced-features/listing-20-20/output.txt index 0e78ae2d9..b6e283f20 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-20/output.txt +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-20/output.txt @@ -1,18 +1,5 @@ $ cargo run Compiling traits-example v0.1.0 (file:///projects/traits-example) -error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type - --> src/main.rs:20:43 - | -2 | fn baby_name() -> String; - | ------------------------- `Animal::baby_name` defined here -... -20 | println!("A baby dog is called a {}", Animal::baby_name()); - | ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait - | -help: use the fully-qualified path to the only available implementation - | -20 | println!("A baby dog is called a {}", ::baby_name()); - | +++++++ + - -For more information about this error, try `rustc --explain E0790`. -error: could not compile `traits-example` (bin "traits-example") due to 1 previous error + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.54s + Running `target/debug/traits-example` +A baby dog is called a Spot diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-20/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-20/src/main.rs index 8e295c9b6..44affe0ee 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-20/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-20/src/main.rs @@ -16,8 +16,6 @@ impl Animal for Dog { } } -// ANCHOR: here fn main() { - println!("A baby dog is called a {}", Animal::baby_name()); + println!("A baby dog is called a {}", Dog::baby_name()); } -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-21/output.txt b/rustbook-en/listings/ch20-advanced-features/listing-20-21/output.txt index f59d0bc27..0e78ae2d9 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-21/output.txt +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-21/output.txt @@ -1,5 +1,18 @@ $ cargo run Compiling traits-example v0.1.0 (file:///projects/traits-example) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.48s - Running `target/debug/traits-example` -A baby dog is called a puppy +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type + --> src/main.rs:20:43 + | +2 | fn baby_name() -> String; + | ------------------------- `Animal::baby_name` defined here +... +20 | println!("A baby dog is called a {}", Animal::baby_name()); + | ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait + | +help: use the fully-qualified path to the only available implementation + | +20 | println!("A baby dog is called a {}", ::baby_name()); + | +++++++ + + +For more information about this error, try `rustc --explain E0790`. +error: could not compile `traits-example` (bin "traits-example") due to 1 previous error diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-21/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-21/src/main.rs index b1df72895..8e295c9b6 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-21/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-21/src/main.rs @@ -18,6 +18,6 @@ impl Animal for Dog { // ANCHOR: here fn main() { - println!("A baby dog is called a {}", ::baby_name()); + println!("A baby dog is called a {}", Animal::baby_name()); } // ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-18/output.txt b/rustbook-en/listings/ch20-advanced-features/listing-20-22/output.txt similarity index 73% rename from rustbook-en/listings/ch20-advanced-features/listing-20-18/output.txt rename to rustbook-en/listings/ch20-advanced-features/listing-20-22/output.txt index d7e315bfa..f59d0bc27 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-18/output.txt +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-22/output.txt @@ -1,7 +1,5 @@ $ cargo run Compiling traits-example v0.1.0 (file:///projects/traits-example) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.46s + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.48s Running `target/debug/traits-example` -This is your captain speaking. -Up! -*waving arms furiously* +A baby dog is called a puppy diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-22/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-22/src/main.rs index 7069fef17..b1df72895 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-22/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-22/src/main.rs @@ -1,17 +1,23 @@ -// ANCHOR: here -use std::fmt; +trait Animal { + fn baby_name() -> String; +} + +struct Dog; -trait OutlinePrint: fmt::Display { - fn outline_print(&self) { - let output = self.to_string(); - let len = output.len(); - println!("{}", "*".repeat(len + 4)); - println!("*{}*", " ".repeat(len + 2)); - println!("* {output} *"); - println!("*{}*", " ".repeat(len + 2)); - println!("{}", "*".repeat(len + 4)); +impl Dog { + fn baby_name() -> String { + String::from("Spot") + } +} + +impl Animal for Dog { + fn baby_name() -> String { + String::from("puppy") } } -// ANCHOR_END: here -fn main() {} +// ANCHOR: here +fn main() { + println!("A baby dog is called a {}", ::baby_name()); +} +// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-23/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-23/src/main.rs index f8c8366b4..7069fef17 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-23/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-23/src/main.rs @@ -1,14 +1,17 @@ +// ANCHOR: here use std::fmt; -struct Wrapper(Vec); - -impl fmt::Display for Wrapper { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "[{}]", self.0.join(", ")) +trait OutlinePrint: fmt::Display { + fn outline_print(&self) { + let output = self.to_string(); + let len = output.len(); + println!("{}", "*".repeat(len + 4)); + println!("*{}*", " ".repeat(len + 2)); + println!("* {output} *"); + println!("*{}*", " ".repeat(len + 2)); + println!("{}", "*".repeat(len + 4)); } } +// ANCHOR_END: here -fn main() { - let w = Wrapper(vec![String::from("hello"), String::from("world")]); - println!("w = {w}"); -} +fn main() {} diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-24/Cargo.lock b/rustbook-en/listings/ch20-advanced-features/listing-20-24/Cargo.lock index c0c98a79c..b1977d01e 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-24/Cargo.lock +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-24/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] -name = "types-example" +name = "traits-example" version = "0.1.0" diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-24/Cargo.toml b/rustbook-en/listings/ch20-advanced-features/listing-20-24/Cargo.toml index a2ae20c77..52395a587 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-24/Cargo.toml +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-24/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "types-example" +name = "traits-example" version = "0.1.0" edition = "2021" diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-24/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-24/src/main.rs index d604ae8d6..f8c8366b4 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-24/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-24/src/main.rs @@ -1,16 +1,14 @@ -fn main() { - // ANCHOR: here - let f: Box = Box::new(|| println!("hi")); +use std::fmt; - fn takes_long_type(f: Box) { - // --snip-- - } +struct Wrapper(Vec); - fn returns_long_type() -> Box { - // --snip-- - // ANCHOR_END: here - Box::new(|| ()) - // ANCHOR: here +impl fmt::Display for Wrapper { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "[{}]", self.0.join(", ")) } - // ANCHOR_END: here +} + +fn main() { + let w = Wrapper(vec![String::from("hello"), String::from("world")]); + println!("w = {w}"); } diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-25/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-25/src/main.rs index af35bed2c..d604ae8d6 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-25/src/main.rs +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-25/src/main.rs @@ -1,14 +1,12 @@ fn main() { // ANCHOR: here - type Thunk = Box; + let f: Box = Box::new(|| println!("hi")); - let f: Thunk = Box::new(|| println!("hi")); - - fn takes_long_type(f: Thunk) { + fn takes_long_type(f: Box) { // --snip-- } - fn returns_long_type() -> Thunk { + fn returns_long_type() -> Box { // --snip-- // ANCHOR_END: here Box::new(|| ()) diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-27/Cargo.lock b/rustbook-en/listings/ch20-advanced-features/listing-20-26/Cargo.lock similarity index 81% rename from rustbook-en/listings/ch20-advanced-features/listing-20-27/Cargo.lock rename to rustbook-en/listings/ch20-advanced-features/listing-20-26/Cargo.lock index b2327c755..c0c98a79c 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-27/Cargo.lock +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-26/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] -name = "functions-example" +name = "types-example" version = "0.1.0" diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-27/Cargo.toml b/rustbook-en/listings/ch20-advanced-features/listing-20-26/Cargo.toml similarity index 69% rename from rustbook-en/listings/ch20-advanced-features/listing-20-27/Cargo.toml rename to rustbook-en/listings/ch20-advanced-features/listing-20-26/Cargo.toml index b196f35b5..a2ae20c77 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-27/Cargo.toml +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-26/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "functions-example" +name = "types-example" version = "0.1.0" edition = "2021" diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-26/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-26/src/main.rs new file mode 100644 index 000000000..af35bed2c --- /dev/null +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-26/src/main.rs @@ -0,0 +1,18 @@ +fn main() { + // ANCHOR: here + type Thunk = Box; + + let f: Thunk = Box::new(|| println!("hi")); + + fn takes_long_type(f: Thunk) { + // --snip-- + } + + fn returns_long_type() -> Thunk { + // --snip-- + // ANCHOR_END: here + Box::new(|| ()) + // ANCHOR: here + } + // ANCHOR_END: here +} diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-28/Cargo.lock b/rustbook-en/listings/ch20-advanced-features/listing-20-28/Cargo.lock index b2d925754..b2327c755 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-28/Cargo.lock +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-28/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] -name = "macros-example" +name = "functions-example" version = "0.1.0" diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-28/Cargo.toml b/rustbook-en/listings/ch20-advanced-features/listing-20-28/Cargo.toml index 9218091c8..b196f35b5 100644 --- a/rustbook-en/listings/ch20-advanced-features/listing-20-28/Cargo.toml +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-28/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "macros-example" +name = "functions-example" version = "0.1.0" edition = "2021" diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-27/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-28/src/main.rs similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-27/src/main.rs rename to rustbook-en/listings/ch20-advanced-features/listing-20-28/src/main.rs diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-29/Cargo.lock b/rustbook-en/listings/ch20-advanced-features/listing-20-29/Cargo.lock new file mode 100644 index 000000000..b2d925754 --- /dev/null +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-29/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "macros-example" +version = "0.1.0" + diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-29/Cargo.toml b/rustbook-en/listings/ch20-advanced-features/listing-20-29/Cargo.toml new file mode 100644 index 000000000..9218091c8 --- /dev/null +++ b/rustbook-en/listings/ch20-advanced-features/listing-20-29/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "macros-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-28/src/lib.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-29/src/lib.rs similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-28/src/lib.rs rename to rustbook-en/listings/ch20-advanced-features/listing-20-29/src/lib.rs diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-30/Cargo.lock b/rustbook-en/listings/ch20-advanced-features/listing-20-31/Cargo.lock similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-30/Cargo.lock rename to rustbook-en/listings/ch20-advanced-features/listing-20-31/Cargo.lock diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-30/Cargo.toml b/rustbook-en/listings/ch20-advanced-features/listing-20-31/Cargo.toml similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-30/Cargo.toml rename to rustbook-en/listings/ch20-advanced-features/listing-20-31/Cargo.toml diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-30/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-31/src/main.rs similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-30/src/main.rs rename to rustbook-en/listings/ch20-advanced-features/listing-20-31/src/main.rs diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/Cargo.lock b/rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/Cargo.lock similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/Cargo.lock rename to rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/Cargo.lock diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/Cargo.toml b/rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/Cargo.toml similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/Cargo.toml rename to rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/Cargo.toml diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/hello_macro_derive/Cargo.lock b/rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/hello_macro_derive/Cargo.lock similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/hello_macro_derive/Cargo.lock rename to rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/hello_macro_derive/Cargo.lock diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/hello_macro_derive/Cargo.toml b/rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/hello_macro_derive/Cargo.toml similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/hello_macro_derive/Cargo.toml rename to rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/hello_macro_derive/Cargo.toml diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/hello_macro_derive/src/lib.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/hello_macro_derive/src/lib.rs similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/hello_macro_derive/src/lib.rs rename to rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/hello_macro_derive/src/lib.rs diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/src/lib.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/src/lib.rs similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/src/lib.rs rename to rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/src/lib.rs diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/src/main.rs similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-31/hello_macro/src/main.rs rename to rustbook-en/listings/ch20-advanced-features/listing-20-32/hello_macro/src/main.rs diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/Cargo.lock b/rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/Cargo.lock similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/Cargo.lock rename to rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/Cargo.lock diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/Cargo.toml b/rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/Cargo.toml similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/Cargo.toml rename to rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/Cargo.toml diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/hello_macro_derive/Cargo.lock b/rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/hello_macro_derive/Cargo.lock similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/hello_macro_derive/Cargo.lock rename to rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/hello_macro_derive/Cargo.lock diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/hello_macro_derive/Cargo.toml b/rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/hello_macro_derive/Cargo.toml similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/hello_macro_derive/Cargo.toml rename to rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/hello_macro_derive/Cargo.toml diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/hello_macro_derive/src/lib.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/hello_macro_derive/src/lib.rs similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/hello_macro_derive/src/lib.rs rename to rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/hello_macro_derive/src/lib.rs diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/src/lib.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/src/lib.rs similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/src/lib.rs rename to rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/src/lib.rs diff --git a/rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/src/main.rs b/rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/src/main.rs similarity index 100% rename from rustbook-en/listings/ch20-advanced-features/listing-20-33/hello_macro/src/main.rs rename to rustbook-en/listings/ch20-advanced-features/listing-20-34/hello_macro/src/main.rs diff --git a/rustbook-en/src/ch01-01-installation.md b/rustbook-en/src/ch01-01-installation.md index 64968f6bc..f554c94b7 100644 --- a/rustbook-en/src/ch01-01-installation.md +++ b/rustbook-en/src/ch01-01-installation.md @@ -134,7 +134,16 @@ Any time a type or function is provided by the standard library and you’re not sure what it does or how to use it, use the application programming interface (API) documentation to find out! +### Text Editors and Integrated Development Environments + +This book makes no assumptions about what tools you use to author Rust code. +Just about any text editor will get the job done! However, many text editors and +integrated development environments (IDEs) have built-in support for Rust. You +can always find a fairly current list of many editors and IDEs on [the tools +page][tools] on the Rust website. + [otherinstall]: https://forge.rust-lang.org/infra/other-installation-methods.html [install]: https://www.rust-lang.org/tools/install [msvc]: https://rust-lang.github.io/rustup/installation/windows-msvc.html [community]: https://www.rust-lang.org/community +[tools]: https://www.rust-lang.org/tools diff --git a/rustbook-en/src/ch03-02-data-types.md b/rustbook-en/src/ch03-02-data-types.md index 84af90e3f..881319dbc 100644 --- a/rustbook-en/src/ch03-02-data-types.md +++ b/rustbook-en/src/ch03-02-data-types.md @@ -141,8 +141,7 @@ Here’s an example that shows floating-point numbers in action: {{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-06-floating-point/src/main.rs}} ``` -Floating-point numbers are represented according to the IEEE-754 standard. The -`f32` type is a single-precision float, and `f64` has double precision. +Floating-point numbers are represented according to the IEEE-754 standard. #### Numeric Operations diff --git a/rustbook-en/src/ch06-03-if-let.md b/rustbook-en/src/ch06-03-if-let.md index fee6b2caf..829d01169 100644 --- a/rustbook-en/src/ch06-03-if-let.md +++ b/rustbook-en/src/ch06-03-if-let.md @@ -32,8 +32,8 @@ sign. It works the same way as a `match`, where the expression is given to the `match` and the pattern is its first arm. In this case, the pattern is `Some(max)`, and the `max` binds to the value inside the `Some`. We can then use `max` in the body of the `if let` block in the same way we used `max` in -the corresponding `match` arm. The code in the `if let` block isn’t run if the -value doesn’t match the pattern. +the corresponding `match` arm. The code in the `if let` block only runs if the +value matches the pattern. Using `if let` means less typing, less indentation, and less boilerplate code. However, you lose the exhaustive checking that `match` enforces. Choosing diff --git a/rustbook-en/src/ch17-05-traits-for-async.md b/rustbook-en/src/ch17-05-traits-for-async.md index 1b7b23b7d..e3819d9a4 100644 --- a/rustbook-en/src/ch17-05-traits-for-async.md +++ b/rustbook-en/src/ch17-05-traits-for-async.md @@ -92,9 +92,9 @@ loop { ``` If Rust compiled it to exactly that code, though, every `await` would be -blocking—exactly the opposite of what we were going for! Instead, Rust needs -makes sure that the loop can hand off control to something which can pause work -on this future and work on other futures and check this one again later. That +blocking—exactly the opposite of what we were going for! Instead, Rust makes +sure that the loop can hand off control to something which can pause work on +this future and work on other futures and check this one again later. That “something” is an async runtime, and this scheduling and coordination work is one of the main jobs for a runtime. @@ -153,10 +153,10 @@ future with `await` pins the future implicitly. That’s why we don’t need to However, we’re not directly awaiting a future here. Instead, we construct a new future, `JoinAll`, by passing a collection of futures to the `join_all` -function. The signature for `join_all` produces requires that the type of the -items in the collection all implement the `Future` trait, and `Box` only -implements `Future` if the `T` that it wraps is a future which implements the -`Unpin` trait. +function. The signature for `join_all` requires that the type of the items in +the collection all implement the `Future` trait, and `Box` only implements +`Future` if the `T` that it wraps is a future which implements the `Unpin` +trait. That’s a lot! But we can understand it, if we dive a little further into how the `Future` type actually works, in particular around *pinning*. diff --git a/rustbook-en/src/ch20-01-unsafe-rust.md b/rustbook-en/src/ch20-01-unsafe-rust.md index 156c0f05f..935b4fe43 100644 --- a/rustbook-en/src/ch20-01-unsafe-rust.md +++ b/rustbook-en/src/ch20-01-unsafe-rust.md @@ -103,7 +103,7 @@ raw pointers in safe code; we just can’t dereference raw pointers outside an unsafe block, as you’ll see in a bit. We’ve created raw pointers by using the raw borrow operators: `&raw const num` -creates a `*const i32` immutable raw pointer, and `&raw mut num` creates a `&mut +creates a `*const i32` immutable raw pointer, and `&raw mut num` creates a `*mut i32` mutable raw pointer. Because we created them directly from a local variable, we know these particular raw pointers are valid, but we can’t make that assumption about just any raw pointer. @@ -311,9 +311,10 @@ programming language to call those functions. Listing 20-8 demonstrates how to set up an integration with the `abs` function from the C standard library. Functions declared within `extern` blocks are -always unsafe to call from Rust code. The reason is that other languages don’t -enforce Rust’s rules and guarantees, and Rust can’t check them, so -responsibility falls on the programmer to ensure safety. +usually unsafe to call from Rust code, so they must also be marked `unsafe`. The +reason is that other languages don’t enforce Rust’s rules and guarantees, and +Rust can’t check them, so responsibility falls on the programmer to ensure +safety. @@ -323,30 +324,51 @@ responsibility falls on the programmer to ensure safety. -Within the `extern "C"` block, we list the names and signatures of external -functions from another language we want to call. The `"C"` part defines which -*application binary interface (ABI)* the external function uses: the ABI +Within the `unsafe extern "C"` block, we list the names and signatures of +external functions from another language we want to call. The `"C"` part defines +which *application binary interface (ABI)* the external function uses: the ABI defines how to call the function at the assembly level. The `"C"` ABI is the most common and follows the C programming language’s ABI. +This particular function does not have any memory safety considerations, though. +In fact, we know that any call to `abs` will always be safe for any `i32`, so we +can use the `safe` keyword to say that this specific function is safe to call +even though it is in an `unsafe extern` block. Once we make that change, calling +it no longer requires an `unsafe` block, as shown in Listing 20-9. + ++ +```rust +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-09/src/main.rs}} +``` + + + +Marking a function as `safe` does not inherently make it safe! Instead, it is +like a promise you are making to Rust that it *is* safe. It is still your +responsibility to make sure that promise is kept! + > #### Calling Rust Functions from Other Languages > -> We can also use `extern` to create an interface that allows other languages -> to call Rust functions. Instead of creating a whole `extern` block, we add -> the `extern` keyword and specify the ABI to use just before the `fn` keyword -> for the relevant function. We also need to add a `#[no_mangle]` annotation to -> tell the Rust compiler not to mangle the name of this function. *Mangling* is -> when a compiler changes the name we’ve given a function to a different name +> We can also use `extern` to create an interface that allows other languages to +> call Rust functions. Instead of creating a whole `extern` block, we add the +> `extern` keyword and specify the ABI to use just before the `fn` keyword for +> the relevant function. We also need to add a `#[unsafe(no_mangle)]` annotation +> to tell the Rust compiler not to mangle the name of this function. *Mangling* +> is when a compiler changes the name we’ve given a function to a different name > that contains more information for other parts of the compilation process to > consume but is less human readable. Every programming language compiler > mangles names slightly differently, so for a Rust function to be nameable by -> other languages, we must disable the Rust compiler’s name mangling. +> other languages, we must disable the Rust compiler’s name mangling. This is +> unsafe because there might be name collisions across libraries without the +> built-in mangling, so it is our responsibility to make sure the name we have +> exported is safe to export without mangling. > > In the following example, we make the `call_from_c` function accessible from > C code, after it’s compiled to a shared library and linked from C: > > ```rust -> #[no_mangle] +> #[unsafe(no_mangle)] > pub extern "C" fn call_from_c() { > println!("Just called a Rust function from C!"); > } @@ -360,14 +382,14 @@ In this book, we’ve not yet talked about *global variables*, which Rust does support but can be problematic with Rust’s ownership rules. If two threads are accessing the same mutable global variable, it can cause a data race. -In Rust, global variables are called *static* variables. Listing 20-9 shows an +In Rust, global variables are called *static* variables. Listing 20-10 shows an example declaration and use of a static variable with a string slice as a value. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-09/src/main.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-10/src/main.rs}} ``` @@ -386,13 +408,13 @@ values in a static variable have a fixed address in memory. Using the value will always access the same data. Constants, on the other hand, are allowed to duplicate their data whenever they’re used. Another difference is that static variables can be mutable. Accessing and modifying mutable static variables is -*unsafe*. Listing 20-10 shows how to declare, access, and modify a mutable +*unsafe*. Listing 20-11 shows how to declare, access, and modify a mutable static variable named `COUNTER`. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-10/src/main.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-11/src/main.rs}} ``` @@ -423,12 +445,12 @@ We can use `unsafe` to implement an unsafe trait. A trait is unsafe when at least one of its methods has some invariant that the compiler can’t verify. We declare that a trait is `unsafe` by adding the `unsafe` keyword before `trait` and marking the implementation of the trait as `unsafe` too, as shown in -Listing 20-11. +Listing 20-12. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-11/src/main.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-12/src/main.rs}} ``` @@ -463,7 +485,7 @@ actually is safe and correct. One of the best ways to do that is to use [Miri][miri], an official Rust tool for detecting undefined behavior. Whereas the borrow checker is a *static* tool which works at compile time, Miri is a *dynamic* tool which works at runtime. It checks your code by running your -program, or its test suite, and detecting when you violate the rules its +program, or its test suite, and detecting when you violate the rules it understands about how Rust should work. Using Miri requires a nightly build of Rust (which we talk about more in @@ -475,10 +497,10 @@ You can run Miri on a project by typing `cargo +nightly miri run` or `cargo +nightly miri test`. For an example of how helpful this can be, consider what happens when we run it -against Listing 20-10: +against Listing 20-11: ```console -{{#include ../listings/ch20-advanced-features/listing-20-10/output.txt}} +{{#include ../listings/ch20-advanced-features/listing-20-11/output.txt}} ``` It helpfully and correctly notices that we have shared references to mutable diff --git a/rustbook-en/src/ch20-03-advanced-traits.md b/rustbook-en/src/ch20-03-advanced-traits.md index e411dd57d..d95b1d9b9 100644 --- a/rustbook-en/src/ch20-03-advanced-traits.md +++ b/rustbook-en/src/ch20-03-advanced-traits.md @@ -23,12 +23,12 @@ 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. The definition of the `Iterator` trait is as shown in Listing -20-12. +20-13. -+ ```rust,noplayground -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-12/src/lib.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-13/src/lib.rs}} ``` @@ -53,17 +53,17 @@ the `Item` type is `u32`: This syntax seems comparable to that of generics. So why not just define the -`Iterator` trait with generics, as shown in Listing 20-13? +`Iterator` trait with generics, as shown in Listing 20-14? -+ ```rust,noplayground -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-13/src/lib.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-14/src/lib.rs}} ``` -The difference is that when using generics, as in Listing 20-13, we must +The difference is that when using generics, as in Listing 20-14, we must annotate the types in each implementation; because we can also implement `Iterator for Counter` or any other type, we could have multiple implementations of `Iterator` for `Counter`. In other words, when a trait has a @@ -73,7 +73,7 @@ the concrete types of the generic type parameters each time. When we use the indicate which implementation of `Iterator` we want to use. With associated types, we don’t need to annotate types because we can’t -implement a trait on a type multiple times. In Listing 20-12 with the +implement a trait on a type multiple times. In Listing 20-13 with the definition that uses associated types, we can only choose what the type of `Item` will be once, because there can only be one `impl Iterator for Counter`. We don’t have to specify that we want an iterator of `u32` values everywhere @@ -98,14 +98,14 @@ in particular situations. Rust doesn’t allow you to create your own operators or overload arbitrary operators. But you can overload the operations and corresponding traits listed in `std::ops` by implementing the traits associated with the operator. For -example, in Listing 20-14 we overload the `+` operator to add two `Point` +example, in Listing 20-15 we overload the `+` operator to add two `Point` instances together. We do this by implementing the `Add` trait on a `Point` struct: -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-14/src/main.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-15/src/main.rs}} ``` @@ -145,12 +145,12 @@ units. This thin wrapping of an existing type in another struct is known as the Pattern to Implement External Traits on External Types”][newtype] section. We want to add values in millimeters to values in meters and have the implementation of `Add` do the conversion correctly. We can implement `Add` -for `Millimeters` with `Meters` as the `Rhs`, as shown in Listing 20-15. +for `Millimeters` with `Meters` as the `Rhs`, as shown in Listing 20-16. -+ ```rust,noplayground -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-15/src/lib.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-16/src/lib.rs}} ``` @@ -183,26 +183,26 @@ on one type. It’s also possible to implement a method directly on the type wit the same name as methods from traits. When calling methods with the same name, you’ll need to tell Rust which one you -want to use. Consider the code in Listing 20-16 where we’ve defined two traits, +want to use. Consider the code in Listing 20-17 where we’ve defined two traits, `Pilot` and `Wizard`, that both have a method called `fly`. We then implement both traits on a type `Human` that already has a method named `fly` implemented on it. Each `fly` method does something different. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-16/src/main.rs:here}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-17/src/main.rs:here}} ``` When we call `fly` on an instance of `Human`, the compiler defaults to calling -the method that is directly implemented on the type, as shown in Listing 20-17. +the method that is directly implemented on the type, as shown in Listing 20-18. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-17/src/main.rs:here}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-18/src/main.rs:here}} ``` @@ -212,12 +212,12 @@ called the `fly` method implemented on `Human` directly. To call the `fly` methods from either the `Pilot` trait or the `Wizard` trait, we need to use more explicit syntax to specify which `fly` method we mean. -Listing 20-18 demonstrates this syntax. +Listing 20-19 demonstrates this syntax. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-18/src/main.rs:here}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-19/src/main.rs:here}} ``` @@ -225,13 +225,13 @@ Listing 20-18 demonstrates this syntax. Specifying the trait name before the method name clarifies to Rust which implementation of `fly` we want to call. We could also write `Human::fly(&person)`, which is equivalent to the `person.fly()` that we used -in Listing 20-18, but this is a bit longer to write if we don’t need to +in Listing 20-19, but this is a bit longer to write if we don’t need to disambiguate. Running this code prints the following: ```console -{{#include ../listings/ch20-advanced-features/listing-20-18/output.txt}} +{{#include ../listings/ch20-advanced-features/listing-20-19/output.txt}} ``` Because the `fly` method takes a `self` parameter, if we had two *types* that @@ -241,16 +241,16 @@ trait to use based on the type of `self`. However, associated functions that are not methods don’t have a `self` parameter. When there are multiple types or traits that define non-method functions with the same function name, Rust doesn't always know which type you -mean unless you use *fully qualified syntax*. For example, in Listing 20-19 we +mean unless you use *fully qualified syntax*. For example, in Listing 20-20 we create a trait for an animal shelter that wants to name all baby dogs *Spot*. We make an `Animal` trait with an associated non-method function `baby_name`. The `Animal` trait is implemented for the struct `Dog`, on which we also provide an associated non-method function `baby_name` directly. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-19/src/main.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-20/src/main.rs}} ``` @@ -265,19 +265,19 @@ In `main`, we call the `Dog::baby_name` function, which calls the associated function defined on `Dog` directly. This code prints the following: ```console -{{#include ../listings/ch20-advanced-features/listing-20-19/output.txt}} +{{#include ../listings/ch20-advanced-features/listing-20-20/output.txt}} ``` This output isn’t what we wanted. We want to call the `baby_name` function that is part of the `Animal` trait that we implemented on `Dog` so the code prints `A baby dog is called a puppy`. The technique of specifying the trait name that -we used in Listing 20-18 doesn’t help here; if we change `main` to the code in -Listing 20-20, we’ll get a compilation error. +we used in Listing 20-19 doesn’t help here; if we change `main` to the code in +Listing 20-21, we’ll get a compilation error. -+ ```rust,ignore,does_not_compile -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-20/src/main.rs:here}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-21/src/main.rs:here}} ``` @@ -287,18 +287,18 @@ other types that implement the `Animal` trait, Rust can’t figure out which implementation of `Animal::baby_name` we want. We’ll get this compiler error: ```console -{{#include ../listings/ch20-advanced-features/listing-20-20/output.txt}} +{{#include ../listings/ch20-advanced-features/listing-20-21/output.txt}} ``` To disambiguate and tell Rust that we want to use the implementation of `Animal` for `Dog` as opposed to the implementation of `Animal` for some other -type, we need to use fully qualified syntax. Listing 20-21 demonstrates how to +type, we need to use fully qualified syntax. Listing 20-22 demonstrates how to use fully qualified syntax. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-21/src/main.rs:here}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-22/src/main.rs:here}} ``` @@ -309,7 +309,7 @@ implemented on `Dog` by saying that we want to treat the `Dog` type as an `Animal` for this function call. This code will now print what we want: ```console -{{#include ../listings/ch20-advanced-features/listing-20-21/output.txt}} +{{#include ../listings/ch20-advanced-features/listing-20-22/output.txt}} ``` In general, fully qualified syntax is defined as follows: @@ -354,13 +354,13 @@ In the implementation of the `outline_print` method, we want to use the `OutlinePrint` trait will work only for types that also implement `Display` and provide the functionality that `OutlinePrint` needs. We can do that in the trait definition by specifying `OutlinePrint: Display`. This technique is -similar to adding a trait bound to the trait. Listing 20-22 shows an +similar to adding a trait bound to the trait. Listing 20-23 shows an implementation of the `OutlinePrint` trait. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-22/src/main.rs:here}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-23/src/main.rs:here}} ``` @@ -424,12 +424,12 @@ 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 `Vec` type are defined outside our crate. We can make a `Wrapper` struct that holds an instance of `Vec`; then we can implement `Display` on -`Wrapper` and use the `Vec` value, as shown in Listing 20-23. +`Wrapper` and use the `Vec` value, as shown in Listing 20-24. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-23/src/main.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-24/src/main.rs}} ``` diff --git a/rustbook-en/src/ch20-04-advanced-types.md b/rustbook-en/src/ch20-04-advanced-types.md index 88f2b36f6..a3f1f4320 100644 --- a/rustbook-en/src/ch20-04-advanced-types.md +++ b/rustbook-en/src/ch20-04-advanced-types.md @@ -15,7 +15,7 @@ the `!` type and dynamically sized types. The newtype pattern is also useful for tasks beyond those we’ve discussed so far, including statically enforcing that values are never confused and indicating the units of a value. You saw an example of using newtypes to -indicate units in Listing 20-15: recall that the `Millimeters` and `Meters` +indicate units in Listing 20-16: recall that the `Millimeters` and `Meters` structs wrapped `u32` values in a newtype. If we wrote a function with a parameter of type `Millimeters`, we couldn’t compile a program that accidentally tried to call that function with a value of type `Meters` or a @@ -47,7 +47,7 @@ the alias `Kilometers` to `i32` like so: ``` Now, the alias `Kilometers` is a *synonym* for `i32`; unlike the `Millimeters` -and `Meters` types we created in Listing 20-15, `Kilometers` is not a separate, +and `Meters` types we created in Listing 20-16, `Kilometers` is not a separate, new type. Values that have the type `Kilometers` will be treated the same as values of type `i32`: @@ -71,24 +71,24 @@ Box Writing this lengthy type in function signatures and as type annotations all over the code can be tiresome and error prone. Imagine having a project full of -code like that in Listing 20-24. +code like that in Listing 20-25. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-24/src/main.rs:here}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-25/src/main.rs:here}} ``` A type alias makes this code more manageable by reducing the repetition. In -Listing 20-25, we’ve introduced an alias named `Thunk` for the verbose type and +Listing 20-26, we’ve introduced an alias named `Thunk` for the verbose type and can replace all uses of the type with the shorter alias `Thunk`. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-25/src/main.rs:here}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-26/src/main.rs:here}} ``` @@ -148,9 +148,9 @@ so `bar` can never possibly return. But what use is a type you can never create values for? Recall the code from Listing 2-5, part of the number guessing game; we’ve reproduced a bit of it -here in Listing 20-26. +here in Listing 20-27. -+ ```rust,ignore {{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs:ch19}} @@ -170,7 +170,7 @@ example, the following code doesn’t work: The type of `guess` in this code would have to be an integer *and* a string, and Rust requires that `guess` have only one type. So what does `continue` return? How were we allowed to return a `u32` from one arm and have another arm -that ends with `continue` in Listing 20-26? +that ends with `continue` in Listing 20-27? As you might have guessed, `continue` has a `!` value. That is, when Rust computes the type of `guess`, it looks at both match arms, the former with a @@ -191,7 +191,7 @@ this definition: {{#rustdoc_include ../listings/ch20-advanced-features/no-listing-09-unwrap-definition/src/lib.rs:here}} ``` -In this code, the same thing happens as in the `match` in Listing 20-26: Rust +In this code, the same thing happens as in the `match` in Listing 20-27: Rust sees that `val` has the type `T` and `panic!` has the type `!`, so the result of the overall `match` expression is `T`. This code works because `panic!` doesn’t produce a value; it ends the program. In the `None` case, we won’t be diff --git a/rustbook-en/src/ch20-05-advanced-functions-and-closures.md b/rustbook-en/src/ch20-05-advanced-functions-and-closures.md index 70385af32..618568d0d 100644 --- a/rustbook-en/src/ch20-05-advanced-functions-and-closures.md +++ b/rustbook-en/src/ch20-05-advanced-functions-and-closures.md @@ -14,7 +14,7 @@ with function pointers will allow you to use functions as arguments to other functions. The syntax for specifying that a parameter is a function pointer is similar to -that of closures, as shown in Listing 20-27, where we’ve defined a function +that of closures, as shown in Listing 20-28, where we’ve defined a function `add_one` that adds one to its parameter. The function `do_twice` takes two parameters: a function pointer to any function that takes an `i32` parameter and returns an `i32`, and one `i32` value. The `do_twice` function calls the @@ -22,10 +22,10 @@ function `f` twice, passing it the `arg` value, then adds the two function call results together. The `main` function calls `do_twice` with the arguments `add_one` and `5`. -+ ```rust -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-27/src/main.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-28/src/main.rs}} ``` diff --git a/rustbook-en/src/ch20-06-macros.md b/rustbook-en/src/ch20-06-macros.md index 7900a015b..cd4ded07d 100644 --- a/rustbook-en/src/ch20-06-macros.md +++ b/rustbook-en/src/ch20-06-macros.md @@ -73,12 +73,12 @@ We could also use the `vec!` macro to make a vector of two integers or a vector of five string slices. We wouldn’t be able to use a function to do the same because we wouldn’t know the number or type of values up front. -Listing 20-28 shows a slightly simplified definition of the `vec!` macro. +Listing 20-29 shows a slightly simplified definition of the `vec!` macro. -+ ```rust,noplayground -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-28/src/lib.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-29/src/lib.rs}} ``` @@ -106,7 +106,7 @@ one arm. Valid pattern syntax in macro definitions is different than the pattern syntax covered in Chapter 19 because macro patterns are matched against Rust code structure rather than values. Let’s walk through what the pattern pieces in -Listing 20-28 mean; for the full macro pattern syntax, see the [Rust +Listing 20-29 mean; for the full macro pattern syntax, see the [Rust Reference][ref]. First, we use a set of parentheses to encompass the whole pattern. We use a @@ -159,11 +159,11 @@ attribute-like, and function-like, and all work in a similar fashion. When creating procedural macros, the definitions must reside in their own crate with a special crate type. This is for complex technical reasons that we hope -to eliminate in the future. In Listing 20-29, we show how to define a +to eliminate in the future. In Listing 20-30, we show how to define a procedural macro, where `some_attribute` is a placeholder for using a specific macro variety. -+ ```rust,ignore use proc_macro; @@ -198,12 +198,12 @@ we’ll provide a procedural macro so users can annotate their type with function. The default implementation will print `Hello, Macro! My name is TypeName!` where `TypeName` is the name of the type on which this trait has been defined. In other words, we’ll write a crate that enables another -programmer to write code like Listing 20-30 using our crate. +programmer to write code like Listing 20-31 using our crate. -+ ```rust,ignore,does_not_compile -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-30/src/main.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-31/src/main.rs}} ``` @@ -271,19 +271,19 @@ in a moment, so we need to add them as dependencies. Add the following to the ```toml -{{#include ../listings/ch20-advanced-features/listing-20-31/hello_macro/hello_macro_derive/Cargo.toml:6:12}} +{{#include ../listings/ch20-advanced-features/listing-20-32/hello_macro/hello_macro_derive/Cargo.toml:6:12}} ``` -To start defining the procedural macro, place the code in Listing 20-31 into +To start defining the procedural macro, place the code in Listing 20-32 into your *src/lib.rs* file for the `hello_macro_derive` crate. Note that this code won’t compile until we add a definition for the `impl_hello_macro` function. -+ ```rust,ignore,does_not_compile -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-31/hello_macro/hello_macro_derive/src/lib.rs}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-32/hello_macro/hello_macro_derive/src/lib.rs}} ``` @@ -318,10 +318,10 @@ The `hello_macro_derive` function first converts the `input` from a `TokenStream` to a data structure that we can then interpret and perform operations on. This is where `syn` comes into play. The `parse` function in `syn` takes a `TokenStream` and returns a `DeriveInput` struct representing the -parsed Rust code. Listing 20-32 shows the relevant parts of the `DeriveInput` +parsed Rust code. Listing 20-33 shows the relevant parts of the `DeriveInput` struct we get from parsing the `struct Pancakes;` string: -+ ```rust,ignore DeriveInput { @@ -367,23 +367,23 @@ about what went wrong by using `panic!` or `expect`. Now that we have the code to turn the annotated Rust code from a `TokenStream` into a `DeriveInput` instance, let’s generate the code that implements the -`HelloMacro` trait on the annotated type, as shown in Listing 20-33. +`HelloMacro` trait on the annotated type, as shown in Listing 20-34. -+ ```rust,ignore -{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-33/hello_macro/hello_macro_derive/src/lib.rs:here}} +{{#rustdoc_include ../listings/ch20-advanced-features/listing-20-34/hello_macro/hello_macro_derive/src/lib.rs:here}} ``` We get an `Ident` struct instance containing the name (identifier) of the -annotated type using `ast.ident`. The struct in Listing 20-32 shows that when -we run the `impl_hello_macro` function on the code in Listing 20-30, the +annotated type using `ast.ident`. The struct in Listing 20-33 shows that when +we run the `impl_hello_macro` function on the code in Listing 20-31, the `ident` we get will have the `ident` field with a value of `"Pancakes"`. Thus, -the `name` variable in Listing 20-33 will contain an `Ident` struct instance +the `name` variable in Listing 20-34 will contain an `Ident` struct instance that, when printed, will be the string `"Pancakes"`, the name of the struct in -Listing 20-30. +Listing 20-31. The `quote!` macro lets us define the Rust code that we want to return. The compiler expects something different to the direct result of the `quote!` @@ -412,7 +412,7 @@ saves an allocation by converting `#name` to a string literal at compile time. At this point, `cargo build` should complete successfully in both `hello_macro` and `hello_macro_derive`. Let’s hook up these crates to the code in Listing -20-30 to see the procedural macro in action! Create a new binary project in +20-31 to see the procedural macro in action! Create a new binary project in your *projects* directory using `cargo new pancakes`. We need to add `hello_macro` and `hello_macro_derive` as dependencies in the `pancakes` crate’s *Cargo.toml*. If you’re publishing your versions of `hello_macro` and @@ -423,7 +423,7 @@ dependencies; if not, you can specify them as `path` dependencies as follows: {{#include ../listings/ch20-advanced-features/no-listing-21-pancakes/pancakes/Cargo.toml:7:9}} ``` -Put the code in Listing 20-30 into *src/main.rs*, and run `cargo run`: it +Put the code in Listing 20-31 into *src/main.rs*, and run `cargo run`: it should print `Hello, Macro! My name is Pancakes!` The implementation of the `HelloMacro` trait from the procedural macro was included without the `pancakes` crate needing to implement it; the `#[derive(HelloMacro)]` added the