That doesn't follow. That's like saying that
Cell::set is unsound because it creates a
&mut T while setting the value. There is nothing about creating this
&mut T is wrong. Because for the entire lifetime of the
&mut T there is no other way to access the pointee (
T) other than going through the
&mut T. Also the a new
Cell is immediately created from the
&mut T, so it doesn't leak to the outside world.
This does pass MIRI (although that isn't proof, it's still strong evidence because this is what MIRI was designed to catch).
Now this is UB, because if
Field: Freeze, then
&Field is immutable. But
&Cell<Field> is most certainly not immutable. You must use
Cell::from_mut or pointer casts from
*mut T to
*const Cell<T> to soundly get a
Also, there is a cost to using function pointers, so I'm not sure if that's the best way to do this. You can look into my unpublished crate, where I made a trait for field which handles the projection an lots of type-level meta programming to encode multiple fields and get the rest of the features. Though that may be a bit too heavy weight and hard to maintain.