Skip to content

Commit

Permalink
Tried fixing prefix_type::WithMetadata_ declaration for future fix of…
Browse files Browse the repository at this point in the history
… MSVC abi fix.

Tried fixing marker type declarations to be zero sized after MSVC abi.

This commit assumes that this issue will get resolved to "#[repr(C)] structs can't be zero-sized":
rust-lang/rust#81996
  • Loading branch information
rodrimati1992 committed Feb 17, 2021
1 parent 5fc89e5 commit ef99da4
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 26 deletions.
1 change: 1 addition & 0 deletions abi_stable/src/inline_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ pub mod alignment{
/// Aligns its contents to an address to an address at
/// a multiple of the size of a pointer.
#[repr(C)]
#[derive(Copy, Clone)]
#[cfg_attr(target_pointer_width="128",repr(C,align(16)))]
#[cfg_attr(target_pointer_width="64",repr(C,align(8)))]
#[cfg_attr(target_pointer_width="32",repr(C,align(4)))]
Expand Down
123 changes: 103 additions & 20 deletions abi_stable/src/marker_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use crate::{
}
};

#[macro_use]
mod stable_abi_impls;

/////////////////

Expand All @@ -23,26 +25,27 @@ pub struct SyncSend;
/////////////////

/// Marker type used to mark a type as being `!Send + !Sync`.
#[repr(C)]
#[derive(StableAbi)]
pub struct UnsyncUnsend {
_marker: UnsafeIgnoredType<Rc<()>>,
}

monomorphic_marker_type!{UnsyncUnsend, UnsafeIgnoredType<Rc<()>>}

impl UnsyncUnsend {
/// Constructs a `UnsyncUnsend`
pub const NEW: Self = Self { _marker: UnsafeIgnoredType::NEW };
}


/////////////////

/// Marker type used to mark a type as being `Send + !Sync`.
#[repr(C)]
#[derive(StableAbi)]
pub struct UnsyncSend {
_marker: UnsafeIgnoredType<Cell<()>>,
}

monomorphic_marker_type!{UnsyncSend, UnsafeIgnoredType<Cell<()>>}

