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}