summaryrefslogtreecommitdiffstats
path: root/src/doc/book/listings/ch15-smart-pointers
diff options
context:
space:
mode:
Diffstat (limited to 'src/doc/book/listings/ch15-smart-pointers')
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-01/src/main.rs4
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-02/src/main.rs8
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt27
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-03/src/main.rs12
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-05/src/main.rs10
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-06/src/main.rs7
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-07/src/main.rs7
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-08/src/main.rs11
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-09/output.txt10
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-09/src/main.rs17
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-10/src/main.rs27
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-11/src/main.rs7
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-12/src/main.rs28
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-13/src/main.rs28
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-14/output.txt7
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-14/src/main.rs19
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-15/output.txt13
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-15/src/main.rs20
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-16/output.txt7
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-16/src/main.rs20
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-17/output.txt14
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-17/src/main.rs12
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-18/src/main.rs13
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-19/output.txt8
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-19/src/main.rs21
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-20/src/lib.rs38
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-21/output.txt14
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-21/src/lib.rs73
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-22/src/lib.rs78
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt21
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-23/src/lib.rs78
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-24/output.txt7
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-24/src/main.rs24
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-25/src/main.rs20
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-26/output.txt11
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-26/src/main.rs44
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-27/src/main.rs24
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-28/src/main.rs33
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-29/src/main.rs54
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt12
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs4
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml6
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt23
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/src/main.rs7
103 files changed, 1282 insertions, 0 deletions
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.lock
new file mode 100644
index 000000000..8c125fc84
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "box-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.toml
new file mode 100644
index 000000000..690385c7a
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "box-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-01/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/src/main.rs
new file mode 100644
index 000000000..8da1d905d
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-01/src/main.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let b = Box::new(5);
+ println!("b = {}", b);
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.lock
new file mode 100644
index 000000000..a792c49aa
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "cons-list"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.toml
new file mode 100644
index 000000000..dce1515c3
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "cons-list"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-02/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/src/main.rs
new file mode 100644
index 000000000..84640b9b9
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-02/src/main.rs
@@ -0,0 +1,8 @@
+// ANCHOR: here
+enum List {
+ Cons(i32, List),
+ Nil,
+}
+// ANCHOR_END: here
+
+fn main() {}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.lock
new file mode 100644
index 000000000..a792c49aa
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "cons-list"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.toml
new file mode 100644
index 000000000..dce1515c3
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "cons-list"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt
new file mode 100644
index 000000000..437d74b5c
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt
@@ -0,0 +1,27 @@
+$ cargo run
+ Compiling cons-list v0.1.0 (file:///projects/cons-list)
+error[E0072]: recursive type `List` has infinite size
+ --> src/main.rs:1:1
+ |
+1 | enum List {
+ | ^^^^^^^^^ recursive type has infinite size
+2 | Cons(i32, List),
+ | ---- recursive without indirection
+ |
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` representable
+ |
+2 | Cons(i32, Box<List>),
+ | ++++ +
+
+error[E0391]: cycle detected when computing drop-check constraints for `List`
+ --> src/main.rs:1:1
+ |
+1 | enum List {
+ | ^^^^^^^^^
+ |
+ = note: ...which immediately requires computing drop-check constraints for `List` again
+ = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, constness: NotConst }, value: List } }`
+
+Some errors have detailed explanations: E0072, E0391.
+For more information about an error, try `rustc --explain E0072`.
+error: could not compile `cons-list` due to 2 previous errors
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/src/main.rs
new file mode 100644
index 000000000..a96f3d7b1
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/src/main.rs
@@ -0,0 +1,12 @@
+enum List {
+ Cons(i32, List),
+ Nil,
+}
+
+// ANCHOR: here
+use crate::List::{Cons, Nil};
+
+fn main() {
+ let list = Cons(1, Cons(2, Cons(3, Nil)));
+}
+// ANCHOR_END: here
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.lock
new file mode 100644
index 000000000..a792c49aa
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "cons-list"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.toml
new file mode 100644
index 000000000..dce1515c3
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "cons-list"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-05/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/src/main.rs
new file mode 100644
index 000000000..22f7d8338
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-05/src/main.rs
@@ -0,0 +1,10 @@
+enum List {
+ Cons(i32, Box<List>),
+ Nil,
+}
+
+use crate::List::{Cons, Nil};
+
+fn main() {
+ let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.lock
new file mode 100644
index 000000000..4297c6733
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "deref-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.toml
new file mode 100644
index 000000000..67ec198f7
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "deref-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-06/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/src/main.rs
new file mode 100644
index 000000000..174b620cf
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-06/src/main.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let x = 5;
+ let y = &x;
+
+ assert_eq!(5, x);
+ assert_eq!(5, *y);
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.lock
new file mode 100644
index 000000000..4297c6733
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "deref-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.toml
new file mode 100644
index 000000000..67ec198f7
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "deref-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-07/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/src/main.rs
new file mode 100644
index 000000000..4933a416b
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-07/src/main.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let x = 5;
+ let y = Box::new(x);
+
+ assert_eq!(5, x);
+ assert_eq!(5, *y);
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.lock
new file mode 100644
index 000000000..4297c6733
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "deref-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.toml
new file mode 100644
index 000000000..67ec198f7
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "deref-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-08/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/src/main.rs
new file mode 100644
index 000000000..f48594673
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-08/src/main.rs
@@ -0,0 +1,11 @@
+// ANCHOR: here
+struct MyBox<T>(T);
+
+impl<T> MyBox<T> {
+ fn new(x: T) -> MyBox<T> {
+ MyBox(x)
+ }
+}
+// ANCHOR_END: here
+
+fn main() {}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.lock
new file mode 100644
index 000000000..4297c6733
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "deref-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.toml
new file mode 100644
index 000000000..67ec198f7
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "deref-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-09/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/output.txt
new file mode 100644
index 000000000..75e5f1c8c
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/output.txt
@@ -0,0 +1,10 @@
+$ cargo run
+ Compiling deref-example v0.1.0 (file:///projects/deref-example)
+error[E0614]: type `MyBox<{integer}>` cannot be dereferenced
+ --> src/main.rs:14:19
+ |
+14 | assert_eq!(5, *y);
+ | ^^
+
+For more information about this error, try `rustc --explain E0614`.
+error: could not compile `deref-example` due to previous error
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-09/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/src/main.rs
new file mode 100644
index 000000000..d07f2d78a
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-09/src/main.rs
@@ -0,0 +1,17 @@
+struct MyBox<T>(T);
+
+impl<T> MyBox<T> {
+ fn new(x: T) -> MyBox<T> {
+ MyBox(x)
+ }
+}
+
+// ANCHOR: here
+fn main() {
+ let x = 5;
+ let y = MyBox::new(x);
+
+ assert_eq!(5, x);
+ assert_eq!(5, *y);
+}
+// ANCHOR_END: here
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.lock
new file mode 100644
index 000000000..4297c6733
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "deref-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.toml
new file mode 100644
index 000000000..67ec198f7
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "deref-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-10/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/src/main.rs
new file mode 100644
index 000000000..cce754d08
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-10/src/main.rs
@@ -0,0 +1,27 @@
+// ANCHOR: here
+use std::ops::Deref;
+
+impl<T> Deref for MyBox<T> {
+ type Target = T;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+// ANCHOR_END: here
+
+struct MyBox<T>(T);
+
+impl<T> MyBox<T> {
+ fn new(x: T) -> MyBox<T> {
+ MyBox(x)
+ }
+}
+
+fn main() {
+ let x = 5;
+ let y = MyBox::new(x);
+
+ assert_eq!(5, x);
+ assert_eq!(5, *y);
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.lock
new file mode 100644
index 000000000..4297c6733
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "deref-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.toml
new file mode 100644
index 000000000..67ec198f7
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "deref-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-11/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/src/main.rs
new file mode 100644
index 000000000..77a88c91f
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-11/src/main.rs
@@ -0,0 +1,7 @@
+// ANCHOR: here
+fn hello(name: &str) {
+ println!("Hello, {name}!");
+}
+// ANCHOR_END: here
+
+fn main() {}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.lock
new file mode 100644
index 000000000..4297c6733
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "deref-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.toml
new file mode 100644
index 000000000..67ec198f7
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "deref-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-12/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/src/main.rs
new file mode 100644
index 000000000..8cd3893cb
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-12/src/main.rs
@@ -0,0 +1,28 @@
+use std::ops::Deref;
+
+impl<T> Deref for MyBox<T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &self.0
+ }
+}
+
+struct MyBox<T>(T);
+
+impl<T> MyBox<T> {
+ fn new(x: T) -> MyBox<T> {
+ MyBox(x)
+ }
+}
+
+fn hello(name: &str) {
+ println!("Hello, {name}!");
+}
+
+// ANCHOR: here
+fn main() {
+ let m = MyBox::new(String::from("Rust"));
+ hello(&m);
+}
+// ANCHOR_END: here
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.lock
new file mode 100644
index 000000000..4297c6733
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "deref-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.toml
new file mode 100644
index 000000000..67ec198f7
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "deref-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-13/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/src/main.rs
new file mode 100644
index 000000000..9debe2a31
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-13/src/main.rs
@@ -0,0 +1,28 @@
+use std::ops::Deref;
+
+impl<T> Deref for MyBox<T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &self.0
+ }
+}
+
+struct MyBox<T>(T);
+
+impl<T> MyBox<T> {
+ fn new(x: T) -> MyBox<T> {
+ MyBox(x)
+ }
+}
+
+fn hello(name: &str) {
+ println!("Hello, {name}!");
+}
+
+// ANCHOR: here
+fn main() {
+ let m = MyBox::new(String::from("Rust"));
+ hello(&(*m)[..]);
+}
+// ANCHOR_END: here
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.lock
new file mode 100644
index 000000000..eb8a2817a
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "drop-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.toml
new file mode 100644
index 000000000..1e4c99481
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "drop-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-14/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/output.txt
new file mode 100644
index 000000000..4e795949a
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/output.txt
@@ -0,0 +1,7 @@
+$ cargo run
+ Compiling drop-example v0.1.0 (file:///projects/drop-example)
+ Finished dev [unoptimized + debuginfo] target(s) in 0.60s
+ Running `target/debug/drop-example`
+CustomSmartPointers created.
+Dropping CustomSmartPointer with data `other stuff`!
+Dropping CustomSmartPointer with data `my stuff`!
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-14/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/src/main.rs
new file mode 100644
index 000000000..231612ae6
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-14/src/main.rs
@@ -0,0 +1,19 @@
+struct CustomSmartPointer {
+ data: String,
+}
+
+impl Drop for CustomSmartPointer {
+ fn drop(&mut self) {
+ println!("Dropping CustomSmartPointer with data `{}`!", self.data);
+ }
+}
+
+fn main() {
+ let c = CustomSmartPointer {
+ data: String::from("my stuff"),
+ };
+ let d = CustomSmartPointer {
+ data: String::from("other stuff"),
+ };
+ println!("CustomSmartPointers created.");
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.lock
new file mode 100644
index 000000000..eb8a2817a
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "drop-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.toml
new file mode 100644
index 000000000..1e4c99481
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "drop-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-15/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/output.txt
new file mode 100644
index 000000000..a38c9ccb7
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/output.txt
@@ -0,0 +1,13 @@
+$ cargo run
+ Compiling drop-example v0.1.0 (file:///projects/drop-example)
+error[E0040]: explicit use of destructor method
+ --> src/main.rs:16:7
+ |
+16 | c.drop();
+ | --^^^^--
+ | | |
+ | | explicit destructor calls not allowed
+ | help: consider using `drop` function: `drop(c)`
+
+For more information about this error, try `rustc --explain E0040`.
+error: could not compile `drop-example` due to previous error
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-15/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/src/main.rs
new file mode 100644
index 000000000..ff3b391a9
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-15/src/main.rs
@@ -0,0 +1,20 @@
+struct CustomSmartPointer {
+ data: String,
+}
+
+impl Drop for CustomSmartPointer {
+ fn drop(&mut self) {
+ println!("Dropping CustomSmartPointer with data `{}`!", self.data);
+ }
+}
+
+// ANCHOR: here
+fn main() {
+ let c = CustomSmartPointer {
+ data: String::from("some data"),
+ };
+ println!("CustomSmartPointer created.");
+ c.drop();
+ println!("CustomSmartPointer dropped before the end of main.");
+}
+// ANCHOR_END: here
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.lock
new file mode 100644
index 000000000..eb8a2817a
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "drop-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.toml
new file mode 100644
index 000000000..1e4c99481
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "drop-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-16/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/output.txt
new file mode 100644
index 000000000..e960cd89a
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/output.txt
@@ -0,0 +1,7 @@
+$ cargo run
+ Compiling drop-example v0.1.0 (file:///projects/drop-example)
+ Finished dev [unoptimized + debuginfo] target(s) in 0.73s
+ Running `target/debug/drop-example`
+CustomSmartPointer created.
+Dropping CustomSmartPointer with data `some data`!
+CustomSmartPointer dropped before the end of main.
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-16/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/src/main.rs
new file mode 100644
index 000000000..f11715c45
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-16/src/main.rs
@@ -0,0 +1,20 @@
+struct CustomSmartPointer {
+ data: String,
+}
+
+impl Drop for CustomSmartPointer {
+ fn drop(&mut self) {
+ println!("Dropping CustomSmartPointer with data `{}`!", self.data);
+ }
+}
+
+// ANCHOR: here
+fn main() {
+ let c = CustomSmartPointer {
+ data: String::from("some data"),
+ };
+ println!("CustomSmartPointer created.");
+ drop(c);
+ println!("CustomSmartPointer dropped before the end of main.");
+}
+// ANCHOR_END: here
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.lock
new file mode 100644
index 000000000..a792c49aa
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "cons-list"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.toml
new file mode 100644
index 000000000..dce1515c3
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "cons-list"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-17/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/output.txt
new file mode 100644
index 000000000..ab314d883
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/output.txt
@@ -0,0 +1,14 @@
+$ cargo run
+ Compiling cons-list v0.1.0 (file:///projects/cons-list)
+error[E0382]: use of moved value: `a`
+ --> src/main.rs:11:30
+ |
+9 | let a = Cons(5, Box::new(Cons(10, Box::new(Nil))));
+ | - move occurs because `a` has type `List`, which does not implement the `Copy` trait
+10 | let b = Cons(3, Box::new(a));
+ | - value moved here
+11 | let c = Cons(4, Box::new(a));
+ | ^ value used here after move
+
+For more information about this error, try `rustc --explain E0382`.
+error: could not compile `cons-list` due to previous error
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-17/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/src/main.rs
new file mode 100644
index 000000000..47c33e4c4
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-17/src/main.rs
@@ -0,0 +1,12 @@
+enum List {
+ Cons(i32, Box<List>),
+ Nil,
+}
+
+use crate::List::{Cons, Nil};
+
+fn main() {
+ let a = Cons(5, Box::new(Cons(10, Box::new(Nil))));
+ let b = Cons(3, Box::new(a));
+ let c = Cons(4, Box::new(a));
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.lock
new file mode 100644
index 000000000..a792c49aa
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "cons-list"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.toml
new file mode 100644
index 000000000..dce1515c3
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "cons-list"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-18/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/src/main.rs
new file mode 100644
index 000000000..602f7de40
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-18/src/main.rs
@@ -0,0 +1,13 @@
+enum List {
+ Cons(i32, Rc<List>),
+ Nil,
+}
+
+use crate::List::{Cons, Nil};
+use std::rc::Rc;
+
+fn main() {
+ let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
+ let b = Cons(3, Rc::clone(&a));
+ let c = Cons(4, Rc::clone(&a));
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.lock
new file mode 100644
index 000000000..a792c49aa
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "cons-list"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.toml
new file mode 100644
index 000000000..dce1515c3
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "cons-list"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-19/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/output.txt
new file mode 100644
index 000000000..6a8cc8efe
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/output.txt
@@ -0,0 +1,8 @@
+$ cargo run
+ Compiling cons-list v0.1.0 (file:///projects/cons-list)
+ Finished dev [unoptimized + debuginfo] target(s) in 0.45s
+ Running `target/debug/cons-list`
+count after creating a = 1
+count after creating b = 2
+count after creating c = 3
+count after c goes out of scope = 2
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-19/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/src/main.rs
new file mode 100644
index 000000000..1bd7bc533
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-19/src/main.rs
@@ -0,0 +1,21 @@
+enum List {
+ Cons(i32, Rc<List>),
+ Nil,
+}
+
+use crate::List::{Cons, Nil};
+use std::rc::Rc;
+
+// ANCHOR: here
+fn main() {
+ let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
+ println!("count after creating a = {}", Rc::strong_count(&a));
+ let b = Cons(3, Rc::clone(&a));
+ println!("count after creating b = {}", Rc::strong_count(&a));
+ {
+ let c = Cons(4, Rc::clone(&a));
+ println!("count after creating c = {}", Rc::strong_count(&a));
+ }
+ println!("count after c goes out of scope = {}", Rc::strong_count(&a));
+}
+// ANCHOR_END: here
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.lock
new file mode 100644
index 000000000..4dc2226a5
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "limit-tracker"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.toml
new file mode 100644
index 000000000..98c3f537c
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "limit-tracker"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-20/src/lib.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/src/lib.rs
new file mode 100644
index 000000000..a5181834c
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-20/src/lib.rs
@@ -0,0 +1,38 @@
+pub trait Messenger {
+ fn send(&self, msg: &str);
+}
+
+pub struct LimitTracker<'a, T: Messenger> {
+ messenger: &'a T,
+ value: usize,
+ max: usize,
+}
+
+impl<'a, T> LimitTracker<'a, T>
+where
+ T: Messenger,
+{
+ pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> {
+ LimitTracker {
+ messenger,
+ value: 0,
+ max,
+ }
+ }
+
+ pub fn set_value(&mut self, value: usize) {
+ self.value = value;
+
+ let percentage_of_max = self.value as f64 / self.max as f64;
+
+ if percentage_of_max >= 1.0 {
+ self.messenger.send("Error: You are over your quota!");
+ } else if percentage_of_max >= 0.9 {
+ self.messenger
+ .send("Urgent warning: You've used up over 90% of your quota!");
+ } else if percentage_of_max >= 0.75 {
+ self.messenger
+ .send("Warning: You've used up over 75% of your quota!");
+ }
+ }
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.lock
new file mode 100644
index 000000000..4dc2226a5
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "limit-tracker"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.toml
new file mode 100644
index 000000000..98c3f537c
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "limit-tracker"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-21/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/output.txt
new file mode 100644
index 000000000..6b07b66ea
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/output.txt
@@ -0,0 +1,14 @@
+$ cargo test
+ Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker)
+error[E0596]: cannot borrow `self.sent_messages` as mutable, as it is behind a `&` reference
+ --> src/lib.rs:58:13
+ |
+2 | fn send(&self, msg: &str);
+ | ----- help: consider changing that to be a mutable reference: `&mut self`
+...
+58 | self.sent_messages.push(String::from(message));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+For more information about this error, try `rustc --explain E0596`.
+error: could not compile `limit-tracker` due to previous error
+warning: build failed, waiting for other jobs to finish...
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-21/src/lib.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/src/lib.rs
new file mode 100644
index 000000000..4572d4313
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-21/src/lib.rs
@@ -0,0 +1,73 @@
+pub trait Messenger {
+ fn send(&self, msg: &str);
+}
+
+pub struct LimitTracker<'a, T: Messenger> {
+ messenger: &'a T,
+ value: usize,
+ max: usize,
+}
+
+impl<'a, T> LimitTracker<'a, T>
+where
+ T: Messenger,
+{
+ pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> {
+ LimitTracker {
+ messenger,
+ value: 0,
+ max,
+ }
+ }
+
+ pub fn set_value(&mut self, value: usize) {
+ self.value = value;
+
+ let percentage_of_max = self.value as f64 / self.max as f64;
+
+ if percentage_of_max >= 1.0 {
+ self.messenger.send("Error: You are over your quota!");
+ } else if percentage_of_max >= 0.9 {
+ self.messenger
+ .send("Urgent warning: You've used up over 90% of your quota!");
+ } else if percentage_of_max >= 0.75 {
+ self.messenger
+ .send("Warning: You've used up over 75% of your quota!");
+ }
+ }
+}
+
+// ANCHOR: here
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ struct MockMessenger {
+ sent_messages: Vec<String>,
+ }
+
+ impl MockMessenger {
+ fn new() -> MockMessenger {
+ MockMessenger {
+ sent_messages: vec![],
+ }
+ }
+ }
+
+ impl Messenger for MockMessenger {
+ fn send(&self, message: &str) {
+ self.sent_messages.push(String::from(message));
+ }
+ }
+
+ #[test]
+ fn it_sends_an_over_75_percent_warning_message() {
+ let mock_messenger = MockMessenger::new();
+ let mut limit_tracker = LimitTracker::new(&mock_messenger, 100);
+
+ limit_tracker.set_value(80);
+
+ assert_eq!(mock_messenger.sent_messages.len(), 1);
+ }
+}
+// ANCHOR_END: here
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.lock
new file mode 100644
index 000000000..4dc2226a5
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "limit-tracker"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.toml
new file mode 100644
index 000000000..98c3f537c
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "limit-tracker"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-22/src/lib.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/src/lib.rs
new file mode 100644
index 000000000..a77ffa41c
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-22/src/lib.rs
@@ -0,0 +1,78 @@
+pub trait Messenger {
+ fn send(&self, msg: &str);
+}
+
+pub struct LimitTracker<'a, T: Messenger> {
+ messenger: &'a T,
+ value: usize,
+ max: usize,
+}
+
+impl<'a, T> LimitTracker<'a, T>
+where
+ T: Messenger,
+{
+ pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> {
+ LimitTracker {
+ messenger,
+ value: 0,
+ max,
+ }
+ }
+
+ pub fn set_value(&mut self, value: usize) {
+ self.value = value;
+
+ let percentage_of_max = self.value as f64 / self.max as f64;
+
+ if percentage_of_max >= 1.0 {
+ self.messenger.send("Error: You are over your quota!");
+ } else if percentage_of_max >= 0.9 {
+ self.messenger
+ .send("Urgent warning: You've used up over 90% of your quota!");
+ } else if percentage_of_max >= 0.75 {
+ self.messenger
+ .send("Warning: You've used up over 75% of your quota!");
+ }
+ }
+}
+
+// ANCHOR: here
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::cell::RefCell;
+
+ struct MockMessenger {
+ sent_messages: RefCell<Vec<String>>,
+ }
+
+ impl MockMessenger {
+ fn new() -> MockMessenger {
+ MockMessenger {
+ sent_messages: RefCell::new(vec![]),
+ }
+ }
+ }
+
+ impl Messenger for MockMessenger {
+ fn send(&self, message: &str) {
+ self.sent_messages.borrow_mut().push(String::from(message));
+ }
+ }
+
+ #[test]
+ fn it_sends_an_over_75_percent_warning_message() {
+ // --snip--
+ // ANCHOR_END: here
+ let mock_messenger = MockMessenger::new();
+ let mut limit_tracker = LimitTracker::new(&mock_messenger, 100);
+
+ limit_tracker.set_value(80);
+ // ANCHOR: here
+
+ // ANCHOR: here
+ assert_eq!(mock_messenger.sent_messages.borrow().len(), 1);
+ }
+}
+// ANCHOR_END: here
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.lock
new file mode 100644
index 000000000..4dc2226a5
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "limit-tracker"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.toml
new file mode 100644
index 000000000..98c3f537c
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "limit-tracker"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt
new file mode 100644
index 000000000..c44e69f13
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt
@@ -0,0 +1,21 @@
+$ cargo test
+ Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker)
+ Finished test [unoptimized + debuginfo] target(s) in 0.91s
+ Running unittests src/lib.rs (target/debug/deps/limit_tracker-e599811fa246dbde)
+
+running 1 test
+test tests::it_sends_an_over_75_percent_warning_message ... FAILED
+
+failures:
+
+---- tests::it_sends_an_over_75_percent_warning_message stdout ----
+thread 'main' panicked at 'already borrowed: BorrowMutError', src/lib.rs:60:53
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+
+
+failures:
+ tests::it_sends_an_over_75_percent_warning_message
+
+test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
+
+error: test failed, to rerun pass '--lib'
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/src/lib.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/src/lib.rs
new file mode 100644
index 000000000..7d288e680
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/src/lib.rs
@@ -0,0 +1,78 @@
+pub trait Messenger {
+ fn send(&self, msg: &str);
+}
+
+pub struct LimitTracker<'a, T: Messenger> {
+ messenger: &'a T,
+ value: usize,
+ max: usize,
+}
+
+impl<'a, T> LimitTracker<'a, T>
+where
+ T: Messenger,
+{
+ pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> {
+ LimitTracker {
+ messenger,
+ value: 0,
+ max,
+ }
+ }
+
+ pub fn set_value(&mut self, value: usize) {
+ self.value = value;
+
+ let percentage_of_max = self.value as f64 / self.max as f64;
+
+ if percentage_of_max >= 1.0 {
+ self.messenger.send("Error: You are over your quota!");
+ } else if percentage_of_max >= 0.9 {
+ self.messenger
+ .send("Urgent warning: You've used up over 90% of your quota!");
+ } else if percentage_of_max >= 0.75 {
+ self.messenger
+ .send("Warning: You've used up over 75% of your quota!");
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::cell::RefCell;
+
+ struct MockMessenger {
+ sent_messages: RefCell<Vec<String>>,
+ }
+
+ impl MockMessenger {
+ fn new() -> MockMessenger {
+ MockMessenger {
+ sent_messages: RefCell::new(vec![]),
+ }
+ }
+ }
+
+ // ANCHOR: here
+ impl Messenger for MockMessenger {
+ fn send(&self, message: &str) {
+ let mut one_borrow = self.sent_messages.borrow_mut();
+ let mut two_borrow = self.sent_messages.borrow_mut();
+
+ one_borrow.push(String::from(message));
+ two_borrow.push(String::from(message));
+ }
+ }
+ // ANCHOR_END: here
+
+ #[test]
+ fn it_sends_an_over_75_percent_warning_message() {
+ let mock_messenger = MockMessenger::new();
+ let mut limit_tracker = LimitTracker::new(&mock_messenger, 100);
+
+ limit_tracker.set_value(80);
+
+ assert_eq!(mock_messenger.sent_messages.borrow().len(), 1);
+ }
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.lock
new file mode 100644
index 000000000..a792c49aa
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "cons-list"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.toml
new file mode 100644
index 000000000..dce1515c3
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "cons-list"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-24/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/output.txt
new file mode 100644
index 000000000..21b3530d9
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/output.txt
@@ -0,0 +1,7 @@
+$ cargo run
+ Compiling cons-list v0.1.0 (file:///projects/cons-list)
+ Finished dev [unoptimized + debuginfo] target(s) in 0.63s
+ Running `target/debug/cons-list`
+a after = Cons(RefCell { value: 15 }, Nil)
+b after = Cons(RefCell { value: 3 }, Cons(RefCell { value: 15 }, Nil))
+c after = Cons(RefCell { value: 4 }, Cons(RefCell { value: 15 }, Nil))
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-24/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/src/main.rs
new file mode 100644
index 000000000..e225bd862
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-24/src/main.rs
@@ -0,0 +1,24 @@
+#[derive(Debug)]
+enum List {
+ Cons(Rc<RefCell<i32>>, Rc<List>),
+ Nil,
+}
+
+use crate::List::{Cons, Nil};
+use std::cell::RefCell;
+use std::rc::Rc;
+
+fn main() {
+ let value = Rc::new(RefCell::new(5));
+
+ let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil)));
+
+ let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a));
+ let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a));
+
+ *value.borrow_mut() += 10;
+
+ println!("a after = {:?}", a);
+ println!("b after = {:?}", b);
+ println!("c after = {:?}", c);
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.lock
new file mode 100644
index 000000000..a792c49aa
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "cons-list"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.toml
new file mode 100644
index 000000000..dce1515c3
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "cons-list"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-25/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/src/main.rs
new file mode 100644
index 000000000..f36c7fd06
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-25/src/main.rs
@@ -0,0 +1,20 @@
+use crate::List::{Cons, Nil};
+use std::cell::RefCell;
+use std::rc::Rc;
+
+#[derive(Debug)]
+enum List {
+ Cons(i32, RefCell<Rc<List>>),
+ Nil,
+}
+
+impl List {
+ fn tail(&self) -> Option<&RefCell<Rc<List>>> {
+ match self {
+ Cons(_, item) => Some(item),
+ Nil => None,
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.lock
new file mode 100644
index 000000000..a792c49aa
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "cons-list"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.toml
new file mode 100644
index 000000000..dce1515c3
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "cons-list"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-26/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/output.txt
new file mode 100644
index 000000000..8b8eb40b6
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/output.txt
@@ -0,0 +1,11 @@
+$ cargo run
+ Compiling cons-list v0.1.0 (file:///projects/cons-list)
+ Finished dev [unoptimized + debuginfo] target(s) in 0.53s
+ Running `target/debug/cons-list`
+a initial rc count = 1
+a next item = Some(RefCell { value: Nil })
+a rc count after b creation = 2
+b initial rc count = 1
+b next item = Some(RefCell { value: Cons(5, RefCell { value: Nil }) })
+b rc count after changing a = 2
+a rc count after changing a = 2
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-26/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/src/main.rs
new file mode 100644
index 000000000..08963aaa5
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-26/src/main.rs
@@ -0,0 +1,44 @@
+use crate::List::{Cons, Nil};
+use std::cell::RefCell;
+use std::rc::Rc;
+
+#[derive(Debug)]
+enum List {
+ Cons(i32, RefCell<Rc<List>>),
+ Nil,
+}
+
+impl List {
+ fn tail(&self) -> Option<&RefCell<Rc<List>>> {
+ match self {
+ Cons(_, item) => Some(item),
+ Nil => None,
+ }
+ }
+}
+
+// ANCHOR: here
+fn main() {
+ let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));
+
+ println!("a initial rc count = {}", Rc::strong_count(&a));
+ println!("a next item = {:?}", a.tail());
+
+ let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a))));
+
+ println!("a rc count after b creation = {}", Rc::strong_count(&a));
+ println!("b initial rc count = {}", Rc::strong_count(&b));
+ println!("b next item = {:?}", b.tail());
+
+ if let Some(link) = a.tail() {
+ *link.borrow_mut() = Rc::clone(&b);
+ }
+
+ println!("b rc count after changing a = {}", Rc::strong_count(&b));
+ println!("a rc count after changing a = {}", Rc::strong_count(&a));
+
+ // Uncomment the next line to see that we have a cycle;
+ // it will overflow the stack
+ // println!("a next item = {:?}", a.tail());
+}
+// ANCHOR_END: here
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.lock
new file mode 100644
index 000000000..dd1f00a87
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "tree"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.toml
new file mode 100644
index 000000000..0bbf897d0
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "tree"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-27/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/src/main.rs
new file mode 100644
index 000000000..335d154dd
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-27/src/main.rs
@@ -0,0 +1,24 @@
+// ANCHOR: here
+use std::cell::RefCell;
+use std::rc::Rc;
+
+#[derive(Debug)]
+struct Node {
+ value: i32,
+ children: RefCell<Vec<Rc<Node>>>,
+}
+// ANCHOR_END: here
+
+// ANCHOR: there
+fn main() {
+ let leaf = Rc::new(Node {
+ value: 3,
+ children: RefCell::new(vec![]),
+ });
+
+ let branch = Rc::new(Node {
+ value: 5,
+ children: RefCell::new(vec![Rc::clone(&leaf)]),
+ });
+}
+// ANCHOR_END: there
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.lock
new file mode 100644
index 000000000..dd1f00a87
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "tree"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.toml
new file mode 100644
index 000000000..0bbf897d0
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "tree"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-28/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/src/main.rs
new file mode 100644
index 000000000..fabd1cbce
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-28/src/main.rs
@@ -0,0 +1,33 @@
+// ANCHOR: here
+use std::cell::RefCell;
+use std::rc::{Rc, Weak};
+
+#[derive(Debug)]
+struct Node {
+ value: i32,
+ parent: RefCell<Weak<Node>>,
+ children: RefCell<Vec<Rc<Node>>>,
+}
+// ANCHOR_END: here
+
+// ANCHOR: there
+fn main() {
+ let leaf = Rc::new(Node {
+ value: 3,
+ parent: RefCell::new(Weak::new()),
+ children: RefCell::new(vec![]),
+ });
+
+ println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
+
+ let branch = Rc::new(Node {
+ value: 5,
+ parent: RefCell::new(Weak::new()),
+ children: RefCell::new(vec![Rc::clone(&leaf)]),
+ });
+
+ *leaf.parent.borrow_mut() = Rc::downgrade(&branch);
+
+ println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
+}
+// ANCHOR_END: there
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.lock
new file mode 100644
index 000000000..dd1f00a87
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "tree"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.toml
new file mode 100644
index 000000000..0bbf897d0
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "tree"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-29/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/src/main.rs
new file mode 100644
index 000000000..ea13df0eb
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-29/src/main.rs
@@ -0,0 +1,54 @@
+use std::cell::RefCell;
+use std::rc::{Rc, Weak};
+
+#[derive(Debug)]
+struct Node {
+ value: i32,
+ parent: RefCell<Weak<Node>>,
+ children: RefCell<Vec<Rc<Node>>>,
+}
+
+// ANCHOR: here
+fn main() {
+ let leaf = Rc::new(Node {
+ value: 3,
+ parent: RefCell::new(Weak::new()),
+ children: RefCell::new(vec![]),
+ });
+
+ println!(
+ "leaf strong = {}, weak = {}",
+ Rc::strong_count(&leaf),
+ Rc::weak_count(&leaf),
+ );
+
+ {
+ let branch = Rc::new(Node {
+ value: 5,
+ parent: RefCell::new(Weak::new()),
+ children: RefCell::new(vec![Rc::clone(&leaf)]),
+ });
+
+ *leaf.parent.borrow_mut() = Rc::downgrade(&branch);
+
+ println!(
+ "branch strong = {}, weak = {}",
+ Rc::strong_count(&branch),
+ Rc::weak_count(&branch),
+ );
+
+ println!(
+ "leaf strong = {}, weak = {}",
+ Rc::strong_count(&leaf),
+ Rc::weak_count(&leaf),
+ );
+ }
+
+ println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
+ println!(
+ "leaf strong = {}, weak = {}",
+ Rc::strong_count(&leaf),
+ Rc::weak_count(&leaf),
+ );
+}
+// ANCHOR_END: here
diff --git a/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock
new file mode 100644
index 000000000..340f6604a
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "borrowing"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml
new file mode 100644
index 000000000..16f92447f
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "borrowing"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt
new file mode 100644
index 000000000..8e84746ee
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt
@@ -0,0 +1,12 @@
+$ cargo run
+ Compiling borrowing v0.1.0 (file:///projects/borrowing)
+error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
+ --> src/main.rs:3:13
+ |
+2 | let x = 5;
+ | - help: consider changing this to be mutable: `mut x`
+3 | let y = &mut x;
+ | ^^^^^^ cannot borrow as mutable
+
+For more information about this error, try `rustc --explain E0596`.
+error: could not compile `borrowing` due to previous error
diff --git a/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs
new file mode 100644
index 000000000..8f48d41c1
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let x = 5;
+ let y = &mut x;
+}
diff --git a/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock
new file mode 100644
index 000000000..4297c6733
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "deref-example"
+version = "0.1.0"
+
diff --git a/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml
new file mode 100644
index 000000000..67ec198f7
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "deref-example"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt
new file mode 100644
index 000000000..a03cc34e2
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt
@@ -0,0 +1,23 @@
+$ cargo run
+ Compiling deref-example v0.1.0 (file:///projects/deref-example)
+error[E0277]: can't compare `{integer}` with `&{integer}`
+ --> src/main.rs:6:5
+ |
+6 | assert_eq!(5, y);
+ | ^^^^^^^^^^^^^^^^ no implementation for `{integer} == &{integer}`
+ |
+ = help: the trait `PartialEq<&{integer}>` is not implemented for `{integer}`
+ = help: the following other types implement trait `PartialEq<Rhs>`:
+ f32
+ f64
+ i128
+ i16
+ i32
+ i64
+ i8
+ isize
+ and 6 others
+ = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+For more information about this error, try `rustc --explain E0277`.
+error: could not compile `deref-example` due to previous error
diff --git a/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/src/main.rs b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/src/main.rs
new file mode 100644
index 000000000..4e20cae0b
--- /dev/null
+++ b/src/doc/book/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/src/main.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let x = 5;
+ let y = &x;
+
+ assert_eq!(5, x);
+ assert_eq!(5, y);
+}