-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rust 2024: update Ch. 20 for new
unsafe
rules
- `extern` now requires `unsafe extern`, but in turn allows functions within it to be marked as `safe`. Add examples to both effects within the text, and update listing numbers accordingly. - `#[no_mangle]` now requires `#[unsafe(no_mangle)]` These are all backwards-compatible, so we can opt the chapter into using the new rules without issue.
- Loading branch information
1 parent
e16dd73
commit 93d741a
Showing
60 changed files
with
303 additions
and
262 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
extern "C" { | ||
unsafe extern "C" { | ||
fn abs(input: i32) -> i32; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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}"); | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
[package] | ||
name = "traits-example" | ||
name = "unsafe-example" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
unsafe trait Foo { | ||
// methods go here | ||
} | ||
|
||
unsafe impl Foo for i32 { | ||
// method implementations go here | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
pub trait Iterator<T> { | ||
fn next(&mut self) -> Option<T>; | ||
pub trait Iterator { | ||
type Item; | ||
|
||
fn next(&mut self) -> Option<Self::Item>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub trait Iterator<T> { | ||
fn next(&mut self) -> Option<T>; | ||
} |
File renamed without changes.
File renamed without changes.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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* |
35 changes: 25 additions & 10 deletions
35
listings/ch20-advanced-features/listing-20-19/src/main.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 {}", <Dog as Animal>::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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 {}", <Dog as Animal>::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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 2 additions & 4 deletions
6
...dvanced-features/listing-20-18/output.txt → ...dvanced-features/listing-20-22/output.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
32 changes: 19 additions & 13 deletions
32
listings/ch20-advanced-features/listing-20-22/src/main.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 {}", <Dog as Animal>::baby_name()); | ||
} | ||
// ANCHOR_END: here |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,17 @@ | ||
// ANCHOR: here | ||
use std::fmt; | ||
|
||
struct Wrapper(Vec<String>); | ||
|
||
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() {} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
[package] | ||
name = "types-example" | ||
name = "traits-example" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
|
22 changes: 10 additions & 12 deletions
22
listings/ch20-advanced-features/listing-20-24/src/main.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,14 @@ | ||
fn main() { | ||
// ANCHOR: here | ||
let f: Box<dyn Fn() + Send + 'static> = Box::new(|| println!("hi")); | ||
use std::fmt; | ||
|
||
fn takes_long_type(f: Box<dyn Fn() + Send + 'static>) { | ||
// --snip-- | ||
} | ||
struct Wrapper(Vec<String>); | ||
|
||
fn returns_long_type() -> Box<dyn Fn() + Send + 'static> { | ||
// --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}"); | ||
} |
Oops, something went wrong.