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 SelfSource§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§const LAYOUT: &'static TypeLayout
const LAYOUT: &'static TypeLayout
Source§type IsNonZeroType = <NonNull<T> as StableAbi>::IsNonZeroType
type IsNonZeroType = <NonNull<T> as StableAbi>::IsNonZeroType
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§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
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