Skip to main content

design/
boxed.rs

1use std::{
2    alloc::{
3        Layout,
4        dealloc,
5    },
6    marker::PhantomCovariant,
7    ptr::NonNull,
8};
9
10use crate::{
11    ops::place::{
12        BorrowPlace,
13        CreateHandle,
14        DropHusk,
15        DropPlace,
16        MovePlace,
17        PlaceHandle,
18        PlaceProxy,
19        ProjectPlace,
20        ReadPlace,
21        WritePlace,
22        borrowck::{
23            AccessKind,
24            Instant,
25            Lifetime,
26        },
27    },
28    place::Subplace,
29};
30
31pub struct BoxHandle<T: ?Sized> {
32    ptr: NonNull<T>,
33    _variance: PhantomCovariant<T>,
34}
35
36impl<T: ?Sized> PlaceProxy for Box<T> {
37    type Target = T;
38}
39
40unsafe impl<T: ?Sized> CreateHandle<Instant> for Box<T> {
41    type Handle = BoxHandle<T>;
42    const ACCESS: AccessKind = AccessKind::Shared;
43
44    unsafe fn handle_from_raw(this: *const Self) -> Self::Handle {
45        let this: *const NonNull<T> = this.cast();
46        BoxHandle {
47            ptr: unsafe { *this },
48            _variance: PhantomCovariant::new(),
49        }
50    }
51}
52
53impl<T: ?Sized> PlaceHandle for BoxHandle<T> {
54    type Target = T;
55}
56
57unsafe impl<S: Subplace> ProjectPlace<S> for BoxHandle<S::Source> {
58    type Projected = BoxHandle<S::Target>;
59
60    unsafe fn project_place(self, subplace: S) -> Self::Projected {
61        BoxHandle {
62            ptr: unsafe { self.ptr.project_place(subplace) },
63            _variance: PhantomCovariant::new(),
64        }
65    }
66}
67
68unsafe impl<T> WritePlace for BoxHandle<T> {
69    const ACCESS: AccessKind = AccessKind::Exclusive;
70    const SAFE: bool = true;
71
72    unsafe fn write_place(self, value: Self::Target) {
73        unsafe { self.ptr.write(value) }
74    }
75}
76
77unsafe impl<T> ReadPlace for BoxHandle<T> {
78    const ACCESS: AccessKind = AccessKind::Shared;
79    const SAFE: bool = true;
80
81    unsafe fn read_place(self) -> Self::Target {
82        unsafe { self.ptr.read() }
83    }
84}
85
86unsafe impl<T> MovePlace for BoxHandle<T> {}
87
88unsafe impl<T> DropPlace for BoxHandle<T> {
89    unsafe fn drop_place(self) {
90        unsafe { self.ptr.drop_in_place() };
91    }
92}
93
94unsafe impl<T: ?Sized> DropHusk for Box<T> {
95    unsafe fn drop_husk(this: *mut Self) {
96        let ptr: *mut NonNull<T> = this.cast();
97        let ptr = unsafe { *ptr };
98        let layout = unsafe { Layout::for_value_raw(ptr.as_ptr()) };
99        unsafe { dealloc(ptr.as_ptr().cast(), layout) };
100    }
101}
102
103unsafe impl<'a, T: ?Sized> BorrowPlace<&'a mut T> for BoxHandle<T> {
104    const ACCESS: AccessKind = AccessKind::Exclusive;
105    type Timing = Lifetime<'a>;
106    const SAFE: bool = true;
107
108    unsafe fn borrow(mut self) -> &'a mut T {
109        unsafe { self.ptr.as_mut() }
110    }
111}