abi_stable/pointer_trait.rs
1//! Traits for pointers.
2
3use std::{mem::ManuallyDrop, ptr::NonNull};
4
5use crate::{
6 sabi_types::{MovePtr, RMut, RRef},
7 utils::Transmuter,
8};
9
10#[allow(unused_imports)]
11use core_extensions::utils::transmute_ignore_size;
12
13#[cfg(test)]
14mod tests;
15
16///
17/// Determines whether the referent of a pointer is dropped when the
18/// pointer deallocates the memory.
19///
20/// On Yes, the referent of the pointer is dropped.
21///
22/// On No,the memory the pointer owns is deallocated without calling the destructor
23/// of the referent.
24#[repr(u8)]
25#[derive(Debug, Copy, Clone, PartialEq, Eq, StableAbi)]
26pub enum CallReferentDrop {
27 ///
28 Yes,
29 ///
30 No,
31}
32
33/// Determines whether the pointer is deallocated.
34#[repr(u8)]
35#[derive(Debug, Clone, Copy, PartialEq, Eq, StableAbi)]
36pub enum Deallocate {
37 ///
38 No,
39 ///
40 Yes,
41}
42
43///////////
44
45/// What kind of pointer this is.
46///
47/// # Safety
48///
49/// Each associated item describes their requirements for the implementor.
50///
51///
52pub unsafe trait GetPointerKind: Sized {
53 /// The kind of the pointer.
54 ///
55 /// # Safety for implementor
56 ///
57 /// This is what each kind requires to be used as this associated type:
58 ///
59 /// - [`PK_Reference`]: `Self` must be a `&T`,
60 /// or a `Copy` and `#[repr(transparent)]` wrapper around a raw pointer or reference,
61 /// with `&T` semantics.
62 /// Note that converting into and then back from `&Self::PtrTarget` might
63 /// be a lossy operation for such a type and therefore incorrect.
64 ///
65 /// - [`PK_MutReference`]: `Self` must be a `&mut T`,
66 /// or a non-`Drop` and `#[repr(transparent)]` wrapper around a
67 /// primitive pointer, with `&mut T` semantics.
68 ///
69 /// - [`PK_SmartPointer`]: Any pointer type that's neither of the two other kinds.
70 ///
71 ///
72 /// [`PK_Reference`]: ./struct.PK_Reference.html
73 /// [`PK_MutReference`]: ./struct.PK_MutReference.html
74 /// [`PK_SmartPointer`]: ./struct.PK_SmartPointer.html
75 type Kind: PointerKindVariant;
76
77 /// What this pointer points to.
78 ///
79 /// This is here so that pointers don't *have to* implement `Deref`.
80 ///
81 /// # Safety for implementor
82 ///
83 /// If the type implements `std::ops::Deref` this must be the same as
84 /// `<Self as Deref>::Target`.
85 ///
86 type PtrTarget;
87
88 /// The value-level version of the [`Kind`](#associatedtype.Kind) associated type.
89 ///
90 /// # Safety for implementor
91 ///
92 /// This must not be overriden.
93 const KIND: PointerKind = <Self::Kind as PointerKindVariant>::VALUE;
94}
95
96unsafe impl<'a, T> GetPointerKind for &'a T {
97 type Kind = PK_Reference;
98 type PtrTarget = T;
99}
100
101unsafe impl<'a, T> GetPointerKind for &'a mut T {
102 type Kind = PK_MutReference;
103 type PtrTarget = T;
104}
105
106////////////////////////////////////////////
107
108/// For restricting types to the type-level equivalents of [`PointerKind`] variants.
109///
110/// This trait is sealed, cannot be implemented outside this module,
111/// and won't be implemented for any more types.
112///
113/// [`PointerKind`]: ./enum.PointerKind.html
114pub trait PointerKindVariant: Sealed {
115 /// The value of the PointerKind variant Self is equivalent to.
116 const VALUE: PointerKind;
117}
118
119use self::sealed::Sealed;
120mod sealed {
121 pub trait Sealed {}
122}
123
124/// Describes the kind of a pointer.
125#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, StableAbi)]
126#[repr(u8)]
127pub enum PointerKind {
128 /// A `&T`-like pointer
129 Reference,
130 /// a `&mut T`-like pointer
131 MutReference,
132 /// Any pointer type that's neither of the other variants
133 SmartPointer,
134}
135
136/// The type-level equivalent of [`PointerKind::Reference`].
137///
138/// [`PointerKind::Reference`]: ./enum.PointerKind.html#variant.Reference
139#[allow(non_camel_case_types)]
140pub struct PK_Reference;
141
142/// The type-level equivalent of [`PointerKind::MutReference`].
143///
144/// [`PointerKind::MutReference`]: ./enum.PointerKind.html#variant.MutReference
145#[allow(non_camel_case_types)]
146pub struct PK_MutReference;
147
148/// The type-level equivalent of [`PointerKind::SmartPointer`].
149///
150/// [`PointerKind::SmartPointer`]: ./enum.PointerKind.html#variant.SmartPointer
151#[allow(non_camel_case_types)]
152pub struct PK_SmartPointer;
153
154impl Sealed for PK_Reference {}
155impl Sealed for PK_MutReference {}
156impl Sealed for PK_SmartPointer {}
157
158impl PointerKindVariant for PK_Reference {
159 const VALUE: PointerKind = PointerKind::Reference;
160}
161
162impl PointerKindVariant for PK_MutReference {
163 const VALUE: PointerKind = PointerKind::MutReference;
164}
165
166impl PointerKindVariant for PK_SmartPointer {
167 const VALUE: PointerKind = PointerKind::SmartPointer;
168}
169
170///////////
171
172/// Whether the pointer can be transmuted to an equivalent pointer with `T` as the referent type.
173///
174/// # Safety
175///
176/// Implementors of this trait must ensure that:
177///
178/// - The memory layout of this
179/// type is the same regardless of the type of the referent.
180///
181/// - The pointer type is either `!Drop`(no drop glue either),
182/// or it uses a vtable to Drop the referent and deallocate the memory correctly.
183///
184/// - `transmute_element_` must return a pointer to the same allocation as `self`,
185/// at the same offset,
186/// and with no reduced provenance
187/// (the range of addresses that are valid to dereference with pointers
188/// derived from the returned pointer).
189///
190/// # Example
191///
192/// ```rust
193/// use abi_stable::{
194/// pointer_trait::{
195/// PK_Reference,
196/// AsPtr, CanTransmuteElement, GetPointerKind, TransmuteElement,
197/// },
198/// sabi_types::StaticRef,
199/// std_types::{Tuple2, Tuple4},
200/// };
201///
202/// fn main() {
203/// let reff = FooRef::new(&Tuple4::<u8, u16, u32, u64>(3, 5, 8, 13));
204///
205/// // safety: `Tuple2<u8, u16>` is a compatible prefix of `Tuple4<u8, u16, u32, u64>`
206/// let smaller = unsafe{ reff.transmute_element::<Tuple2<u8, u16>>() };
207/// assert_eq!(smaller.get(), &Tuple2(3u8, 5u16));
208/// }
209///
210///
211/// #[derive(Debug, Copy, Clone)]
212/// #[repr(transparent)]
213/// struct FooRef<T>(StaticRef<T>);
214///
215/// impl<T: 'static> FooRef<T> {
216/// pub const fn new(reff: &'static T) -> Self {
217/// Self(StaticRef::new(reff))
218/// }
219/// pub fn get(self) -> &'static T {
220/// self.0.get()
221/// }
222/// }
223///
224/// unsafe impl<T: 'static> GetPointerKind for FooRef<T> {
225/// type PtrTarget = T;
226/// type Kind = PK_Reference;
227/// }
228///
229/// unsafe impl<T, U> CanTransmuteElement<U> for FooRef<T>
230/// where
231/// T: 'static,
232/// U: 'static,
233/// {
234/// type TransmutedPtr = FooRef<U>;
235///
236/// unsafe fn transmute_element_(self) -> Self::TransmutedPtr {
237/// FooRef(self.0.transmute_element_())
238/// }
239/// }
240///
241/// unsafe impl<T: 'static> AsPtr for FooRef<T> {
242/// fn as_ptr(&self) -> *const T {
243/// self.0.as_ptr()
244/// }
245/// }
246///
247///
248///
249///
250/// ```
251pub unsafe trait CanTransmuteElement<T>: GetPointerKind {
252 /// The type of the pointer after it's element type has been changed.
253 type TransmutedPtr: AsPtr<PtrTarget = T>;
254
255 /// Transmutes the element type of this pointer..
256 ///
257 /// # Safety
258 ///
259 /// Callers must ensure that it is valid to convert from a pointer to `Self::Referent`
260 /// to a pointer to `T` .
261 ///
262 /// For example:
263 ///
264 /// It is undefined behavior to create unaligned references ,
265 /// therefore transmuting from `&u8` to `&u16` is UB
266 /// if the caller does not ensure that the reference is aligned to a multiple of 2 address.
267 ///
268 ///
269 /// # Example
270 ///
271 /// ```
272 /// use abi_stable::{
273 /// pointer_trait::TransmuteElement,
274 /// std_types::RBox,
275 /// };
276 ///
277 /// let signed:RBox<u32>=unsafe{
278 /// RBox::new(1_i32)
279 /// .transmute_element::<u32>()
280 /// };
281 ///
282 /// ```
283 unsafe fn transmute_element_(self) -> Self::TransmutedPtr;
284}
285
286/// Allows transmuting pointers to point to a different type.
287pub trait TransmuteElement {
288 /// Transmutes the element type of this pointer..
289 ///
290 /// # Safety
291 ///
292 /// Callers must ensure that it is valid to convert from a pointer to `Self::PtrTarget`
293 /// to a pointer to `T`, and then use the pointed-to data.
294 ///
295 /// For example:
296 ///
297 /// It is undefined behavior to create unaligned references ,
298 /// therefore transmuting from `&u8` to `&u16` is UB
299 /// if the caller does not ensure that the reference is aligned to a multiple of 2 address.
300 ///
301 ///
302 /// # Example
303 ///
304 /// ```
305 /// use abi_stable::{
306 /// pointer_trait::TransmuteElement,
307 /// std_types::RBox,
308 /// };
309 ///
310 /// let signed:RBox<u32>=unsafe{
311 /// RBox::new(1_i32)
312 /// .transmute_element::<u32>()
313 /// };
314 ///
315 /// ```
316 #[inline(always)]
317 unsafe fn transmute_element<T>(self) -> <Self as CanTransmuteElement<T>>::TransmutedPtr
318 where
319 Self: CanTransmuteElement<T>,
320 {
321 unsafe { self.transmute_element_() }
322 }
323}
324
325impl<This: ?Sized> TransmuteElement for This {}
326
327///////////
328
329unsafe impl<'a, T: 'a, O: 'a> CanTransmuteElement<O> for &'a T {
330 type TransmutedPtr = RRef<'a, O>;
331
332 unsafe fn transmute_element_(self) -> Self::TransmutedPtr {
333 unsafe { RRef::from_raw(self as *const T as *const O) }
334 }
335}
336
337///////////
338
339unsafe impl<'a, T: 'a, O: 'a> CanTransmuteElement<O> for &'a mut T {
340 type TransmutedPtr = RMut<'a, O>;
341
342 unsafe fn transmute_element_(self) -> Self::TransmutedPtr {
343 unsafe { RMut::from_raw(self as *mut T as *mut O) }
344 }
345}
346
347///////////////////////////////////////////////////////////////////////////////
348
349/// For getting a const raw pointer to the value that this points to.
350///
351/// # Safety
352///
353/// The implementor of this trait must return a pointer to the same data as
354/// `Deref::deref`, without constructing a `&Self::Target` in `as_ptr`
355/// (or any function it calls),
356///
357/// The implementor of this trait must not override the defaulted methods.
358///
359/// # Example
360///
361/// ```rust
362/// use abi_stable::{
363/// erased_types::interfaces::DebugDefEqInterface,
364/// pointer_trait::{
365/// PK_Reference,
366/// AsPtr, CanTransmuteElement, GetPointerKind, TransmuteElement,
367/// },
368/// sabi_types::StaticRef,
369/// DynTrait,
370/// };
371///
372/// fn main() {
373/// let reff: DynTrait<BarRef<()>, DebugDefEqInterface> =
374/// DynTrait::from_ptr(BarRef::new(&1234i32));
375///
376/// assert_eq!(format!("{:?}", reff), "1234");
377/// }
378///
379///
380/// #[derive(Debug, Copy, Clone)]
381/// #[repr(transparent)]
382/// struct BarRef<T>(StaticRef<T>);
383///
384/// impl<T: 'static> BarRef<T> {
385/// pub const fn new(reff: &'static T) -> Self {
386/// Self(StaticRef::new(reff))
387/// }
388/// }
389///
390/// unsafe impl<T: 'static> GetPointerKind for BarRef<T> {
391/// type PtrTarget = T;
392/// type Kind = PK_Reference;
393/// }
394///
395/// unsafe impl<T, U> CanTransmuteElement<U> for BarRef<T>
396/// where
397/// T: 'static,
398/// U: 'static,
399/// {
400/// type TransmutedPtr = BarRef<U>;
401///
402/// unsafe fn transmute_element_(self) -> Self::TransmutedPtr {
403/// BarRef(self.0.transmute_element_())
404/// }
405/// }
406///
407/// unsafe impl<T: 'static> AsPtr for BarRef<T> {
408/// fn as_ptr(&self) -> *const T {
409/// self.0.as_ptr()
410/// }
411/// }
412///
413///
414/// ```
415pub unsafe trait AsPtr: GetPointerKind {
416 /// Gets a const raw pointer to the value that this points to.
417 fn as_ptr(&self) -> *const Self::PtrTarget;
418
419 /// Converts this pointer to an `RRef`.
420 #[inline(always)]
421 fn as_rref(&self) -> RRef<'_, Self::PtrTarget> {
422 unsafe { RRef::from_raw(self.as_ptr()) }
423 }
424}
425
426/// For getting a mutable raw pointer to the value that this points to.
427///
428/// # Safety
429///
430/// The implementor of this trait must return a pointer to the same data as
431/// `DerefMut::deref_mut`,
432/// without constructing a `&mut Self::Target` in `as_mut_ptr`
433/// (or any function it calls).
434///
435/// The implementor of this trait must not override the defaulted methods.
436///
437/// # Example
438///
439/// ```rust
440/// use abi_stable::{
441/// erased_types::interfaces::DEIteratorInterface,
442/// pointer_trait::{
443/// PK_MutReference,
444/// AsPtr, AsMutPtr, CanTransmuteElement, GetPointerKind, TransmuteElement,
445/// },
446/// sabi_types::RMut,
447/// DynTrait,
448/// };
449///
450/// fn main() {
451/// let mut iter = 0..=5;
452/// let reff: DynTrait<QuxMut<()>, DEIteratorInterface<_>> =
453/// DynTrait::from_ptr(QuxMut::new(&mut iter)).interface(DEIteratorInterface::NEW);
454///
455/// assert_eq!(reff.collect::<Vec<u32>>(), [0, 1, 2, 3, 4, 5]);
456///
457/// assert_eq!(iter.next(), None);
458/// }
459///
460///
461/// #[derive(Debug)]
462/// #[repr(transparent)]
463/// struct QuxMut<'a, T>(RMut<'a, T>);
464///
465/// impl<'a, T> QuxMut<'a, T> {
466/// pub fn new(reff: &'a mut T) -> Self {
467/// Self(RMut::new(reff))
468/// }
469/// }
470///
471/// unsafe impl<T> GetPointerKind for QuxMut<'_, T> {
472/// type PtrTarget = T;
473/// type Kind = PK_MutReference;
474/// }
475///
476/// unsafe impl<'a, T: 'a, U: 'a> CanTransmuteElement<U> for QuxMut<'a, T> {
477/// type TransmutedPtr = QuxMut<'a, U>;
478///
479/// unsafe fn transmute_element_(self) -> Self::TransmutedPtr {
480/// QuxMut(self.0.transmute_element_())
481/// }
482/// }
483///
484/// unsafe impl<T> AsPtr for QuxMut<'_, T> {
485/// fn as_ptr(&self) -> *const T {
486/// self.0.as_ptr()
487/// }
488/// }
489///
490/// unsafe impl<T> AsMutPtr for QuxMut<'_, T> {
491/// fn as_mut_ptr(&mut self) -> *mut T {
492/// self.0.as_mut_ptr()
493/// }
494/// }
495///
496///
497/// ```
498pub unsafe trait AsMutPtr: AsPtr {
499 /// Gets a mutable raw pointer to the value that this points to.
500 fn as_mut_ptr(&mut self) -> *mut Self::PtrTarget;
501
502 /// Converts this pointer to an `RRef`.
503 #[inline(always)]
504 fn as_rmut(&mut self) -> RMut<'_, Self::PtrTarget> {
505 unsafe { RMut::from_raw(self.as_mut_ptr()) }
506 }
507}
508
509///////////////////////////////////////////////////////////////////////////////
510
511/// For owned pointers, allows extracting their contents separate from deallocating them.
512///
513/// # Safety
514///
515/// Implementors must:
516///
517/// - Implement this trait such that `get_move_ptr` can be called before `drop_allocation`.
518///
519/// - Not override `with_move_ptr`
520///
521/// - Not override `in_move_ptr`
522///
523/// # Example
524///
525/// Implementing this trait for a Box-like type.
526///
527/// ```rust
528/// use abi_stable::{
529/// pointer_trait::{
530/// CallReferentDrop, PK_SmartPointer,
531/// GetPointerKind, AsPtr, AsMutPtr, OwnedPointer,
532/// },
533/// sabi_types::MovePtr,
534/// std_types::RString,
535/// StableAbi,
536/// };
537///
538/// use std::{
539/// alloc::{self, Layout},
540/// marker::PhantomData,
541/// mem::ManuallyDrop,
542/// };
543///
544///
545/// fn main(){
546/// let this = BoxLike::new(RString::from("12345"));
547///
548/// let string: RString = this.in_move_ptr(|x: MovePtr<'_, RString>|{
549/// MovePtr::into_inner(x)
550/// });
551///
552/// assert_eq!(string, "12345");
553/// }
554///
555///
556/// #[repr(C)]
557/// #[derive(StableAbi)]
558/// pub struct BoxLike<T> {
559/// ptr: *mut T,
560///
561/// dropper: unsafe extern "C" fn(*mut T, CallReferentDrop),
562///
563/// _marker: PhantomData<T>,
564/// }
565///
566///
567/// impl<T> BoxLike<T>{
568/// pub fn new(value:T)->Self{
569/// let box_ = Box::new(value);
570///
571/// Self{
572/// ptr: Box::into_raw(box_),
573/// dropper: destroy_box::<T>,
574/// _marker:PhantomData,
575/// }
576/// }
577/// }
578///
579/// unsafe impl<T> GetPointerKind for BoxLike<T> {
580/// type PtrTarget = T;
581/// type Kind = PK_SmartPointer;
582/// }
583///
584/// unsafe impl<T> AsPtr for BoxLike<T> {
585/// fn as_ptr(&self) -> *const T {
586/// self.ptr
587/// }
588/// }
589///
590/// unsafe impl<T> AsMutPtr for BoxLike<T> {
591/// fn as_mut_ptr(&mut self) -> *mut T {
592/// self.ptr
593/// }
594/// }
595///
596/// unsafe impl<T> OwnedPointer for BoxLike<T> {
597/// unsafe fn get_move_ptr(this: &mut ManuallyDrop<Self>) -> MovePtr<'_,Self::PtrTarget>{
598/// MovePtr::from_raw(this.ptr)
599/// }
600///
601/// unsafe fn drop_allocation(this: &mut ManuallyDrop<Self>) {
602/// unsafe{
603/// (this.dropper)(this.ptr, CallReferentDrop::No)
604/// }
605/// }
606/// }
607///
608/// impl<T> Drop for BoxLike<T>{
609/// fn drop(&mut self){
610/// unsafe{
611/// (self.dropper)(self.ptr, CallReferentDrop::Yes)
612/// }
613/// }
614/// }
615///
616/// unsafe extern "C" fn destroy_box<T>(v: *mut T, call_drop: CallReferentDrop) {
617/// abi_stable::extern_fn_panic_handling! {
618/// let mut box_ = Box::from_raw(v as *mut ManuallyDrop<T>);
619/// if call_drop == CallReferentDrop::Yes {
620/// ManuallyDrop::drop(&mut *box_);
621/// }
622/// drop(box_);
623/// }
624/// }
625///
626///
627/// ```
628pub unsafe trait OwnedPointer: Sized + AsMutPtr + GetPointerKind {
629 /// Gets a move pointer to the contents of this pointer.
630 ///
631 /// # Safety
632 ///
633 /// This function logically moves the owned contents out of this pointer,
634 /// the only safe thing that can be done with the pointer afterwads
635 /// is to call `OwnedPointer::drop_allocation`.
636 ///
637 /// <span id="get_move_ptr-example"></span>
638 /// # Example
639 ///
640 /// ```rust
641 /// use abi_stable::{
642 /// pointer_trait::OwnedPointer,
643 /// sabi_types::MovePtr,
644 /// std_types::{RBox, RVec},
645 /// rvec, StableAbi,
646 /// };
647 ///
648 /// use std::mem::ManuallyDrop;
649 ///
650 /// let mut this = ManuallyDrop::new(RBox::new(rvec![3, 5, 8]));
651 ///
652 /// // safety:
653 /// // this is only called once,
654 /// // and the `RVec` is never accessed again through the `RBox`.
655 /// let moveptr: MovePtr<'_, RVec<u8>> = unsafe { OwnedPointer::get_move_ptr(&mut this) };
656 ///
657 /// let vector: RVec<u8> = MovePtr::into_inner(moveptr);
658 ///
659 /// // safety: this is only called once, after all uses of `this`
660 /// unsafe{ OwnedPointer::drop_allocation(&mut this); }
661 ///
662 /// assert_eq!(vector[..], [3, 5, 8]);
663 ///
664 /// ```
665 unsafe fn get_move_ptr(this: &mut ManuallyDrop<Self>) -> MovePtr<'_, Self::PtrTarget>;
666
667 /// Deallocates the pointer without dropping its owned contents.
668 ///
669 /// Note that if `Self::get_move_ptr` has not been called this will
670 /// leak the values owned by the referent of the pointer.
671 ///
672 /// # Safety
673 ///
674 /// This method must only be called once,
675 /// since it'll deallocate whatever memory this pointer owns.
676 ///
677 /// # Example
678 ///
679 /// [`get_move_ptr` has an example](#get_move_ptr-example) that uses both that function
680 /// and this one.
681 unsafe fn drop_allocation(this: &mut ManuallyDrop<Self>);
682
683 /// Runs a callback with the contents of this pointer, and then deallocates it.
684 ///
685 /// The pointer is deallocated even in the case that `func` panics
686 ///
687 /// # Example
688 ///
689 /// ```rust
690 /// use abi_stable::{
691 /// pointer_trait::OwnedPointer,
692 /// sabi_types::MovePtr,
693 /// std_types::{RBox, RCow, RCowSlice},
694 /// };
695 ///
696 /// use std::mem::ManuallyDrop;
697 ///
698 /// let this = ManuallyDrop::new(RBox::new(RCow::from_slice(&[13, 21, 34])));
699 ///
700 /// let cow: RCowSlice<'static, u8> = OwnedPointer::with_move_ptr(this, |moveptr|{
701 /// MovePtr::into_inner(moveptr)
702 /// });
703 ///
704 /// assert_eq!(cow[..], [13, 21, 34]);
705 ///
706 /// ```
707 #[inline]
708 fn with_move_ptr<F, R>(mut this: ManuallyDrop<Self>, func: F) -> R
709 where
710 F: FnOnce(MovePtr<'_, Self::PtrTarget>) -> R,
711 {
712 unsafe {
713 let guard = DropAllocationMutGuard(&mut this);
714 func(Self::get_move_ptr(guard.0))
715 }
716 }
717
718 /// Runs a callback with the contents of this pointer, and then deallocates it.
719 ///
720 /// The pointer is deallocated even in the case that `func` panics
721 ///
722 /// # Example
723 ///
724 /// ```rust
725 /// use abi_stable::{
726 /// pointer_trait::OwnedPointer,
727 /// sabi_types::MovePtr,
728 /// std_types::RBox,
729 /// };
730 ///
731 /// let this = RBox::new(Foo(41));
732 ///
733 /// let cow: Foo = this.in_move_ptr(|moveptr| MovePtr::into_inner(moveptr) );
734 ///
735 /// assert_eq!(cow, Foo(41));
736 ///
737 ///
738 /// #[derive(Debug, PartialEq)]
739 /// struct Foo(u32);
740 ///
741 /// ```
742 #[inline]
743 fn in_move_ptr<F, R>(self, func: F) -> R
744 where
745 F: FnOnce(MovePtr<'_, Self::PtrTarget>) -> R,
746 {
747 unsafe {
748 let mut guard = DropAllocationGuard(ManuallyDrop::new(self));
749 func(Self::get_move_ptr(&mut guard.0))
750 }
751 }
752}
753
754struct DropAllocationGuard<T: OwnedPointer>(ManuallyDrop<T>);
755
756impl<T: OwnedPointer> Drop for DropAllocationGuard<T> {
757 #[inline(always)]
758 fn drop(&mut self) {
759 unsafe { T::drop_allocation(&mut self.0) }
760 }
761}
762
763struct DropAllocationMutGuard<'a, T: OwnedPointer>(&'a mut ManuallyDrop<T>);
764
765impl<T: OwnedPointer> Drop for DropAllocationMutGuard<'_, T> {
766 #[inline(always)]
767 fn drop(&mut self) {
768 unsafe { T::drop_allocation(self.0) }
769 }
770}
771
772///////////////////////////////////////////////////////////////////////////////
773
774/// Trait for non-owning pointers that are shared-reference-like.
775///
776/// # Safety
777///
778/// As implied by `GetPointerKind<Kind = PK_Reference>`,
779/// implementors must be `#[repr(transparent)]` wrappers around references,
780/// and semantically act like references.
781pub unsafe trait ImmutableRef: Copy + GetPointerKind<Kind = PK_Reference> {
782 /// Converts this pointer to a `NonNull`.
783 #[inline(always)]
784 fn to_nonnull(self) -> NonNull<Self::PtrTarget> {
785 unsafe { Transmuter { from: self }.to }
786 }
787
788 /// Constructs this pointer from a `NonNull`.
789 ///
790 /// # Safety
791 ///
792 /// `from` must be a non-dangling pointer from a call to `to_nonnull` or
793 /// `to_raw_ptr` on an instance of `Self` or a compatible pointer type.
794 ///
795 ///
796 #[inline(always)]
797 unsafe fn from_nonnull(from: NonNull<Self::PtrTarget>) -> Self {
798 unsafe { Transmuter { from }.to }
799 }
800
801 /// Converts this pointer to a raw pointer.
802 #[inline(always)]
803 fn to_raw_ptr(self) -> *const Self::PtrTarget {
804 unsafe { Transmuter { from: self }.to }
805 }
806
807 /// Constructs this pointer from a raw pointer.
808 ///
809 /// # Safety
810 ///
811 /// This has the same safety requirements as [`from_nonnull`](Self::from_nonnull),
812 /// with the exception that null pointers are allowed.
813 ///
814 #[inline(always)]
815 unsafe fn from_raw_ptr(from: *const Self::PtrTarget) -> Option<Self> {
816 unsafe { Transmuter { from }.to }
817 }
818}
819
820unsafe impl<T> ImmutableRef for T where T: Copy + GetPointerKind<Kind = PK_Reference> {}
821
822/// `const` equivalents of [`ImmutableRef`] methods.
823pub mod immutable_ref {
824 use super::*;
825
826 use crate::utils::const_transmute;
827
828 /// Converts the `from` pointer to a `NonNull`.
829 ///
830 /// # Example
831 ///
832 /// ```rust
833 /// use abi_stable::pointer_trait::immutable_ref;
834 ///
835 /// use std::ptr::NonNull;
836 ///
837 /// const X: NonNull<i8> = immutable_ref::to_nonnull(&3i8);
838 /// unsafe {
839 /// assert_eq!(*X.as_ref(), 3i8);
840 /// }
841 /// ```
842 ///
843 pub const fn to_nonnull<T>(from: T) -> NonNull<T::PtrTarget>
844 where
845 T: GetPointerKind<Kind = PK_Reference>,
846 {
847 unsafe { const_transmute!(T, NonNull<T::PtrTarget>, from) }
848 }
849
850 /// Constructs this pointer from a `NonNull`.
851 ///
852 /// # Safety
853 ///
854 /// `from` must be a non-dangling pointer from a call to `to_nonnull` or
855 /// `to_raw_ptr` on an instance of `T` or a compatible pointer type.
856 ///
857 /// # Example
858 ///
859 /// ```rust
860 /// use abi_stable::pointer_trait::immutable_ref;
861 ///
862 /// const X: &u32 = unsafe {
863 /// let nn = abi_stable::utils::ref_as_nonnull(&5u32);
864 /// immutable_ref::from_nonnull(nn)
865 /// };
866 /// assert_eq!(*X, 5u32);
867 /// ```
868 ///
869 pub const unsafe fn from_nonnull<T>(from: NonNull<T::PtrTarget>) -> T
870 where
871 T: GetPointerKind<Kind = PK_Reference>,
872 {
873 unsafe { const_transmute!(NonNull<T::PtrTarget>, T, from) }
874 }
875
876 /// Converts the `from` pointer to a raw pointer.
877 ///
878 /// # Example
879 ///
880 /// ```rust
881 /// use abi_stable::pointer_trait::immutable_ref;
882 ///
883 /// unsafe {
884 /// const X: *const u32 = immutable_ref::to_raw_ptr(&8u32);
885 /// assert_eq!(*X, 8u32);
886 /// }
887 /// ```
888 ///
889 pub const fn to_raw_ptr<T>(from: T) -> *const T::PtrTarget
890 where
891 T: GetPointerKind<Kind = PK_Reference>,
892 {
893 unsafe { const_transmute!(T, *const T::PtrTarget, from) }
894 }
895
896 /// Converts a raw pointer to an `T` pointer.
897 ///
898 /// # Safety
899 ///
900 /// This has the same safety requirements as [`from_nonnull`],
901 /// with the exception that null pointers are allowed.
902 ///
903 /// # Example
904 ///
905 /// ```rust
906 /// use abi_stable::pointer_trait::immutable_ref;
907 ///
908 /// unsafe {
909 /// const X: Option<&u8> = unsafe {
910 /// immutable_ref::from_raw_ptr(&13u8 as *const u8)
911 /// };
912 /// assert_eq!(*X.unwrap(), 13u8);
913 /// }
914 /// ```
915 ///
916 pub const unsafe fn from_raw_ptr<T>(from: *const T::PtrTarget) -> Option<T>
917 where
918 T: GetPointerKind<Kind = PK_Reference>,
919 {
920 unsafe { const_transmute!(*const T::PtrTarget, Option<T>, from) }
921 }
922}