mbox/
free.rs

1//! Trait to instruct how to properly drop and free pointers.
2
3use std::ptr::{drop_in_place, NonNull};
4
5use crate::internal::gen_free;
6
7/// Implemented for pointers which can be freed.
8pub trait Free {
9    /// Drops the content pointed by this pointer and frees it.
10    ///
11    /// # Safety
12    ///
13    /// The `ptr` must be allocated through `malloc()`.
14    ///
15    /// Do not call this method if the pointer has been freed. Users of this trait should maintain a
16    /// flag to track if the pointer has been freed or not (the Rust compiler will automatically do
17    /// this with a `Drop` type).
18    unsafe fn free(ptr: NonNull<Self>);
19}
20
21/// Drops the content of `*ptr`, then frees the `ptr` itself.
22unsafe fn free_ptr_ref<T>(ptr: NonNull<T>) {
23    drop_in_place(ptr.as_ptr());
24    gen_free(ptr);
25}
26
27impl<T> Free for T {
28    #[cfg(feature = "nightly")]
29    default unsafe fn free(ptr_ref: NonNull<Self>) {
30        free_ptr_ref(ptr_ref);
31    }
32
33    #[cfg(not(feature = "nightly"))]
34    unsafe fn free(ptr_ref: NonNull<Self>) {
35        free_ptr_ref(ptr_ref);
36    }
37}
38
39impl<T> Free for [T] {
40    unsafe fn free(fat_ptr: NonNull<Self>) {
41        let fat_ptr = fat_ptr.as_ptr();
42        drop_in_place(fat_ptr);
43        gen_free(NonNull::new_unchecked(fat_ptr as *mut T));
44    }
45}
46
47impl Free for str {
48    unsafe fn free(fat_ptr: NonNull<Self>) {
49        Free::free(NonNull::new_unchecked(fat_ptr.as_ptr() as *mut [u8]));
50    }
51}