DEV Community

Cover image for Self-referential structs: Which version is for you?
Prathmesh barot
Prathmesh barot

Posted on

Self-referential structs: Which version is for you?

Writing self-referential structs in Rust is a complete nightmare; the borrow checker won't let you do it natively. Testing three common workarounds for this pattern. Which approach do you actually commit to?

Version 1: Unsafe & Raw Pointers

No dependencies; total control but requires manual safety audits.

struct SelfRef {
    data: String,
    slice: *const str,
    _pin: std::marker::PhantomPinned,
}

Enter fullscreen mode Exit fullscreen mode

Version 2: Index Offsets

100% safe code; avoids lifetime issues entirely by storing ranges.

struct IndexRef {
    data: String,
    slice_range: std::ops::Range<usize>,
}

Enter fullscreen mode Exit fullscreen mode

Version 3: Macro Crates (ouroboros)

Clean syntax; abstracts the pain away but introduces a heavy dependency.

#[ouroboros::self_referencing]
struct MacroRef {
    data: String,
    #[borrowed]
    slice: &str,
}

Enter fullscreen mode Exit fullscreen mode

Offsets feel like a workaround that loses type expressiveness; raw pointers are an open invitation for UB. Is using a macro crate the only sane path forward; or do you just refactor the data flow to avoid this entirely?

Now tell me which one is for you?

Top comments (0)