Rust terminology

From bibbleWiki
Jump to navigation Jump to search

Introduction

Just a page to remind myself of

Rust Terminology Cheat Sheet

Term Meaning Example Notes
Move Transfer ownership of a value let b = a;a is moved into b After move, a is invalid unless Copy
Copy Duplicate value without invalidating original let y = x; where x: u32 Only types that implement Copy (e.g. primitives)
Borrow Create a reference to a value let r = &x; or let r = &mut x; No ownership transfer; enforces lifetimes
Replace Swap a value behind a reference std::mem::replace(&mut x, new_val) Moves out old value, inserts new one
Take Replace with default, return old value std::mem::take(&mut x) Requires Default trait
Drop Explicitly destroy a value drop(x) Frees resources early
Pin Prevent a value from being moved let pinned = Box::pin(my_val) Needed for self-referential types, Future, etc.
Unpin Marker trait: safe to move even if pinned Most types are Unpin by default Opt out with impl !Unpin for T {}
Destructure Break a value into its components let (a, b) = tuple; or let Struct { x, y } = s; Can trigger moves if fields aren’t Copy
Ownership Who is responsible for freeing a value let x = String::from("hi"); Ownership moves unless borrowed
Smart Pointer Wrapper that manages ownership/lifetime Box<T>, Rc<T>, Arc<T>, RefCell<T> Each has different semantics
Interior Mutability Mutate through shared reference RefCell<T>, Mutex<T> Enables mutation behind &
Self-referential Struct with internal pointers to its own fields struct S { buf: Vec<u8>, ptr: *const u8 } Needs Pin to be safe
Map in place Transform a value behind a mutable reference Unsafe: ptr::read + ptr::write combo Can cause double-drop on panic

Example: Replace vs Move

struct T { s: String }

fn main() {
    let mut t = T { s: "hello".to_string() };

    // ❌ Can't move out of `t.s` directly
    // let new_t = T { s: t.s + " world" };

    // ✅ Use replace
    let old = std::mem::replace(&mut t, T { s: String::new() });
    t.s = old.s + " world";
}

🧠 Note on "Nottoe"

If "Nottoe" refers to "not to move" or a shorthand for immovable types, it may relate to:

  • !Unpin types
  • Drop-guarded values
  • Pin<&mut T> where movement is forbidden

Let me know if you'd like to expand this glossary with macro patterns or visual memory layout diagrams.

📌 Idiomatic Pin Usage Patterns

Pinning is essential when working with self-referential types, async state machines, or anything requiring memory stability. This page outlines safe patterns, macro ergonomics, and common pitfalls.

🔒 Why Use Pin?

  • Prevents movement of values after initialization
  • Guarantees memory address stability
  • Required for types that hold internal references or rely on layout

✅ Safe Pin Construction

// Heap-allocate and pin
let pinned = Box::pin(MyType::new());
  • Use Box::pin for heap allocation
  • Avoid Pin::new unless you control the lifetime and layout

🧰 Accessing Fields Safely

Use Pin::as_mut and Pin::map to access fields without moving:

impl MyType {
    fn poll_self(mut self: Pin<&mut Self>) {
        let field = self.as_mut().map(|s| &mut s.field);
        // Use field safely
    }
}

⚠️ Avoiding Moves

Never do this:

// ❌ Moves out of pinned value
let inner = *pinned;

Instead, use references or safe projections.

🧠 Macro Ergonomics for Pin

Define macros to reduce boilerplate and enforce pin-safe access:

macro_rules! pin_project {
    ($self:ident => $field:ident) => {
        $self.as_mut().map(|s| &mut s.$field)
    };
}

Usage:

fn poll(mut self: Pin<&mut Self>) {
    let buf = pin_project!(self => buffer);
    // Use buf safely
}

🧪 Example: Self-Referential Future

<syntaxhighlight lang="rust"> struct MyFuture {

   buffer: Vec<u8>,
   ptr: *const u8, // points into buffer

}

impl Future for MyFuture {

   type Output = ();
   fn poll(mut self: Pin<&mut Self>, _: &mut Context