i reread this tutorial about rust subtype and variance: Subtyping and Variance - The Rustonomicon.
it says UnsafeCell<T> is invariant over T. but i remember that the struct definition of UnsafeCell is following
pub struct UnsafeCell<T: ?Sized> {
value: T,
}
this conclusion is counter intuitive, because if i define MyUnsafeCell like following
pub struct MyUnsafeCell<T> {
value: T,
}
then compiler will infer that MyUnsafeCell is covariant over T.
so i guess UnsafeCell is not only a part of rust std library, but also a part of the rust language itself.
let me make it more clear, if something is just a part of rust std library, i think we can achieve the same functionality and semantic by our own without modification of compiler code. but if something is a part of the language itself, we can't achieve the same functionality and semantic without the modification of compiler code.
Note #[lang] macro means there is a special lang item, and that's the magic
UnsafeCellis a lang item (core) because it has very special semantics; it prevents certain optimizations. Specifically, Rust is allowed to reorder reads/writes to &mut foo with the assumption that the local variable holding the reference is the only alias allowed to read from or write to the data, and it is allowed to reorder reads from &foo assuming that no other alias writes to it. We tell LLVM that these types are noalias . UnsafeCell<T> turns this optimization off, allowing writes to &UnsafeCell<T> references. This is used in the implementation of interior mutability types like Cell<T> , RefCell<T> , and Mutex<T> .