Soundness of Manual Scope Control with transmute and AcqRel under Stacked Borrows
⚓ Rust 📅 2026-02-26 👤 surdeus 👁️ 2Hi everyone,
I'm using transmute to extend a &'a mut T to 'static for linking into a list, while manually enforcing its destruction before 'a ends. I'd like to verify if this is sound under Stacked Borrows (SB).
pub unsafe fn cheat<'a>(self: MyBox<'a, T>) -> MyBox<'static, T> {
// Prevent reordering across the lifetime transformation
std::sync::atomic::compiler_fence(std::sync::atomic::Ordering::AcqRel);
unsafe { std::mem::transmute(self) }
}
Safety Invariants:
Must be removed from the List before 'a ends and cannot be moved out of the scope of 'a.
My Reasoning:
- Tag Preservation:
transmutepreserves the original Pointer Tag (Tag_r) without triggeringRetag. In the SB model, both the original reference and the'staticalias are seen as the sameTag_racting on the sameUniquestack item. - Ordering (The "Two Variables" Problem): Since the compiler might treat the original reference and the
'staticalias as two entirely unrelated variables (due tonoaliasand the broken provenance chain), it could reorder their operations. TheAcqRelfence prevents this by ensuring that original accesses (Release) do not sink below the conversion and new alias accesses (Acquire) do not hoist above it. - Trace Validity: SB tracks the execution trace. Since no access via
Tag_roccurs afterEndRegion('a)(due to the safety invariants), the model should remain valid despite the type-level'staticannotation.
Does this reuse of Tag_r combined with a compiler_fence provide sufficient protection against UB in SB or LLVM's alias analysis?
Thanks!
2 posts - 2 participants
🏷️ Rust_feed