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?
Top comments (0)