I need to access different elements in the slice mutably from multiple threads (it's checked using atomics separately). To avoid creating multiple mutable references to the box I would have to deference it immutably, but then I can't access the elements mutably without UB.
I suppose that it's unlikely to happen. But I would also like my code to work with Loom (whose UnsafeCell<T> is different in layout from T), and the std does explicitly say not to rely on it.
Could you post some actual code? I don't see why this is special to UnsafeCell<Box<[T]>>, it seem to be exactly as easy or hard to do with a primitive array.
I feel like this comment in the standard library does not refer to the #repr[transparent] being unstable at all. Instead it talks about the fact that the standard library is allowed to turn an immutable reference into a mutable pointer here that can then legally be turned into a mutable reference. Ordinarily turning an immutable reference into a mutable one is always UB. On the other hand, the fact that UnsafeCell is transparent is used multiple time in Cell, for example in from_mut or as_slice_of_cells, without any comment that this would be only possible with the special status of he standard library.
I do feel like the comment you linked there is misleading though in that it can be interpreted as the #repr[transparent] being unstable; someone should open an issue about it perhaps. Also I have no idea which casts relying on UnsafeCellʼs transparency are legal and which arenʼt. For example going from &T to &UnsafeCell<T> is probably UB. I don't know about &[UnsafeCell<T>] to &UnsafeCell<[T]>.
All of this is just my personal interpretation. It would be nice to get someone more knowledgeable to comment on these questions.
Well, Cell has an as_slice_of_cells() method, which turns a Cell<&[T]> into a &[Cell<T>]. If this is possible, then the inverse ought to be possible as well, and for UnsafeCell too – it would be weird if it wasn't guaranteed. The parallel with MaybeUninit can also be drawn, which IIRC can be transmuted exactly in the way that you described. These conversions should probably be allowed explicitly – if not in user code, at least (or, I would say, preferably) by means of implementing appropriate as_*() functions on these types in the standard library.