Make `AliasingSafe` more powerful
joshlf opened this issue · 0 comments
Currently, AliasingSafe
has the following safety invariants:
/// `U: AliasingSafe<T, A, R>` if either of the following conditions holds:
/// - `A` is [`Exclusive`]
/// - `T` and `U` both implement [`Immutable`]
However, we could relax this to:
/// `U: AliasingSafe<T, A, R>` if either of the following conditions holds:
/// - `A` is [`Exclusive`]
/// - `T` and `U` contain [`UnsafeCell`]s at the same locations
In particular, "T
and U
implement Immutable
" is just a special case of " T
and U
contain UnsafeCell
s at the same locations." If we did this, we could add a new AliasingSafeReason
called BecauseUnsafeCellsAgree
or something to that effect.
We could then piggy-back on our existing TransparentWrapper
machinery to provide a blanket impl. In particular, wherever W: TransparentWrapper<Inner = T, UnsafeCellVariance = Covariant>
, we can infer that W: AliasingSafe<T, _, BecauseUnsafeCellsAgree>
.
Unfortunately, this construction is less powerful than we'd like. In particular, it is not true in the general case that W: TransparentWrapper<Inner = T>
implies T: TransparentWrapper<Inner = W>
, but AliasingSafe
is reflexive in this way. In practice, this causes problems for transparent_wrapper_into_inner
: If we try to add an AliasingSafe
bound to cast_unsized
(a natural thing to do, and it removes a safety precondition), transparent_wrapper_into_inner
's TransparentWrapper
bound isn't sufficient to satisfy cast_unsized
's bound. This is prototyped here. Try to build that code and see its compilation errors from transparent_wrapper_into_inner
.
In order to work around this, we should split TransparentWrapper
into multiple traits. Some of its properties - namely, size equality and UnsafeCell
agreement - are reflexive, and can go in a separate trait which guarantees this reflexivity (and maybe encodes it in the type system somehow).