Skip to content

Commit 62b3b40

Browse files
committed
Clarified move semantics in "the details" section.
1 parent 32d962d commit 62b3b40

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

src/doc/book/ownership.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,19 +124,39 @@ special annotation here, it’s the default thing that Rust does.
124124
The reason that we cannot use a binding after we’ve moved it is subtle, but
125125
important. When we write code like this:
126126

127+
```rust
128+
let x = 10;
129+
```
130+
131+
Rust allocates memory for an integer [i32] on the [stack][sh], copies the bit
132+
pattern representing the value of 10 to the allocated memory and binds the
133+
variable name x to this memory region for future reference.
134+
135+
Now consider the following code fragment:
136+
127137
```rust
128138
let v = vec![1, 2, 3];
129139

130140
let v2 = v;
131141
```
132142

133-
The first line allocates memory for the vector object, `v`, and for the data it
134-
contains. The vector object is stored on the [stack][sh] and contains a pointer
135-
to the content (`[1, 2, 3]`) stored on the [heap][sh]. When we move `v` to `v2`,
136-
it creates a copy of that pointer, for `v2`. Which means that there would be two
137-
pointers to the content of the vector on the heap. It would violate Rust’s
138-
safety guarantees by introducing a data race. Therefore, Rust forbids using `v`
139-
after we’ve done the move.
143+
The first line allocates memory for the vector object, `v`, on the stack like
144+
it does for `x` above. But in addition to that it also allocates some memory
145+
on on the [heap][sh] for the actual data `[1, 2, 3]`. Rust copies the address
146+
of this heap allocation to an internal pointer part of the vector object
147+
placed on the stack (let's call it the data pointer). It is worth pointing out
148+
even at the risk of being redundant that the vector object and its data live
149+
in separate memory regions instead of being a single contiguous memory
150+
allocation (due to reasons we will not go into at this point of time).
151+
152+
When we move `v` to `v2`, rust actually does a bitwise copy of the vector
153+
object `v` into the stack allocation represented by `v2`. This shallow copy
154+
does not create a copy of the heap allocation containing the actual data.
155+
Which means that there would be two pointers to the contents of the vector
156+
both pointing to the same memory allocation on the heap. It would violate
157+
Rust’s safety guarantees by introducing a data race if one could access both
158+
`v` and `v2` at the same time. Therefore, Rust forbids using `v` after we’ve
159+
done the move (shallow copy).
140160

141161
[sh]: the-stack-and-the-heap.html
142162

0 commit comments

Comments
 (0)