Is the prohibition of directly converting from &UnsafeCell<T> to &mut T a conceptual or technical restriction?

If it's a technical limitation, can anyone explain the code below, what optimizations might the compiler make that could lead to undefined behavior?

use std::cell::UnsafeCell;

unsafe fn not_allowed<T>(ptr: &UnsafeCell<T>) {
  let t1 = ptr as *const UnsafeCell<T> as *mut T;
  // This is undefined behavior, because the `*mut T` pointer
  // was not obtained through `.get()` nor `.raw_get()`:
  unsafe { &mut *t1 };  

  // OK
  let t2 = ptr.get();
  unsafe { &mut *t2 };
}
2 Likes

Not trying to derail the thread,[1] but since UB is defined at the language level,[2] I will note that at some level there is no meaningful distinction between conceptual and technical restrictions. Different compilers may have different technical considerations, and restrictions may flip between technical and conceptual as a single compiler evolves.

(E.g. many rustc restrictions are projections of LLVM restrictions -- at least so far -- which evolve over time outside of the Rust team's control.)


  1. curious about the practical answer for rustc today myself ↩︎

  2. "could lead to UB" is a red flag that you don't recognize this BTW; if the lang says it's UB, it is ↩︎

2 Likes

Whatever the limitation comes from, I want to know the detail.
It is not meaningless, if I know more, then I can remember less. --- It is impossible to remember all the details such as I should not do something because it will lead to UB.

I prefer some theory, then I can deduce the limitations by my self.

It seems to me that the reason it's currently prohibited is simply because it's unclear whether it would be beneficial in the future to make it UB. Can a pointer obtained by casting `&UnsafeCell<T>` to `*mut T` be written to? · Issue #281 · rust-lang/unsafe-code-guidelines · GitHub

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.