Soundness of Manual Scope Control with transmute and AcqRel under Stacked Borrows

⚓ Rust    📅 2026-02-26    👤 surdeus    👁️ 2      

surdeus

Hi 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: transmute preserves the original Pointer Tag (Tag_r) without triggering Retag. In the SB model, both the original reference and the 'static alias are seen as the same Tag_r acting on the same Unique stack item.
  • Ordering (The "Two Variables" Problem): Since the compiler might treat the original reference and the 'static alias as two entirely unrelated variables (due to noalias and the broken provenance chain), it could reorder their operations. The AcqRel fence 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_r occurs after EndRegion('a) (due to the safety invariants), the model should remain valid despite the type-level 'static annotation.

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

Read full topic

🏷️ Rust_feed