From ef99da4bdf8ccda0eab326a1fcee2ae6dacb7ca6 Mon Sep 17 00:00:00 2001 From: rodrimati1992 Date: Wed, 17 Feb 2021 17:42:12 -0300 Subject: [PATCH] Tried fixing prefix_type::WithMetadata_ declaration for future fix of 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": https://github.com/rust-lang/rust/issues/81996 --- abi_stable/src/inline_storage.rs | 1 + abi_stable/src/marker_type.rs | 123 +++++++++++++++--- .../src/marker_type/stable_abi_impls.rs | 69 ++++++++++ abi_stable/src/prefix_type.rs | 8 +- abi_stable/src/prefix_type/prefix_ref.rs | 2 +- 5 files changed, 177 insertions(+), 26 deletions(-) create mode 100644 abi_stable/src/marker_type/stable_abi_impls.rs diff --git a/abi_stable/src/inline_storage.rs b/abi_stable/src/inline_storage.rs index 54e290a9..7127853f 100644 --- a/abi_stable/src/inline_storage.rs +++ b/abi_stable/src/inline_storage.rs @@ -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)))] diff --git a/abi_stable/src/marker_type.rs b/abi_stable/src/marker_type.rs index 67ca8c38..f6aa9e33 100644 --- a/abi_stable/src/marker_type.rs +++ b/abi_stable/src/marker_type.rs @@ -12,6 +12,8 @@ use crate::{ } }; +#[macro_use] +mod stable_abi_impls; ///////////////// @@ -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>, } +monomorphic_marker_type!{UnsyncUnsend, UnsafeIgnoredType>} + 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>, } +monomorphic_marker_type!{UnsyncSend, UnsafeIgnoredType>} + impl UnsyncSend { /// Constructs a `UnsyncSend` pub const NEW: Self = Self { _marker: UnsafeIgnoredType::NEW }; @@ -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 }; @@ -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{ - _priv: [u8; 0], - _marker:NonOwningPhantom, +pub struct ErasedObject{ + _marker: NonOwningPhantom, +} + +// 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(extern "C" fn(&T)); + unsafe impl __GetStaticEquivalent_ for ErasedObject + where + T: __StableAbi, + { + type StaticEquivalent = _static_ErasedObject<__GetStaticEquivalent>; + } + #[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 ErasedObject + 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,), + __sabi_re::RSlice::from_slice(Self::__SABI_CONST_PARAMS_B), + ); + } + unsafe impl __sabi_re::StableAbi for ErasedObject + where + T: __StableAbi, + { + type IsNonZeroType = __sabi_re::False; + const LAYOUT: &'static __sabi_re::TypeLayout = { + ["Expected this to be Zero-sized"][(std::mem::size_of::() != 0) as usize]; + ["Expected this to be 1 aligned"][(std::mem::align_of::() != 1) as usize]; + + &__sabi_re::TypeLayout::from_derive::(__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, } +const _: [(); 0] = [(); std::mem::size_of::()]; +const _: [(); 1] = [(); std::mem::align_of::()]; + unsafe impl GetStaticEquivalent_ for ErasedPrefix { type StaticEquivalent = ErasedPrefix; } @@ -121,22 +208,18 @@ since the type parameter is ignored when type checking dynamic libraries. [`StableAbi`]: ../trait.StableAbi.html */ -#[repr(C)] pub struct UnsafeIgnoredType { - _priv: [u8; 0], _inner: PhantomData, } impl UnsafeIgnoredType{ /// Constructs an `UnsafeIgnoredType`. pub const DEFAULT:Self=Self{ - _priv:[], _inner:PhantomData, }; /// Constructs an `UnsafeIgnoredType`. pub const NEW:Self=Self{ - _priv:[], _inner:PhantomData, }; } @@ -181,6 +264,9 @@ unsafe impl StableAbi for UnsafeIgnoredType { let (mono_shared_vars,shared_vars)={}; } + ["Expected this to be Zero-sized"][(std::mem::size_of::() != 0) as usize]; + ["Expected this to be 1 aligned"][(std::mem::align_of::() != 1) as usize]; + &TypeLayout::from_std::( shared_vars, MONO_TYPE_LAYOUT, @@ -195,7 +281,6 @@ unsafe impl StableAbi for UnsafeIgnoredType { /// An ffi-safe equivalent of a `PhantomDataT>` pub struct NonOwningPhantom{ - _priv: [u8;0], // The StableAbi layout for a `NonOwningPhantom` is the same as `PhantomData`, // the type of this field is purely for variance. _marker: PhantomDataT> @@ -204,13 +289,11 @@ pub struct NonOwningPhantom{ impl NonOwningPhantom{ /// Constructs a `NonOwningPhantom` pub const DEFAULT:Self=Self{ - _priv:[], _marker:PhantomData, }; /// Constructs a `NonOwningPhantom` pub const NEW:Self=Self{ - _priv:[], _marker:PhantomData, }; } diff --git a/abi_stable/src/marker_type/stable_abi_impls.rs b/abi_stable/src/marker_type/stable_abi_impls.rs new file mode 100644 index 00000000..f094ca63 --- /dev/null +++ b/abi_stable/src/marker_type/stable_abi_impls.rs @@ -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::() != 0) as usize]; + ["Expected this to be 1 aligned"][(std::mem::align_of::() != 1) as usize]; + + &__sabi_re::TypeLayout::from_derive::(__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, + }) + }; + } + }; +} \ No newline at end of file diff --git a/abi_stable/src/prefix_type.rs b/abi_stable/src/prefix_type.rs index 04efd378..3e98a8db 100644 --- a/abi_stable/src/prefix_type.rs +++ b/abi_stable/src/prefix_type.rs @@ -9,6 +9,7 @@ use std::{ }; use crate::{ + inline_storage::alignment::AlignToUsize, pointer_trait::ImmutableRef, marker_type::{NotCopyNotClone, NonOwningPhantom}, sabi_types::StaticRef, @@ -210,10 +211,8 @@ pub type WithMetadata::PrefixFields> = #[repr(C)] pub struct WithMetadata_ { pub metadata: PrefixMetadata, - // Forces value to be aligned to at least a usize. - _alignment: [usize; 0], /// The wrapped value. - pub value: T, + pub value: AlignToUsize, unbounds: NotCopyNotClone, } @@ -227,8 +226,7 @@ impl WithMetadata_ { pub const fn new(metadata: PrefixMetadata, value: T) -> Self { Self { metadata, - _alignment: [], - value, + value: AlignToUsize(value), unbounds: NotCopyNotClone, } } diff --git a/abi_stable/src/prefix_type/prefix_ref.rs b/abi_stable/src/prefix_type/prefix_ref.rs index 36640092..d13bcd67 100644 --- a/abi_stable/src/prefix_type/prefix_ref.rs +++ b/abi_stable/src/prefix_type/prefix_ref.rs @@ -353,7 +353,7 @@ impl

PrefixRef

{ #[inline] pub fn prefix<'a>(self)-> &'a P { unsafe{ - &(*self.ptr.as_ptr()).value + &(*self.ptr.as_ptr()).value.0 } }