>];
+
+
+ edge[tailclip="false"];
+ table0:pointer2:c -> table4:pointee2;
+ table3:pointer:c -> table4:pointee;
+}
+
diff --git a/listings/ch04-understanding-ownership/no-listing-04b-replacement-drop/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-04b-replacement-drop/Cargo.lock
new file mode 100644
index 0000000000..2aa4918e5d
--- /dev/null
+++ b/listings/ch04-understanding-ownership/no-listing-04b-replacement-drop/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "ownership"
+version = "0.1.0"
+
diff --git a/listings/ch04-understanding-ownership/no-listing-04b-replacement-drop/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-04b-replacement-drop/Cargo.toml
new file mode 100644
index 0000000000..e8847526dc
--- /dev/null
+++ b/listings/ch04-understanding-ownership/no-listing-04b-replacement-drop/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "ownership"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/listings/ch04-understanding-ownership/no-listing-04b-replacement-drop/src/main.rs b/listings/ch04-understanding-ownership/no-listing-04b-replacement-drop/src/main.rs
new file mode 100644
index 0000000000..b2d0846c11
--- /dev/null
+++ b/listings/ch04-understanding-ownership/no-listing-04b-replacement-drop/src/main.rs
@@ -0,0 +1,8 @@
+fn main() {
+ // ANCHOR: here
+ let mut s = String::from("hello");
+ s = String::from("ahoy");
+
+ println!("{s}, world!");
+ // ANCHOR_END: here
+}
diff --git a/src/ch04-01-what-is-ownership.md b/src/ch04-01-what-is-ownership.md
index b8f14fd49e..5ef7b5f97f 100644
--- a/src/ch04-01-what-is-ownership.md
+++ b/src/ch04-01-what-is-ownership.md
@@ -356,6 +356,37 @@ In addition, there’s a design choice that’s implied by this: Rust will never
automatically create “deep” copies of your data. Therefore, any *automatic*
copying can be assumed to be inexpensive in terms of runtime performance.
+#### Scope and Assignment
+
+The inverse of this is true for the relationship between scoping, ownership, and
+memory being freed via the `drop` function as well. When you assign a completely
+new value to an existing variable, Rust will call `drop` and free the original
+value’s memory immediately. Consider this code, for example:
+
+```rust
+{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-04b-replacement-drop/src/main.rs:here}}
+```
+
+We initially declare a variable `s` and bind it to a `String` with the value
+`"hello"`. Then we immediately create a new `String` with the value `"ahoy"` and
+assign it to `s`. At this point, nothing is referring to the original value on
+the heap at all.
+
+
+
+Figure 4-5: Representation in memory after the initial
+value has been replaced in its entirety.
+
+The original string thus immediately goes out of scope. Rust will run the `drop`
+function on it and its memory will be freed right away. When we print the value
+at the end, it will be `"ahoy, world!"`.
+
diff --git a/src/ch04-02-references-and-borrowing.md b/src/ch04-02-references-and-borrowing.md
index 04dd601c7d..055001571a 100644
--- a/src/ch04-02-references-and-borrowing.md
+++ b/src/ch04-02-references-and-borrowing.md
@@ -24,13 +24,13 @@ First, notice that all the tuple code in the variable declaration and the
function return value is gone. Second, note that we pass `&s1` into
`calculate_length` and, in its definition, we take `&String` rather than
`String`. These ampersands represent *references*, and they allow you to refer
-to some value without taking ownership of it. Figure 4-5 depicts this concept.
+to some value without taking ownership of it. Figure 4-6 depicts this concept.
+string data on the heap." src="img/trpl04-06.svg" class="center" />
-Figure 4-5: A diagram of `&String s` pointing at `String
+Figure 4-6: A diagram of `&String s` pointing at `String
s1`
> Note: The opposite of referencing by using `&` is *dereferencing*, which is
diff --git a/src/ch04-03-slices.md b/src/ch04-03-slices.md
index 69fb35f82d..d01d905021 100644
--- a/src/ch04-03-slices.md
+++ b/src/ch04-03-slices.md
@@ -119,15 +119,15 @@ corresponds to `ending_index` minus `starting_index`. So, in the case of `let
world = &s[6..11];`, `world` would be a slice that contains a pointer to the
byte at index 6 of `s` with a length value of `5`.
-Figure 4-6 shows this in a diagram.
+Figure 4-7 shows this in a diagram.
+src="img/trpl04-07.svg" class="center" style="width: 50%;" />
-Figure 4-6: String slice referring to part of a
+Figure 4-7: String slice referring to part of a
`String`
With Rust’s `..` range syntax, if you want to start at index 0, you can drop
diff --git a/src/img/trpl04-05.svg b/src/img/trpl04-05.svg
index b4bf2ebee8..f3c6e8a82b 100644
--- a/src/img/trpl04-05.svg
+++ b/src/img/trpl04-05.svg
@@ -1,87 +1,95 @@
-
-
+
diff --git a/src/img/trpl04-06.svg b/src/img/trpl04-06.svg
index e64415fe43..b4bf2ebee8 100644
--- a/src/img/trpl04-06.svg
+++ b/src/img/trpl04-06.svg
@@ -5,111 +5,83 @@
-->
diff --git a/src/img/trpl04-07.svg b/src/img/trpl04-07.svg
new file mode 100644
index 0000000000..e64415fe43
--- /dev/null
+++ b/src/img/trpl04-07.svg
@@ -0,0 +1,115 @@
+
+
+
+
+