← Scrolls rust

Your data is not where you think it is

The two places Rust stores values - and why knowing them matters

Your data is not where you think it is

You have declared a variable before. You gave it a name, assigned a value, used it. Where it actually lived - on what surface, in what part of memory - was not your concern. Most languages do not ask you to care.

Rust does not ask you to manage it either. But it expects you to know the room.

The desk and the corkboard

You are sitting at a desk. The surface in front of you is limited - room for a handful of things. Their sizes are known in advance: a book, a pen (they will stay that size the whole time). When this space is no longer needed, you sweep everything off at once. You do not remove things one by one.

Behind you, a large corkboard is mounted to the wall. It has far more space than the desk. What is pinned there is made up of parts: a set of keys, a collection of medals. You can add or remove a key or medal whenever needed. For each such item, you have a small slip on the desk (keys - bottom right corner, medals - center). What the slip points to can be any size. And when you remove that slip from the desk, you need to take down what it points to from the board as well. It is not one motion - you must unpin it separately.

The desk is the stack. The corkboard is the heap.

The model that almost works

The working model: a variable holds a value. count holds 5. name holds "Alice". That model is correct as far as it goes - and it carries you through most of what you write.

It breaks when types start behaving differently from each other. Why does assigning an integer to another variable leave the original intact, while assigning a String moves it? Why does one copy freely and the other does not?

The answer is not in the type system. It is on the desk.

On the desk, on the board

let id: u32 = 1;                          // four bytes, on the desk
let title = String::from("Buy coffee");   // slip on the desk - text pinned to the board

id sits directly on the desk. Four bytes, size known before the program runs. When this scope ends, it clears with everything else. Copying it means writing the same four bytes onto another slip - trivial. Rust does it automatically.

title is not what it looks like. The text "Buy coffee" lives on the corkboard - allocated there (pinned, in the metaphor) because a String can grow, and its final size is not known at compile time. What sits on the desk is a small slip with three things on it: where on the board the text is pinned, how many bytes are currently in use, and how many the slot can hold before it needs a larger one.

Copying title would cost too much - it would mean duplicating the pin and the text itself. Rust doesn’t hide that cost. When you assign title to a new variable, you simply hand over the slip - only the small piece of paper moves, not what is pinned to the board. The slip is gone. Rust will not let you use the original anymore.

The value is not where the variable is.

When title goes out of scope, Rust removes the pin from the board and reclaims the slot. No action required - because title was the one holding the slip, and it is now gone.

Now it clicks

Most of the time you will not think about this. String, Vec, Box - values that live on the board - behave naturally. Rust handles the pins.

Now the move makes sense. To pass it on is to pass on that responsibility. There was nothing to copy.

But one scroll from now, you will meet the borrow checker. It will talk about references that cannot outlive what they point to, and about conflicting access to the same location. The corkboard it is guarding is the same one behind your desk. The pins it is tracking are the ones you just learned about.

When the error messages come, they will point to places that now make sense.


One thing worth knowing: there are more than two places. String literals - before they become a String - live in static memory, baked into the compiled binary. The program’s executable code lives there too. Neither changes at runtime, and neither is something Rust asks you to manage. For understanding ownership and the borrow checker, the desk and the corkboard are the map you need.