Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Pin and PhantomPinned

Overview

Pin<P> prevents moving of a value in memory, enabling self-referential structs and safe async implementations.

Code Example

#![allow(unused)]
fn main() {
use std::pin::Pin;
use std::marker::PhantomPinned;

struct SelfReferential {
    data: String,
    data_ptr: *const String,
    _pin: PhantomPinned,
}

impl SelfReferential {
    fn new(data: String) -> Pin<Box<Self>> {
        let mut boxed = Box::pin(SelfReferential {
            data,
            data_ptr: std::ptr::null(),
            _pin: PhantomPinned,
        });
        
        let data_ptr = &boxed.data as *const String;
        unsafe {
            let mut_ref = Pin::as_mut(&mut boxed);
            Pin::get_unchecked_mut(mut_ref).data_ptr = data_ptr;
        }
        boxed
    }
    
    fn get_data(&self) -> &str {
        &self.data
    }
}

let pinned = SelfReferential::new("Pinned data".to_string());
println!("Pinned data: {}", pinned.get_data());
}

Key Concepts

  • Pin: Guarantees value won’t move in memory
  • PhantomPinned: Marks type as !Unpin
  • Essential for self-referential structs and async/await

Learn More