How can I reference a Pin struct field from another field?

You cannot write this struct without unsafe code, and Pin cannot reduce the amount of unsafe code you need. Here's how you can build the struct without Pin:

struct S {
    buf: *mut [u8],
    slice: Option<*const [u8]>,
}
impl Drop for S {
    fn drop(&mut self) {
        let b = unsafe { Box::from_raw(self.buf) };
        drop(b);
    }
}

impl S {
    pub fn new() -> Self {
        let buf = vec![0u8, 1, 2, 3].into_boxed_slice();
        let buf_ptr = Box::into_raw(buf);
        let slice = Some(buf_ptr as *const [u8]);

        S {
            buf: buf_ptr,
            slice,
        }
    }
    fn buf(&self) -> &[u8] {
        unsafe { &*self.buf }
    }
    fn slice(&self) -> Option<&[u8]> {
        unsafe { self.slice.map(|ptr| &*ptr) }
    }
}

fn main() {
    let s = S::new();
    assert_eq!(s.slice().unwrap(), s.buf());
}

playground

You may want to read this post of mine, which explains where Pin is useful, namely when two pieces of unsafe code need to communicate guarantees through unknown non-unsafe user code. When everything happens in a single module, Pin does not help you at all, and module privacy can provide all the things you need to write correct (but wildly unsafe) self-referential structs.

1 Like