Self-referential structs: Which version is for you?

⚓ Rust    📅 2026-05-29    👤 surdeus    👁️ 1      

surdeus

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,
}

Version 2: Index Offsets

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

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

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,
}

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?

1 post - 1 participant

Read full topic

🏷️ Rust_feed