RustViz Web - Learning Rust Ownership & Borrowing

Welcome! This interactive tool visualizes Rust's ownership, borrowing, and copying concepts as animated SVG timelines.

Topics Covered

  1. Variables & Mutability – Understand let (immutable) vs let mut (mutable)
  2. Copy – Learn which types copy instead of move (scalar types like integers)
  3. Ownership – See how values are moved between variables and functions
  4. Borrowing – Explore immutable references (&T) and mutable references (&mut T)

How to Use These Examples

  1. Select a topic from the left sidebar (organized from basics to advanced)
  2. Read the Rust source in the diagram on each page (the same code appears inside the visualization)
  3. Hover over the timeline to understand:
    • Dots – Events (variable declarations, moves, borrows)
    • Vertical lines – Variable lifetimes
    • Arrows – Ownership transfers and references

Try the Playground

Use the Playground (last item in the sidebar) to write Rust beside a live ownership & timeline diagram. Experiment with different patterns to build intuition!

Learning Path

Start from the top of the sidebar and work your way down:

  • Begin with Immutable Variables and Mutable Variables
  • Then explore Stack-Only Data: Copy to understand what makes types copyable
  • Move on to Ownership examples (moves and functions)
  • Finally, study References and Borrowing

Project forked from rustviz/rustviz

Immutable Variables

Overview

Rust variables are immutable by default. Once a value is bound to a name, reassigning it is not allowed unless the binding is marked mutable with mut.

This default helps prevent accidental state changes and makes code easier to reason about, because the compiler enforces when values can and cannot change.

Official Rust Book: Variables and Mutability


Code example

Mutable Variables

Overview

When you need to update a value, Rust requires an explicit mutable binding with let mut. This makes mutation intentional and visible to readers of the code.

Rust keeps immutability as the default, while mut is the opt-in mechanism for state changes.

Official Rust Book: Variables and Mutability


Code example

Stack-Only Data: Copy

Overview

Some stack-only types (such as integers) implement the Copy trait. Assigning them duplicates the value, so both variables remain valid after assignment.

Because no heap allocation ownership is transferred, this operation is cheap and does not trigger move semantics.

Official Rust Book: Stack-Only Data: Copy


Code example

Move Semantics: Assignment

Overview

For heap-owning values like String, assignment moves ownership instead of copying heap data. After let s2 = s1;, s1 is no longer valid.

This prevents double-free bugs by ensuring only one owner is responsible for dropping the value.

Official Rust Book: Variables and Data Interacting with Move


Code example

Move Semantics: Different Scope

Overview

Ownership is always tied to scope. When a value is moved, the previous binding becomes invalid, and cleanup happens when the current owner goes out of scope.

This rule is especially important across nested scopes, where validity and drops depend on who owns the value at each point.

Official Rust Book: Variables and Data Interacting with Move


Code example

Move Semantics: Function Return

Overview

Returning a value transfers ownership to the caller. Function boundaries follow the same move rules as assignment.

This means ownership can flow out of one scope and into another through return values, controlling exactly where data remains valid.

Official Rust Book: Return Values and Scope


Code example

Ownership: Function Parameters

Overview

Passing a value into a function transfers ownership when the parameter takes the value by type (for example, String rather than &String).

After that call, the original binding is no longer valid unless ownership is returned in some form.

Official Rust Book: Ownership and Functions


Code example

Ownership: Take and Return

Overview

Functions can take ownership of values and then return ownership back to the caller. This follows the same ownership transfer rules as assignment and returns.

While valid, this pattern is often verbose and motivates borrowing when you only need temporary access.

Official Rust Book: Ownership and Functions and Return Values and Scope


Code example

String Ownership and Move

Overview

String owns heap data, so assigning or passing it by value moves ownership unless you explicitly borrow or clone.

Understanding this move behavior explains why some bindings become invalid after transfer and why Rust prevents later use.

Official Rust Book: Variables and Data Interacting with Move


Code example

Immutable References

Overview

A reference (&T) lets you borrow a value without taking ownership. Borrowing allows functions to read data while the original owner keeps control.

Because ownership does not move, the borrowed value remains usable after the call.

Official Rust Book: References and Borrowing


Code example

Mutable References

Overview

A mutable reference (&mut T) allows mutation through a borrow, but Rust enforces exclusivity: at a given time, either one mutable reference or any number of immutable references.

These rules prevent data races and aliasing bugs at compile time.

Official Rust Book: Mutable References


Code example

Multiple Immutable Borrows

Overview

Rust allows multiple immutable references to the same value at the same time, because read-only access does not create conflicting mutations.

This enables safe shared access while still enforcing strict rules around mutation.

Official Rust Book: References and Borrowing


Code example

Method Calls: Immutable Borrow

Overview

Methods commonly take &self, which means calling the method immutably borrows the receiver instead of moving it.

This allows read-only behavior on a value while keeping ownership with the caller.

Official Rust Book: Method Syntax


Code example

Method Calls: Mutable Borrow

Overview

Methods that take &mut self borrow the receiver mutably, allowing the method to change internal state without taking ownership.

Rust's method-call syntax automatically handles the needed referencing while preserving borrowing rules.

Official Rust Book: Method Syntax


Code example

Playground

Write Rust in the editor — the ownership and timeline on the right update shortly after you stop typing (or at most every second or so while you keep typing). Compile runs the code through the Rust compiler. Hover diagram dots, arrows, and labels for explanations. Line height matches the diagram so rows stay aligned when you scroll.

Editor
Ownership & timeline