Struct abi_stable::sabi_types::StaticRef
source · pub struct StaticRef<T> { /* private fields */ }
Expand description
A wrapper type for vtable static references,
and other constants that have non-'static
generic parameters
but are safe to reference for the lifetime of T
.
§Purpose
This type is necessary because Rust doesn’t understand that vtables live for 'static
,
even though they have non-'static
type parameters.
§Example
This defines a non-extensible vtable,using a StaticRef as the pointer to the vtable.
use abi_stable::{
marker_type::ErasedObject,
prefix_type::{PrefixTypeTrait, WithMetadata},
sabi_extern_fn,
sabi_types::StaticRef,
staticref, StableAbi,
};
use std::{marker::PhantomData, ops::Deref};
fn main() {
let boxed = BoxLike::new("foo".to_string());
assert_eq!(boxed.as_str(), "foo");
}
/// An ffi-safe `Box<T>`
#[repr(C)]
#[derive(StableAbi)]
pub struct BoxLike<T> {
data: *mut T,
vtable: StaticRef<VTable<T>>,
_marker: PhantomData<T>,
}
impl<T> BoxLike<T> {
pub fn new(value: T) -> Self {
Self {
data: Box::into_raw(Box::new(value)),
vtable: VTable::<T>::VTABLE,
_marker: PhantomData,
}
}
}
impl<T> Drop for BoxLike<T> {
fn drop(&mut self) {
unsafe {
(self.vtable.drop_)(self.data);
}
}
}
impl<T> Deref for BoxLike<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.data }
}
}
#[repr(C)]
#[derive(StableAbi)]
pub struct VTable<T> {
drop_: unsafe extern "C" fn(*mut T),
}
impl<T> VTable<T> {
// The `staticref` macro declares a `StaticRef<VTable<T>>` constant.
staticref!(const VTABLE: Self = Self{
drop_: drop_box::<T>,
});
}
#[sabi_extern_fn]
unsafe fn drop_box<T>(object: *mut T) {
drop(Box::from_raw(object));
}
Implementations§
source§impl<T, P> StaticRef<WithMetadata_<T, P>>
impl<T, P> StaticRef<WithMetadata_<T, P>>
sourcepub const fn as_prefix(self) -> PrefixRef<P>
pub const fn as_prefix(self) -> PrefixRef<P>
Constructs a PrefixRef<P>
from self.
This is most useful when you have a generic type that isn’t 'static
for type system reasons, but lives for the entire program.
§Example
use abi_stable::{
for_examples::{PhantModule, PhantModule_Ref},
prefix_type::{PrefixRef, PrefixTypeTrait, WithMetadata},
std_types::{RNone, RStr},
staticref,
};
struct Foo<T>(T);
impl<T: Copy> Foo<T> {
// The `staticref` invocation here declares a
// `StaticRef<WithMetadata<PhantModule<T>>>` constant.
staticref!(const WITH_META: WithMetadata<PhantModule<T>> = WithMetadata::new(
PhantModule {
first: RNone,
second: RStr::from_str("hello"),
third: 100,
phantom: std::marker::PhantomData,
},
));
}
const MOD: PhantModule_Ref<()> = PhantModule_Ref(Foo::WITH_META.as_prefix());
assert_eq!(MOD.first(), RNone);
assert_eq!(MOD.second().as_str(), "hello");
source§impl<T> StaticRef<T>
impl<T> StaticRef<T>
sourcepub const unsafe fn from_raw(ref_: *const T) -> Self
pub const unsafe fn from_raw(ref_: *const T) -> Self
Constructs this StaticRef from a raw pointer.
§Safety
You must ensure that the raw pointer is valid for the entire program’s lifetime.
§Example
use abi_stable::sabi_types::StaticRef;
struct GetPtr<T>(T);
impl<T> GetPtr<T> {
const PTR: *const Option<T> = &None;
const STATIC: StaticRef<Option<T>> = unsafe { StaticRef::from_raw(Self::PTR) };
}
{}
sourcepub const fn new(ref_: &'static T) -> Self
pub const fn new(ref_: &'static T) -> Self
Constructs this StaticRef from a static reference
This implicitly requires that T:'static
.
§Example
use abi_stable::sabi_types::StaticRef;
struct GetPtr<T>(T);
impl<T> GetPtr<T>
where
T: 'static,
{
const REF: &'static Option<T> = &None;
const STATIC: StaticRef<Option<T>> = StaticRef::new(Self::REF);
}
sourcepub fn leak_value(val: T) -> Self
pub fn leak_value(val: T) -> Self
Creates a StaticRef by heap allocating and leaking val
.
sourcepub const fn get<'a>(self) -> &'a T
pub const fn get<'a>(self) -> &'a T
Gets access to the reference.
This returns &'a T
instead of &'static T
to support vtables of non-'static
types.
§Example
use abi_stable::sabi_types::StaticRef;
struct GetPtr<T>(T);
impl<T> GetPtr<T> {
const PTR: *const Option<T> = &None;
const STATIC: StaticRef<Option<T>> = unsafe { StaticRef::from_raw(Self::PTR) };
}
let reference: &'static Option<String> = GetPtr::<String>::STATIC.get();
sourcepub const fn as_ptr(self) -> *const T
pub const fn as_ptr(self) -> *const T
Gets access to the referenced value,as a raw pointer.
§Example
use abi_stable::sabi_types::StaticRef;
use std::convert::Infallible;
struct GetPtr<T>(T);
impl<T> GetPtr<T> {
const PTR: *const Option<T> = &None;
const STATIC: StaticRef<Option<T>> = unsafe { StaticRef::from_raw(Self::PTR) };
}
let reference: *const Option<Infallible> = GetPtr::<Infallible>::STATIC.as_ptr();
sourcepub const unsafe fn transmute<U>(self) -> StaticRef<U>
pub const unsafe fn transmute<U>(self) -> StaticRef<U>
Transmutes this StaticRef<T>
to a StaticRef<U>
.
§Safety
StaticRef has the same rules that references have regarding transmuting from one type to another:
§Example
use abi_stable::sabi_types::StaticRef;
struct GetPtr<T>(T);
impl<T> GetPtr<T> {
const PTR: *const Option<T> = &None;
const STATIC: StaticRef<Option<T>> = unsafe { StaticRef::from_raw(Self::PTR) };
}
let reference: StaticRef<Option<[(); 0xFFF_FFFF]>> =
unsafe { GetPtr::<()>::STATIC.transmute::<Option<[(); 0xFFF_FFFF]>>() };
Trait Implementations§
source§impl<T, U> CanTransmuteElement<U> for StaticRef<T>
impl<T, U> CanTransmuteElement<U> for StaticRef<T>
source§type TransmutedPtr = StaticRef<U>
type TransmutedPtr = StaticRef<U>
source§unsafe fn transmute_element_(self) -> StaticRef<U>
unsafe fn transmute_element_(self) -> StaticRef<U>
source§impl<T> GetPointerKind for StaticRef<T>
impl<T> GetPointerKind for StaticRef<T>
source§impl<T> GetStaticEquivalent_ for StaticRef<T>where
T: __StableAbi,
impl<T> GetStaticEquivalent_ for StaticRef<T>where
T: __StableAbi,
source§type StaticEquivalent = _static_StaticRef<<T as GetStaticEquivalent_>::StaticEquivalent>
type StaticEquivalent = _static_StaticRef<<T as GetStaticEquivalent_>::StaticEquivalent>
'static
equivalent of Self
source§impl<T> Ord for StaticRef<T>where
T: Ord,
impl<T> Ord for StaticRef<T>where
T: Ord,
source§impl<T> PartialOrd for StaticRef<T>where
T: PartialOrd,
impl<T> PartialOrd for StaticRef<T>where
T: PartialOrd,
source§impl<T> StableAbi for StaticRef<T>where
T: __StableAbi,
impl<T> StableAbi for StaticRef<T>where
T: __StableAbi,
source§type IsNonZeroType = <NonNull<T> as StableAbi>::IsNonZeroType
type IsNonZeroType = <NonNull<T> as StableAbi>::IsNonZeroType
source§const LAYOUT: &'static TypeLayout = _
const LAYOUT: &'static TypeLayout = _
source§const ABI_CONSTS: AbiConsts = _
const ABI_CONSTS: AbiConsts = _
const
-equivalents of the associated types.impl<T> Copy for StaticRef<T>
impl<T> Eq for StaticRef<T>where
T: Eq,
impl<'a, T: 'a> Send for StaticRef<T>
impl<'a, T: 'a> Sync for StaticRef<T>
Auto Trait Implementations§
impl<T> Freeze for StaticRef<T>
impl<T> RefUnwindSafe for StaticRef<T>where
T: RefUnwindSafe,
impl<T> Unpin for StaticRef<T>
impl<T> UnwindSafe for StaticRef<T>where
T: RefUnwindSafe,
Blanket Implementations§
source§impl<T> AlignerFor<1> for T
impl<T> AlignerFor<1> for T
source§impl<T> AlignerFor<1024> for T
impl<T> AlignerFor<1024> for T
source§type Aligner = AlignTo1024<T>
type Aligner = AlignTo1024<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<128> for T
impl<T> AlignerFor<128> for T
source§type Aligner = AlignTo128<T>
type Aligner = AlignTo128<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<16> for T
impl<T> AlignerFor<16> for T
source§impl<T> AlignerFor<16384> for T
impl<T> AlignerFor<16384> for T
source§type Aligner = AlignTo16384<T>
type Aligner = AlignTo16384<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<2> for T
impl<T> AlignerFor<2> for T
source§impl<T> AlignerFor<2048> for T
impl<T> AlignerFor<2048> for T
source§type Aligner = AlignTo2048<T>
type Aligner = AlignTo2048<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<256> for T
impl<T> AlignerFor<256> for T
source§type Aligner = AlignTo256<T>
type Aligner = AlignTo256<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<32> for T
impl<T> AlignerFor<32> for T
source§impl<T> AlignerFor<32768> for T
impl<T> AlignerFor<32768> for T
source§type Aligner = AlignTo32768<T>
type Aligner = AlignTo32768<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<4> for T
impl<T> AlignerFor<4> for T
source§impl<T> AlignerFor<4096> for T
impl<T> AlignerFor<4096> for T
source§type Aligner = AlignTo4096<T>
type Aligner = AlignTo4096<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<512> for T
impl<T> AlignerFor<512> for T
source§type Aligner = AlignTo512<T>
type Aligner = AlignTo512<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> AlignerFor<64> for T
impl<T> AlignerFor<64> for T
source§impl<T> AlignerFor<8> for T
impl<T> AlignerFor<8> for T
source§impl<T> AlignerFor<8192> for T
impl<T> AlignerFor<8192> for T
source§type Aligner = AlignTo8192<T>
type Aligner = AlignTo8192<T>
AlignTo*
type which aligns Self
to ALIGNMENT
.source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<T> ImmutableRef for T
impl<T> ImmutableRef for T
source§impl<'a, T> RCowCompatibleRef<'a> for Twhere
T: Clone + 'a,
impl<'a, T> RCowCompatibleRef<'a> for Twhere
T: Clone + 'a,
source§fn as_c_ref(from: &'a T) -> <T as RCowCompatibleRef<'a>>::RefC
fn as_c_ref(from: &'a T) -> <T as RCowCompatibleRef<'a>>::RefC
source§fn as_rust_ref(from: <T as RCowCompatibleRef<'a>>::RefC) -> &'a T
fn as_rust_ref(from: <T as RCowCompatibleRef<'a>>::RefC) -> &'a T
source§impl<S> ROExtAcc for S
impl<S> ROExtAcc for S
source§fn f_get<F>(&self, offset: FieldOffset<S, F, Aligned>) -> &F
fn f_get<F>(&self, offset: FieldOffset<S, F, Aligned>) -> &F
offset
. Read moresource§fn f_get_mut<F>(&mut self, offset: FieldOffset<S, F, Aligned>) -> &mut F
fn f_get_mut<F>(&mut self, offset: FieldOffset<S, F, Aligned>) -> &mut F
offset
. Read moresource§fn f_get_ptr<F, A>(&self, offset: FieldOffset<S, F, A>) -> *const F
fn f_get_ptr<F, A>(&self, offset: FieldOffset<S, F, A>) -> *const F
offset
. Read moresource§fn f_get_mut_ptr<F, A>(&mut self, offset: FieldOffset<S, F, A>) -> *mut F
fn f_get_mut_ptr<F, A>(&mut self, offset: FieldOffset<S, F, A>) -> *mut F
offset
. Read moresource§impl<S> ROExtOps<Aligned> for S
impl<S> ROExtOps<Aligned> for S
source§fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Aligned>, value: F) -> F
fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Aligned>, value: F) -> F
offset
) with value
,
returning the previous value of the field. Read moresource§fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Aligned>) -> Fwhere
F: Copy,
fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Aligned>) -> Fwhere
F: Copy,
source§impl<S> ROExtOps<Unaligned> for S
impl<S> ROExtOps<Unaligned> for S
source§fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Unaligned>, value: F) -> F
fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Unaligned>, value: F) -> F
offset
) with value
,
returning the previous value of the field. Read moresource§fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Unaligned>) -> Fwhere
F: Copy,
fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Unaligned>) -> Fwhere
F: Copy,
source§impl<T> SelfOps for Twhere
T: ?Sized,
impl<T> SelfOps for Twhere
T: ?Sized,
source§fn piped<F, U>(self, f: F) -> U
fn piped<F, U>(self, f: F) -> U
source§fn piped_ref<'a, F, U>(&'a self, f: F) -> Uwhere
F: FnOnce(&'a Self) -> U,
fn piped_ref<'a, F, U>(&'a self, f: F) -> Uwhere
F: FnOnce(&'a Self) -> U,
piped
except that the function takes &Self
Useful for functions that take &Self
instead of Self
. Read moresource§fn piped_mut<'a, F, U>(&'a mut self, f: F) -> Uwhere
F: FnOnce(&'a mut Self) -> U,
fn piped_mut<'a, F, U>(&'a mut self, f: F) -> Uwhere
F: FnOnce(&'a mut Self) -> U,
piped
, except that the function takes &mut Self
.
Useful for functions that take &mut Self
instead of Self
.source§fn mutated<F>(self, f: F) -> Self
fn mutated<F>(self, f: F) -> Self
source§fn observe<F>(self, f: F) -> Self
fn observe<F>(self, f: F) -> Self
source§fn as_ref_<T>(&self) -> &T
fn as_ref_<T>(&self) -> &T
AsRef
,
using the turbofish .as_ref_::<_>()
syntax. Read more