PhantomMut marker

Is there a way to make the compiler put a static exemplar to .data instead of .rodata on type level without using cells directly? I mean, is there a way to make compiler make it mutable at run-time by just applying a marker? I tried to implement my own one (basically, a wrapper around PhantomData<UnsafeCell<()>>), but didn’t succeed.

Please don’t ask me about purpose.

Have you tried a wrapper around an ordinary UnsafeCell<()>, rather than a PhantomData? At least for me, that makes the compiler place the symbol into .data instead of .rodata.

I mean, is there a way to make compiler make it mutable at run-time by just applying a marker?

You are never permitted to mutate any part of a static value that is outside an UnsafeCell. If you do, then you are invoking undefined behavior.


Thanks! Fits perfectly!

I know, that’s why I stated “Please don’t ask me about purpose”. I knew people would scold me for such tricks :joy:

Well, the bigger problem isn't that people will scold you, it's that the compiler will miscompile your code. For instance, if something holds a reference to that static variable, then the compiler will happily assume that its value cannot change. To illustrate, this program prints 123 twice (Rust Playground):

use std::{cell::UnsafeCell, ptr::addr_of, hint};

pub struct PhantomMut(UnsafeCell<()>);
unsafe impl Send for PhantomMut {}
unsafe impl Sync for PhantomMut {}
impl PhantomMut {
    pub const fn new() -> Self {

pub static FOO: (i32, PhantomMut) = (123, PhantomMut::new());

fn example(r: &i32) {
    let print = |x| println!("{x}");
    unsafe { *(addr_of!(FOO.0) as *mut i32) = 456 };

fn main() {

I'll admit that the Rust compiler currently doesn't inline the value of the part of an interior-mutable static which is outside an UnsafeCell, so this issue is currently unlikely to occur without holding onto a reference. But there's absolutely no guarantee that this will continue to work on later versions of the compiler.