1use std::{
2 mem::{
3 self,
4 ManuallyDrop,
5 },
6 pin::Pin,
7};
8
9use crate::{
10 ops::place::{
11 BorrowPlace,
12 CreateHandle,
13 DerefPlace,
14 DropHusk,
15 DropPlace,
16 MovePlace,
17 PlaceHandle,
18 PlaceProxy,
19 ProjectPlace,
20 ReadMetadata,
21 ReadPlace,
22 WritePlace,
23 borrowck::{
24 AccessKind,
25 Timing,
26 },
27 },
28 place::Subplace,
29 ptr::Metadata,
30};
31
32impl<P> PlaceProxy for Pin<P>
33where
34 P: PlaceProxy,
35{
36 type Target = P::Target;
37}
38
39unsafe impl<ProxyTiming, P> CreateHandle<ProxyTiming> for Pin<P>
40where
41 ProxyTiming: Timing,
42 P: CreateHandle<ProxyTiming>,
43{
44 type Handle = PinnedHandle<P::Handle>;
45
46 const ACCESS: AccessKind = P::ACCESS;
47
48 unsafe fn handle_from_raw(this: *const Self) -> Self::Handle {
49 let ptr: *const Pin<P> = this;
50 let ptr: *const P = ptr.cast();
51 let handle = unsafe { P::handle_from_raw(ptr) };
52 PinnedHandle(handle)
53 }
54}
55
56pub struct PinnedHandle<H>(H);
57
58impl<H> PinnedHandle<H> {
59 pub unsafe fn new_unchecked(handle: H) -> Self {
60 Self(handle)
61 }
62}
63
64impl<H> PlaceHandle for PinnedHandle<H>
65where
66 H: PlaceHandle,
67{
68 type Target = H::Target;
69}
70
71unsafe impl<H> ReadPlace for PinnedHandle<H>
72where
73 H: ReadPlace,
74 H::Target: Sized + Unpin,
75{
76 const ACCESS: AccessKind = H::ACCESS;
77 const SAFE: bool = H::SAFE;
78
79 unsafe fn read_place(self) -> Self::Target {
80 unsafe { self.0.read_place() }
81 }
82}
83
84unsafe impl<H> ReadMetadata for PinnedHandle<H>
85where
86 H: ReadMetadata,
87{
88 fn metadata(self) -> Metadata<Self::Target> {
89 self.0.metadata()
90 }
91}
92
93unsafe impl<H> MovePlace for PinnedHandle<H>
94where
95 H: MovePlace,
96 H::Target: Sized + Unpin,
97{
98}
99
100unsafe impl<H> WritePlace for PinnedHandle<H>
101where
102 H: WritePlace,
103 H::Target: Sized,
104{
105 const ACCESS: AccessKind = H::ACCESS;
106 const SAFE: bool = H::SAFE;
107
108 unsafe fn write_place(self, value: Self::Target) {
109 unsafe { self.0.write_place(value) }
110 }
111}
112
113unsafe impl<H> DropPlace for PinnedHandle<H>
114where
115 H: DropPlace,
116{
117 unsafe fn drop_place(self) {
118 unsafe { self.0.drop_place() };
119 }
120}
121
122unsafe impl<P> DropHusk for Pin<P>
123where
124 P: DropHusk,
125{
126 unsafe fn drop_husk(this: *mut Self) {
127 unsafe { P::drop_husk(this.cast()) }
129 }
130}
131
132pub unsafe trait PinnableSubplace: Subplace {
133 type StructualPinning<H: PlaceHandle<Target = Self::Target>>: PlaceHandle<
139 Target = Self::Target,
140 >;
141
142 unsafe fn from_pinned<H: PlaceHandle<Target = Self::Target>>(
147 handle: H,
148 ) -> Self::StructualPinning<H>;
149}
150
151unsafe impl<H, S> ProjectPlace<S> for PinnedHandle<H>
152where
153 H: ProjectPlace<S>,
154 S: PinnableSubplace<Source = H::Target>,
155{
156 type Projected = S::StructualPinning<H::Projected>;
157
158 unsafe fn project_place(self, subplace: S) -> Self::Projected {
159 let handle = unsafe { self.0.project_place(subplace) };
160 unsafe { S::from_pinned(handle) }
161 }
162}
163
164unsafe impl<H, PointeeTiming, PointerTiming>
167 DerefPlace<PointeeTiming, PointerTiming> for PinnedHandle<H>
168where
169 Self::Target: CreateHandle<PointeeTiming>,
170 H: DerefPlace<PointeeTiming, PointerTiming>,
171 PointeeTiming: Timing,
172 PointerTiming: Timing,
173{
174 const POINTEE_ACCESS: AccessKind = H::POINTEE_ACCESS;
175 const POINTER_ACCESS: AccessKind = H::POINTER_ACCESS;
176 const SAFE: bool = H::SAFE;
177
178 unsafe fn deref_place(
179 self,
180 ) -> <Self::Target as CreateHandle<PointeeTiming>>::Handle {
181 let handle = unsafe { self.0.deref_place() };
182 handle
183 }
184}
185
186unsafe impl<H, Output> BorrowPlace<Pin<Output>> for PinnedHandle<H>
187where
188 H: BorrowPlace<Output>,
189{
190 const ACCESS: AccessKind = H::ACCESS;
191 type Timing = H::Timing;
192 const SAFE: bool = H::SAFE;
193
194 unsafe fn borrow(self) -> Pin<Output> {
195 unsafe { new_pin_unchecked(self.0.borrow()) }
196 }
197}
198
199unsafe fn new_pin_unchecked<T>(t: T) -> Pin<T> {
200 let t = ManuallyDrop::new(t);
201 unsafe { mem::transmute_copy::<T, Pin<T>>(&t) }
203}