Send, Sync, Variance, and Covariance


title: “NonNull Send, Sync, and Variance in Rust” meta_description: “Understanding how NonNull affects Send, Sync, variance, and covariance in Rust’s type system.” keywords: [“rust variance”, “covariance”, “send sync nonnull”, “type system rust”]

🔄 Reinventing from Scratch: NonNull<T>

Chapter 8 — “Send, Sync, Variance, and Covariance”

“NonNull is covariant in T — and that’s exactly what you want.”


🧭 8.1. Send and Sync

NonNull<T> implements Send and Sync based on T:

// If T: Send, then NonNull<T>: Send
// If T: Sync, then NonNull<T>: Sync

Example: Thread Safety

let ptr: NonNull<i32> = ...;

// i32: Send + Sync
// Therefore: NonNull<i32>: Send + Sync

std::thread::spawn(move || {
    // Can move NonNull<i32> between threads
    let ptr = ptr;
});

But:

use std::rc::Rc;

let ptr: NonNull<Rc<i32>> = ...;

// Rc is !Send !Sync
// Therefore: NonNull<Rc<i32>> is !Send !Sync

// std::thread::spawn(move || {
//     let ptr = ptr;  // ❌ Error: Rc is not Send!
// });

📊 8.2. Variance and Covariance

Variance = How subtyping relationships are preserved through generic types.

What is Covariance?

// String is a subtype of &str (can be coerced)
let s: String = "hello".into();
let s_ref: &str = &s;

// Box<T> is covariant:
let box_string: Box<String> = Box::new("hello".into());
let box_str: Box<&str> = box_string;  // ✅ OK

NonNull is Covariant

// NonNull<T> is covariant in T
let nn_string: NonNull<String> = ...;

// Can treat as NonNull<&str>... in theory
// (In practice, you'd need transmute, but type system allows it)

Why this matters: Container types using NonNull inherit good variance properties!


🎯 8.3. Comparison with *mut T

// *mut T is INVARIANT
// Cannot coerce *mut String to *mut &str

// NonNull<T> is COVARIANT
// Can coerce NonNull<String> to NonNull<&str> (with transmute)

Result: Types using NonNull have better variance!


🧠 8.4. Chapter Takeaways

  • Send/Sync inherited from T
  • Covariant in T
  • Better variance than *mut T

Next: Chapter 9 — Patterns, Internals, and FFI 🌐