core/future/
async_drop.rs1#![unstable(feature = "async_drop", issue = "126482")]
2
3use crate::fmt;
4use crate::future::{Future, IntoFuture};
5use crate::intrinsics::discriminant_value;
6use crate::marker::{DiscriminantKind, PhantomPinned};
7use crate::mem::MaybeUninit;
8use crate::pin::Pin;
9use crate::task::{Context, Poll, ready};
10
11#[unstable(feature = "async_drop", issue = "126482")]
14pub fn async_drop<T>(value: T) -> AsyncDropOwning<T> {
15 AsyncDropOwning { value: MaybeUninit::new(value), dtor: None, _pinned: PhantomPinned }
16}
17
18#[unstable(feature = "async_drop", issue = "126482")]
20pub struct AsyncDropOwning<T> {
21 value: MaybeUninit<T>,
22 dtor: Option<AsyncDropInPlace<T>>,
23 _pinned: PhantomPinned,
24}
25
26#[unstable(feature = "async_drop", issue = "126482")]
27impl<T> fmt::Debug for AsyncDropOwning<T> {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 f.debug_struct("AsyncDropOwning").finish_non_exhaustive()
30 }
31}
32
33#[unstable(feature = "async_drop", issue = "126482")]
34impl<T> Future for AsyncDropOwning<T> {
35 type Output = ();
36
37 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
38 unsafe {
40 let this = self.get_unchecked_mut();
41 let dtor = Pin::new_unchecked(
42 this.dtor.get_or_insert_with(|| async_drop_in_place(this.value.as_mut_ptr())),
43 );
44 dtor.poll(cx)
46 }
47 }
48}
49
50#[lang = "async_drop_in_place"]
51#[allow(unconditional_recursion)]
52unsafe fn async_drop_in_place_raw<T: ?Sized>(
54 to_drop: *mut T,
55) -> <T as AsyncDestruct>::AsyncDestructor {
56 unsafe { async_drop_in_place_raw(to_drop) }
61}
62
63#[unstable(feature = "async_drop", issue = "126482")]
90pub unsafe fn async_drop_in_place<T: ?Sized>(to_drop: *mut T) -> AsyncDropInPlace<T> {
91 unsafe { AsyncDropInPlace(async_drop_in_place_raw(to_drop)) }
93}
94
95#[unstable(feature = "async_drop", issue = "126482")]
97pub struct AsyncDropInPlace<T: ?Sized>(<T as AsyncDestruct>::AsyncDestructor);
98
99#[unstable(feature = "async_drop", issue = "126482")]
100impl<T: ?Sized> fmt::Debug for AsyncDropInPlace<T> {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 f.debug_struct("AsyncDropInPlace").finish_non_exhaustive()
103 }
104}
105
106#[unstable(feature = "async_drop", issue = "126482")]
107impl<T: ?Sized> Future for AsyncDropInPlace<T> {
108 type Output = ();
109
110 #[inline(always)]
111 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
112 unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().0) }.poll(cx)
114 }
115}
116
117#[unstable(feature = "async_drop", issue = "126482")]
121#[lang = "async_drop"]
122pub trait AsyncDrop {
123 #[unstable(feature = "async_drop", issue = "126482")]
126 type Dropper<'a>: Future<Output = ()>
127 where
128 Self: 'a;
129
130 #[unstable(feature = "async_drop", issue = "126482")]
132 fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_>;
133}
134
135#[lang = "async_destruct"]
136#[rustc_deny_explicit_impl]
137#[rustc_do_not_implement_via_object]
138trait AsyncDestruct {
139 type AsyncDestructor: Future<Output = ()>;
140}
141
142#[lang = "surface_async_drop_in_place"]
145async unsafe fn surface_async_drop_in_place<T: AsyncDrop + ?Sized>(ptr: *mut T) {
146 unsafe { <T as AsyncDrop>::async_drop(Pin::new_unchecked(&mut *ptr)).await }
149}
150
151#[allow(drop_bounds)]
154#[lang = "async_drop_surface_drop_in_place"]
155async unsafe fn surface_drop_in_place<T: Drop + ?Sized>(ptr: *mut T) {
156 unsafe { crate::ops::fallback_surface_drop(&mut *ptr) }
159}
160
161struct Fuse<T> {
171 inner: Option<T>,
172}
173
174#[lang = "async_drop_fuse"]
175fn fuse<T>(inner: T) -> Fuse<T> {
176 Fuse { inner: Some(inner) }
177}
178
179impl<T> Future for Fuse<T>
180where
181 T: Future<Output = ()>,
182{
183 type Output = ();
184
185 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
186 unsafe {
188 let this = self.get_unchecked_mut();
189 if let Some(inner) = &mut this.inner {
190 ready!(Pin::new_unchecked(inner).poll(cx));
191 this.inner = None;
192 }
193 }
194 Poll::Ready(())
195 }
196}
197
198#[lang = "async_drop_slice"]
200async unsafe fn slice<T>(s: *mut [T]) {
201 let len = s.len();
202 let ptr = s.as_mut_ptr();
203 for i in 0..len {
204 unsafe { async_drop_in_place_raw(ptr.add(i)).await }
206 }
207}
208
209#[lang = "async_drop_chain"]
212async fn chain<F, G>(first: F, last: G)
213where
214 F: IntoFuture<Output = ()>,
215 G: IntoFuture<Output = ()>,
216{
217 first.await;
218 last.await;
219}
220
221#[lang = "async_drop_defer"]
229async unsafe fn defer<T: ?Sized>(to_drop: *mut T) {
230 unsafe { async_drop_in_place(to_drop) }.await
232}
233
234#[lang = "async_drop_either"]
244async unsafe fn either<O: IntoFuture<Output = ()>, M: IntoFuture<Output = ()>, T>(
245 other: O,
246 matched: M,
247 this: *mut T,
248 discr: <T as DiscriminantKind>::Discriminant,
249) {
250 if unsafe { discriminant_value(&*this) } == discr {
252 drop(other);
253 matched.await
254 } else {
255 drop(matched);
256 other.await
257 }
258}
259
260#[lang = "async_drop_deferred_drop_in_place"]
261async unsafe fn deferred_drop_in_place<T>(to_drop: *mut T) {
262 unsafe { crate::ptr::drop_in_place(to_drop) }
265}
266
267#[derive(Clone, Copy)]
271struct Noop;
272
273#[lang = "async_drop_noop"]
274fn noop() -> Noop {
275 Noop
276}
277
278impl Future for Noop {
279 type Output = ();
280
281 fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
282 Poll::Ready(())
283 }
284}