impl UnsyncSend {
/// Constructs a `UnsyncSend`
pub const NEW: Self = Self { _marker: UnsafeIgnoredType::NEW };
Expand All @@ -51,12 +54,13 @@ impl UnsyncSend {
/////////////////

/// Marker type used to mark a type as being `!Send + Sync`.
#[repr(C)]
#[derive(StableAbi)]
// #[sabi(debug_print)]
pub struct SyncUnsend {
_marker: UnsyncUnsend,
}

monomorphic_marker_type!{SyncUnsend, UnsyncUnsend}

impl SyncUnsend {
/// Constructs a `SyncUnsend`
pub const NEW: Self = Self { _marker: UnsyncUnsend::NEW };
Expand All @@ -71,29 +75,112 @@ unsafe impl Sync for SyncUnsend{}
/// it is semantically an error to do so.
#[repr(C)]
#[derive(StableAbi)]
// #[sabi(debug_print)]
pub struct NotCopyNotClone;

//////////////////////////////////////////////////////////////


/// Used by vtables/pointers to signal that the type has been erased.
///
#[repr(C)]
#[derive(StableAbi)]
pub struct ErasedObject<T=()>{
_priv: [u8; 0],
_marker:NonOwningPhantom<T>,
pub struct ErasedObject<T = ()>{
_marker: NonOwningPhantom<T>,
}

// Delete this once the abi_stable version number isn't 0.9
//
const _ITEM_INFO_CONST_ERASEDOBJECT: abi_stable::type_layout::ItemInfo =
abi_stable::make_item_info!();
const _SHARED_VARS_STRINGS_ERASEDOBJECT: ::abi_stable::std_types::RStr<'static> =
abi_stable::std_types::RStr::from_str("_priv;_marker;");
#[allow(non_upper_case_globals)]
mod _sabi_erasedobject {
use super::*;
pub(super) use :: abi_stable;
#[allow(unused_imports)]
pub(super) use ::abi_stable::derive_macro_reexports::{self as __sabi_re, renamed::*};
pub struct _static_ErasedObject<T: ?Sized>(extern "C" fn(&T));
unsafe impl<T> __GetStaticEquivalent_ for ErasedObject<T>
where
T: __StableAbi,
{
type StaticEquivalent = _static_ErasedObject<__GetStaticEquivalent<T>>;
}
#[doc(hidden)]
pub(super) const _MONO_LAYOUT_ErasedObject: &'static __sabi_re::MonoTypeLayout =
&__sabi_re::MonoTypeLayout::from_derive(__sabi_re::_private_MonoTypeLayoutDerive {
name: abi_stable::std_types::RStr::from_str("ErasedObject"),
item_info: _ITEM_INFO_CONST_ERASEDOBJECT,
data: __sabi_re::MonoTLData::derive_struct(__CompTLFields::new(
abi_stable::std_types::RSlice::from_slice(&[
562949953748992u64,
1688849860722694u64,
]),
None,
)),
generics: abi_stable ::tl_genparams !(
;
__StartLen :: new(0u16, 0u16) ;
__StartLen :: new(0u16, 0u16)
),
mod_refl_mode: __ModReflMode::Opaque,
repr_attr: __ReprAttr::C,
phantom_fields: abi_stable::std_types::RSlice::from_slice(&[]),
shared_vars: abi_stable::type_layout::MonoSharedVars::new(
_SHARED_VARS_STRINGS_ERASEDOBJECT,
abi_stable::std_types::RSlice::from_slice(&[]),
),
});
impl<T> ErasedObject<T>
where
T: __StableAbi,
{
const __SABI_CONST_PARAMS_A: &'static [&'static __sabi_re::ConstGenericErasureHack<
dyn ::std::marker::Send,
>] = &[];
const __SABI_CONST_PARAMS_B: &'static [__ConstGeneric] = &[];
const __SABI_SHARED_VARS: &'static __sabi_re::SharedVars =
&abi_stable::type_layout::SharedVars::new(
_MONO_LAYOUT_ErasedObject.shared_vars_static(),
abi_stable::_sabi_type_layouts!([u8; 0], NonOwningPhantom<T>,),
__sabi_re::RSlice::from_slice(Self::__SABI_CONST_PARAMS_B),
);
}
unsafe impl<T> __sabi_re::StableAbi for ErasedObject<T>
where
T: __StableAbi,
{
type IsNonZeroType = __sabi_re::False;
const LAYOUT: &'static __sabi_re::TypeLayout = {
["Expected this to be Zero-sized"][(std::mem::size_of::<Self>() != 0) as usize];
["Expected this to be 1 aligned"][(std::mem::align_of::<Self>() != 1) as usize];

&__sabi_re::TypeLayout::from_derive::<Self>(__sabi_re::_private_TypeLayoutDerive {
shared_vars: Self::__SABI_SHARED_VARS,
mono: _MONO_LAYOUT_ErasedObject,
abi_consts: Self::ABI_CONSTS,
data: __sabi_re::GenericTLData::Struct,
tag: None,
extra_checks: None,
})
};
}
}



//////////////////////////////////////////////////////////////


/// Used by pointers to vtables/modules to signal that the type has been erased.
///
#[repr(C)]
pub struct ErasedPrefix{
_priv: [u8; 0],
_priv: PhantomData<u8>,
}

const _: [(); 0] = [(); std::mem::size_of::<ErasedPrefix>()];
const _: [(); 1] = [(); std::mem::align_of::<ErasedPrefix>()];

unsafe impl GetStaticEquivalent_ for ErasedPrefix {
type StaticEquivalent = ErasedPrefix;
}
Expand Down Expand Up @@ -121,22 +208,18 @@ since the type parameter is ignored when type checking dynamic libraries.
[`StableAbi`]: ../trait.StableAbi.html
*/
#[repr(C)]
pub struct UnsafeIgnoredType<T:?Sized> {
_priv: [u8; 0],
_inner: PhantomData<T>,
}

impl<T:?Sized> UnsafeIgnoredType<T>{
/// Constructs an `UnsafeIgnoredType`.
pub const DEFAULT:Self=Self{
_priv:[],
_inner:PhantomData,
};

/// Constructs an `UnsafeIgnoredType`.
pub const NEW:Self=Self{
_priv:[],
_inner:PhantomData,
};
}
Expand Down Expand Up @@ -181,6 +264,9 @@ unsafe impl<T> StableAbi for UnsafeIgnoredType<T> {
let (mono_shared_vars,shared_vars)={};
}

["Expected this to be Zero-sized"][(std::mem::size_of::<Self>() != 0) as usize];
["Expected this to be 1 aligned"][(std::mem::align_of::<Self>() != 1) as usize];

&TypeLayout::from_std::<Self>(
shared_vars,
MONO_TYPE_LAYOUT,
Expand All @@ -195,7 +281,6 @@ unsafe impl<T> StableAbi for UnsafeIgnoredType<T> {

/// An ffi-safe equivalent of a `PhantomData<fn()->T>`
pub struct NonOwningPhantom<T:?Sized>{
_priv: [u8;0],
// The StableAbi layout for a `NonOwningPhantom<T>` is the same as `PhantomData<T>`,
// the type of this field is purely for variance.
_marker: PhantomData<extern "C" fn()->T>
Expand All @@ -204,13 +289,11 @@ pub struct NonOwningPhantom<T:?Sized>{
impl<T:?Sized> NonOwningPhantom<T>{
/// Constructs a `NonOwningPhantom`
pub const DEFAULT:Self=Self{
_priv:[],
_marker:PhantomData,
};

/// Constructs a `NonOwningPhantom`
pub const NEW:Self=Self{
_priv:[],
_marker:PhantomData,
};
}
Expand Down
69 changes: 69 additions & 0 deletions abi_stable/src/marker_type/stable_abi_impls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Delete this once the abi_stable version number isn't 0.9
//
macro_rules! monomorphic_marker_type {
($name:ident, $field:ty) => {
#[allow(non_upper_case_globals)]
const _: () = {monomorphic_marker_type!{@inner $name, $field}};
};
(@inner $name:ident, $field:ty) => {
const _item_info_const_: abi_stable::type_layout::ItemInfo =
abi_stable::make_item_info!();
const _SHARED_VARS_STRINGS_: ::abi_stable::std_types::RStr<'static> =
abi_stable::std_types::RStr::from_str("_marker;");

use ::abi_stable::derive_macro_reexports::{self as __sabi_re, renamed::*};
pub struct _static_(extern "C" fn());
unsafe impl __GetStaticEquivalent_ for $name {
type StaticEquivalent = _static_;
}
#[doc(hidden)]
pub(super) const _MONO_LAYOUT_: &'static __sabi_re::MonoTypeLayout =
&__sabi_re::MonoTypeLayout::from_derive(__sabi_re::_private_MonoTypeLayoutDerive {
name: abi_stable::std_types::RStr::from_str(stringify!($name)),
item_info: _item_info_const_,
data: __sabi_re::MonoTLData::derive_struct(__CompTLFields::new(
abi_stable::std_types::RSlice::from_slice(&[562949953880064u64]),
None,
)),
generics: abi_stable ::
tl_genparams !
(; __StartLen :: new(0u16, 0u16) ; __StartLen ::
new(0u16, 0u16)),
mod_refl_mode: __ModReflMode::Opaque,
repr_attr: __ReprAttr::C,
phantom_fields: abi_stable::std_types::RSlice::from_slice(&[]),
shared_vars: abi_stable::type_layout::MonoSharedVars::new(
_SHARED_VARS_STRINGS_,
abi_stable::std_types::RSlice::from_slice(&[]),
),
});
impl $name {
const __SABI_CONST_PARAMS_A: &'static [&'static __sabi_re::ConstGenericErasureHack<
dyn ::std::marker::Send,
>] = &[];
const __SABI_CONST_PARAMS_B: &'static [__ConstGeneric] = &[];
const __SABI_SHARED_VARS: &'static __sabi_re::SharedVars =
&abi_stable::type_layout::SharedVars::new(
_MONO_LAYOUT_.shared_vars_static(),
abi_stable::_sabi_type_layouts!($field,),
__sabi_re::RSlice::from_slice(Self::__SABI_CONST_PARAMS_B),
);
}
unsafe impl __sabi_re::StableAbi for $name {
type IsNonZeroType = __sabi_re::False;
const LAYOUT: &'static __sabi_re::TypeLayout = {
["Expected this to be Zero-sized"][(std::mem::size_of::<Self>() != 0) as usize];
["Expected this to be 1 aligned"][(std::mem::align_of::<Self>() != 1) as usize];

&__sabi_re::TypeLayout::from_derive::<Self>(__sabi_re::_private_TypeLayoutDerive {
shared_vars: Self::__SABI_SHARED_VARS,
mono: _MONO_LAYOUT_,
abi_consts: Self::ABI_CONSTS,
data: __sabi_re::GenericTLData::Struct,
tag: None,
extra_checks: None,
})
};
}
};
}
8 changes: 3 additions & 5 deletions abi_stable/src/prefix_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::{
};

use crate::{
inline_storage::alignment::AlignToUsize,
pointer_trait::ImmutableRef,
marker_type::{NotCopyNotClone, NonOwningPhantom},
sabi_types::StaticRef,
Expand Down Expand Up @@ -210,10 +211,8 @@ pub type WithMetadata<T, P = <T as PrefixTypeTrait>::PrefixFields> =
#[repr(C)]
pub struct WithMetadata_<T, P> {
pub metadata: PrefixMetadata<T, P>,
// Forces value to be aligned to at least a usize.
_alignment: [usize; 0],
/// The wrapped value.
pub value: T,
pub value: AlignToUsize<T>,
unbounds: NotCopyNotClone,
}

Expand All @@ -227,8 +226,7 @@ impl<T, P> WithMetadata_<T, P> {
pub const fn new(metadata: PrefixMetadata<T, P>, value: T) -> Self {
Self {
metadata,
_alignment: [],
value,
value: AlignToUsize(value),
unbounds: NotCopyNotClone,
}
}
Expand Down
2 changes: 1 addition & 1 deletion abi_stable/src/prefix_type/prefix_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ impl<P> PrefixRef<P>{
#[inline]
pub fn prefix<'a>(self)-> &'a P {
unsafe{
&(*self.ptr.as_ptr()).value
&(*self.ptr.as_ptr()).value.0
}
}

Expand Down

0 comments on commit ef99da4

Please sign in to comment.