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}