Fix soundness hole in FieldOffset

This was cause by the change to allow to create FieldOffset in const constext
because a Fn(T)->U  is not allowed in a const constext.
But we need to be contravariant in T.
This commit is contained in:
Olivier Goffart 2020-05-18 11:02:40 +02:00
parent 07942da4bb
commit 68cea2aeec

View file

@ -23,11 +23,23 @@ pub use const_field_offset_macro::FieldOffsets;
pub struct FieldOffset<T, U>( pub struct FieldOffset<T, U>(
/// Offset in bytes of the field within the struct /// Offset in bytes of the field within the struct
usize, usize,
// ### Changed from Fn to fn to allow const /// ### Changed from Fn to fn to allow const
// it is fine to be fariant /// Should be fn(T)->U, but we can't make that work in const context.
PhantomData<(*const T, *const U)>, /// So make it invariant in T instead
///
/// ```compile_fail
/// use const_field_offset::FieldOffset;
/// struct Foo<'a>(&'a str);
/// fn test<'a>(foo: &Foo<'a>, of: FieldOffset<Foo<'static>, &'static str>) -> &'static str {
/// let of2 : FieldOffset<Foo<'a>, &'static str> = of; // This must not compile
/// of2.apply(foo)
/// }
/// ```
PhantomData<(*mut T, *const U)>,
); );
unsafe impl<T, U> Send for FieldOffset<T, U> {}
impl<T, U> FieldOffset<T, U> { impl<T, U> FieldOffset<T, U> {
// Use MaybeUninit to get a fake T // Use MaybeUninit to get a fake T
#[cfg(fieldoffset_maybe_uninit)] #[cfg(fieldoffset_maybe_uninit)]