manutej/luxor-claude-marketplace3 files

Rust Systems Programming

Complete guide for Rust systems programming including ownership, borrowing, concurrency, async programming, unsafe code, and performance optimization

Specification
Skill ID
manutej/luxor-claude-marketplace/rust-systems-programming
Publisher
manutej
Repository
luxor-claude-marketplace
Installs
0
Files
3
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

manutej/luxor-claude-marketplace/rust-systems-programmingInstalls these files
  • EXAMPLES.md
  • README.md
  • SKILL.md

What this skill tells the agent

Rust Systems Programming

A comprehensive skill for building high-performance, memory-safe systems software using Rust. This skill covers ownership, borrowing, concurrency, async programming, unsafe code, FFI, and performance optimization for systems-level development.

When to Use This Skill

Use this skill when:

  • Building systems software requiring memory safety without garbage collection
  • Developing high-performance applications with zero-cost abstractions
  • Writing concurrent or parallel programs with data race prevention
  • Creating async/await applications for I/O-bound workloads (web servers, databases)
  • Working with low-level code, FFI, or hardware interfaces
  • Replacing C/C++ code with safer alternatives
  • Building command-line tools, network services, or embedded systems
  • Optimizing performance-critical sections of applications
  • Creating libraries that guarantee memory safety at compile time
  • Developing WebAssembly modules for near-native performance

Core Concepts

The Ownership Model

Rust's ownership system is the foundation of its memory safety guarantees:

Ownership Rules:

  1. Each value in Rust has exactly one owner
  2. When the owner goes out of scope, the value is dropped
  3. Ownership can be transferred (moved) to new owners

Move Semantics:

struct MyStruct { s: u32 }

fn main() {
    let mut x = MyStruct{ s: 5u32 };
    let y = x;  // Ownership moved from x to y
    // x.s = 6;  // ERROR: x is no longer valid
    // println!("{}", x.s);  // ERROR: cannot use x after move
}

When a type doesn't implement Copy, assignment moves ownership rather than copying. This prevents double-free errors and use-after-move bugs at compile time.

For Copy Types:

let x = 5;  // i32 implements Copy
let y = x;  // x is copied, not moved
println!("{}", x);  // OK: x is still valid

Borrowing and References

Borrowing allows temporary access to data without taking ownership:

Immutable Borrowing:

fn main() {
    let s1 = String::from("hello");

    let len = calculate_length(&s1);  // Borrow s1 immutably

    println!("The length of '{}' is {}.", s1, len);  // s1 still valid
}

fn calculate_length(s: &String) -> usize {
    s.len()  // Can read but not modify
}

Mutable Borrowing:

Rust enforces exclusive mutable access to prevent data races:

fn main() {
    let mut value = 3;
    let borrow = &mut value;  // Mutable borrow
    *borrow += 1;
    println!("{}", borrow);  // 4

    // value is accessible again after borrow ends
}

Borrowing Rules:

  • You can have either one mutable reference OR any number of immutable references
  • References must always be valid (no dangling pointers)
  • Mutable and immutable borrows cannot coexist

Common Borrowing Error:

fn main() {
    let mut value = 3;
    // Create a mutable borrow of `value`.
    let borrow = &mut value;
    let _sum = value + 1; // ERROR: cannot use `value` because
                          //        it was mutably borrowed
    println!("{}", borrow);
}

Lifetimes

Lifetimes ensure references are always valid:

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

The 'a lifetime parameter tells the compiler that the returned reference will be valid as long as both input references are valid.

Ownership Patterns for Sharing

Rc (Reference Counted) for Single-threaded Shared Ownership:

use std::cell::RefCell;
use std::rc::Rc;

struct MyStruct { s: u32 }

fn main() {
    let mut x = Rc::new(RefCell::new(MyStruct{ s: 5u32 }));
    let y = x.clone();  // Increment reference count
    x.borrow_mut().s = 6;  // Interior mutability via RefCell
    println!("{}", x.borrow().s);
}

Rc<T> provides shared ownership with reference counting. RefCell<T> enables interior mutability, enforcing borrow rules at runtime rather than compile time.

Arc (Atomic Reference Counted) for Thread-safe Sharing:

use std::sync::Arc;
use std::thread;

struct FancyNum {
    num: u8,
}

fn main() {
    let fancy_ref1 = Arc::new(FancyNum { num: 5 });
    let fancy_ref2 = fancy_ref1.clone();

    let x = thread::spawn(move || {
        // `fancy_ref1` can be moved and has a `'static` lifetime
        println!("child thread: {}", fancy_ref1.num);
    });

    x.join().expect("child thread should finish");
    println!("main thread: {}", fancy_ref2.num);
}

Arc<T> is the thread-safe version of Rc<T>, using atomic operations for reference counting.

Box for Heap Allocation

Box<T>

Box<T> is an owning pointer that allocates T on the heap. Useful for:

  • Recursive types with known size
  • Large values that should not be copied on the stack
  • Trait objects with dynamic dispatch

Concurrency Patterns

Threads and Message Passing

Rust prevents data races at compile time through its ownership system:

use std::thread;
use std::sync::mpsc;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        tx.send("Hello from thread").unwrap();
    });

    let message = rx.recv().unwrap();
    println!("{}", message);
}

Shared State with Mutex

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}

Key Concurrency Types:

  • Mutex<T>: Mutual exclusion lock for shared mutable state
  • RwLock<T>: Reader-writer lock allowing multiple readers or one writer
  • Arc<T>: Atomic reference counting for thread-safe sharing
  • mpsc: Multi-producer, single-consumer channels

Data Race Prevention

ThreadSanitizer Example:

static mut A: usize = 0;

fn main() {
    let t = std::thread::spawn(|| {
        unsafe { A += 1 };
    });
    unsafe { A += 1 };

    t.join().unwrap();
}

This code has a data race. ThreadSanitizer (enabled with RUSTFLAGS=-Zsanitizer=thread) detects concurrent access to static mutable data:

WARNING: ThreadSanitizer: data race (pid=10574)
  Read of size 8 at 0x5632dfe3d030 by thread T1:
  Previous write of size 8 at 0x5632dfe3d030 by main thread:

Async Programming

Async/Await Basics

Async programming in Rust allows concurrent I/O without blocking threads:

async fn foo(n: usize) {
    if n > 0 {
        Box::pin(foo(n - 1)).await;
    }
}

Recursive async functions require Box::pin() to give the future a known size.

Async Closures

Async Closure with Move Semantics:

fn force_fnonce<T: async FnOnce()>(t: T) -> T { t }

let x = String::new();
let c = force_fnonce(async move || {
    println!("{x}");
});

When constrained to AsyncFnOnce, the closure captures by move to ensure proper ownership.

Async Closure Borrowing:

let x = &1i32; // Lifetime '1
let c = async move || {
    println!("{:?}", *x);
    // Even though the closure moves x, we're only capturing *x,
    // so the inner coroutine can reborrow the data for its original lifetime.
};

Mutable Borrowing in Async Closures:

let mut x = 1i32;
let c = async || {
    x = 1;
    // The parent borrows `x` mutably.
    // When we call `c()`, we implicitly autoref for `AsyncFnMut::async_call_mut`.
    // The inner coroutine captures with the lifetime of the coroutine-closure.
};

Common Async Errors

E0373: Async block capturing short-lived variable:

use std::future::Future;

async fn f() {
    let v = vec![1, 2, 3i32];
    spawn(async { //~ ERROR E0373

Use this skill in a project

Open any RiverX project, search the Skills panel for manutej/luxor-claude-marketplace/rust-systems-programming, and install it in one click.

Use this skill