Soundness of transmuting immutable references to mutable when the underlying data is truly immutable

Note that in my opinion/experience, you'll rarely get a satisfying answer to "can I get away with it" type questions on a Rust forum do to the cultural atmosphere:

people are a lot less interested in "getting away with" unsoundness compared to C, and thus don't know or necessarily even care when you can do it, because "you shouldn't".

(I don't personally have a problem with such exploration for private use. Anything exposed to the public is another matter.)

((Also, UB is defined on the language level, not on the results. "Compiled to something I'm ok with" is not a lack of UB. It's a subset of the possible outcomes of UB. This is as true in C as it is in Rust, though a lot of people are in denial. Threads like this would go easier if we had a curt and distinct word for "compiled to something I'm ok with", but I don't have a good suggestion.[1]))

To me, this sounds like you're still thinking along the lines of the compiler having some predictable rules of transformation you can reason about. In this case, you're assuming it will only make certain changes based on specific guarantees about uniqueness and immutability. But nothing says it has to do that!

Let me try to sketch a story to illustrate: From a compiler perspective, the presence of unavoidable UB is a sign that code execution can't reach this point -- the programmer promised they'd never reach UB, in a sense. The compiler can take the presence of UB as a communication from the programmer that a given situation is unreachable, and the compiler is happy to optimize based on that information.

Now say you have some function that unconditionally does the transmutation. That's UB, so the compiler is within its rights to conclude that the function is never called. Every call site must also logically be UB, and further semantic and probably unpredictable changes are made to your code, propagating up the control flow.[2]

Note that no guarantees about uniqueness and immutability changed in this story. The compiler just found a way to optimize based on things which are (already, currently) UB.

(Even if the compiler did have to base their relevant output based on some rules of uniqueness and immutability, you're assuming you can predict how everything changes in the future; not just the rules, but how compilers utilize them. Compilers don't have to do that, so it's moot, but I don't believe *anybody* has that ability.)
  1. I dislike "miscompilation" because the compiler has done nothing wrong. ↩︎

  2. Or it could just delete the body of the function, or heck, effectively alias it with some random other function, since you communicated it could never be called anyway. ↩︎

2 Likes