1 use core::{
2     mem,
3     fmt,
4     future::Future,
5     marker::PhantomData,
6     pin::Pin,
7     task::{Context, Poll},
8 };
9 
10 /// A custom trait object for polling futures, roughly akin to
11 /// `Box<dyn Future<Output = T> + 'a>`.
12 ///
13 /// This custom trait object was introduced as currently it is not possible to
14 /// take `dyn Trait` by value and `Box<dyn Trait>` is not available in no_std
15 /// contexts.
16 pub struct LocalFutureObj<'a, T> {
17     future: *mut (dyn Future<Output = T> + 'static),
18     drop_fn: unsafe fn(*mut (dyn Future<Output = T> + 'static)),
19     _marker: PhantomData<&'a ()>,
20 }
21 
22 // As LocalFutureObj only holds pointers, even if we move it, the pointed to values won't move,
23 // so this is safe as long as we don't provide any way for a user to directly access the pointers
24 // and move their values.
25 impl<T> Unpin for LocalFutureObj<'_, T> {}
26 
27 #[allow(single_use_lifetimes)]
28 #[allow(clippy::transmute_ptr_to_ptr)]
remove_future_lifetime<'a, T>(ptr: *mut (dyn Future<Output = T> + 'a)) -> *mut (dyn Future<Output = T> + 'static)29 unsafe fn remove_future_lifetime<'a, T>(ptr: *mut (dyn Future<Output = T> + 'a))
30     -> *mut (dyn Future<Output = T> + 'static)
31 {
32     mem::transmute(ptr)
33 }
34 
35 #[allow(single_use_lifetimes)]
remove_drop_lifetime<'a, T>(ptr: unsafe fn (*mut (dyn Future<Output = T> + 'a))) -> unsafe fn(*mut (dyn Future<Output = T> + 'static))36 unsafe fn remove_drop_lifetime<'a, T>(ptr: unsafe fn (*mut (dyn Future<Output = T> + 'a)))
37     -> unsafe fn(*mut (dyn Future<Output = T> + 'static))
38 {
39     mem::transmute(ptr)
40 }
41 
42 impl<'a, T> LocalFutureObj<'a, T> {
43     /// Create a `LocalFutureObj` from a custom trait object representation.
44     #[inline]
new<F: UnsafeFutureObj<'a, T> + 'a>(f: F) -> LocalFutureObj<'a, T>45     pub fn new<F: UnsafeFutureObj<'a, T> + 'a>(f: F) -> LocalFutureObj<'a, T> {
46         LocalFutureObj {
47             future: unsafe { remove_future_lifetime(f.into_raw()) },
48             drop_fn: unsafe { remove_drop_lifetime(F::drop) },
49             _marker: PhantomData,
50         }
51     }
52 
53     /// Converts the `LocalFutureObj` into a `FutureObj`.
54     ///
55     /// # Safety
56     ///
57     /// To make this operation safe one has to ensure that the `UnsafeFutureObj`
58     /// instance from which this `LocalFutureObj` was created actually
59     /// implements `Send`.
60     #[inline]
into_future_obj(self) -> FutureObj<'a, T>61     pub unsafe fn into_future_obj(self) -> FutureObj<'a, T> {
62         FutureObj(self)
63     }
64 }
65 
66 impl<T> fmt::Debug for LocalFutureObj<'_, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result67     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68         f.debug_struct("LocalFutureObj")
69             .finish()
70     }
71 }
72 
73 impl<'a, T> From<FutureObj<'a, T>> for LocalFutureObj<'a, T> {
74     #[inline]
from(f: FutureObj<'a, T>) -> LocalFutureObj<'a, T>75     fn from(f: FutureObj<'a, T>) -> LocalFutureObj<'a, T> {
76         f.0
77     }
78 }
79 
80 impl<T> Future for LocalFutureObj<'_, T> {
81     type Output = T;
82 
83     #[inline]
poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T>84     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
85         unsafe {
86             Pin::new_unchecked(&mut *self.future).poll(cx)
87         }
88     }
89 }
90 
91 impl<T> Drop for LocalFutureObj<'_, T> {
drop(&mut self)92     fn drop(&mut self) {
93         unsafe {
94             (self.drop_fn)(self.future)
95         }
96     }
97 }
98 
99 /// A custom trait object for polling futures, roughly akin to
100 /// `Box<dyn Future<Output = T> + Send + 'a>`.
101 ///
102 /// This custom trait object was introduced as currently it is not possible to
103 /// take `dyn Trait` by value and `Box<dyn Trait>` is not available in no_std
104 /// contexts.
105 ///
106 /// You should generally not need to use this type outside of `no_std` or when
107 /// implementing `Spawn`, consider using `BoxFuture` instead.
108 pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>);
109 
110 impl<T> Unpin for FutureObj<'_, T> {}
111 unsafe impl<T> Send for FutureObj<'_, T> {}
112 
113 impl<'a, T> FutureObj<'a, T> {
114     /// Create a `FutureObj` from a custom trait object representation.
115     #[inline]
new<F: UnsafeFutureObj<'a, T> + Send>(f: F) -> FutureObj<'a, T>116     pub fn new<F: UnsafeFutureObj<'a, T> + Send>(f: F) -> FutureObj<'a, T> {
117         FutureObj(LocalFutureObj::new(f))
118     }
119 }
120 
121 impl<T> fmt::Debug for FutureObj<'_, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result122     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123         f.debug_struct("FutureObj")
124             .finish()
125     }
126 }
127 
128 impl<T> Future for FutureObj<'_, T> {
129     type Output = T;
130 
131     #[inline]
poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T>132     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
133         Pin::new( &mut self.0 ).poll(cx)
134     }
135 }
136 
137 /// A custom implementation of a future trait object for `FutureObj`, providing
138 /// a vtable with drop support.
139 ///
140 /// This custom representation is typically used only in `no_std` contexts,
141 /// where the default `Box`-based implementation is not available.
142 ///
143 /// # Safety
144 ///
145 /// See the safety notes on individual methods for what guarantees an
146 /// implementor must provide.
147 pub unsafe trait UnsafeFutureObj<'a, T>: 'a {
148     /// Convert an owned instance into a (conceptually owned) fat pointer.
149     ///
150     /// # Safety
151     ///
152     /// ## Implementor
153     ///
154     /// The trait implementor must guarantee that it is safe to convert the
155     /// provided `*mut (dyn Future<Output = T> + 'a)` into a `Pin<&mut (dyn
156     /// Future<Output = T> + 'a)>` and call methods on it, non-reentrantly,
157     /// until `UnsafeFutureObj::drop` is called with it.
into_raw(self) -> *mut (dyn Future<Output = T> + 'a)158     fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a);
159 
160     /// Drops the future represented by the given fat pointer.
161     ///
162     /// # Safety
163     ///
164     /// ## Implementor
165     ///
166     /// The trait implementor must guarantee that it is safe to call this
167     /// function once per `into_raw` invocation.
168     ///
169     /// ## Caller
170     ///
171     /// The caller must ensure:
172     ///
173     ///  * the pointer passed was obtained from an `into_raw` invocation from
174     ///    this same trait object
175     ///  * the pointer is not currently in use as a `Pin<&mut (dyn Future<Output
176     ///    = T> + 'a)>`
177     ///  * the pointer must not be used again after this function is called
drop(ptr: *mut (dyn Future<Output = T> + 'a))178     unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a));
179 }
180 
181 unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for &'a mut F
182 where
183     F: Future<Output = T> + Unpin + 'a
184 {
into_raw(self) -> *mut (dyn Future<Output = T> + 'a)185     fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
186         self as *mut dyn Future<Output = T>
187     }
188 
drop(_ptr: *mut (dyn Future<Output = T> + 'a))189     unsafe fn drop(_ptr: *mut (dyn Future<Output = T> + 'a)) {}
190 }
191 
192 unsafe impl<'a, T> UnsafeFutureObj<'a, T> for &'a mut (dyn Future<Output = T> + Unpin + 'a)
193 {
into_raw(self) -> *mut (dyn Future<Output = T> + 'a)194     fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
195         self as *mut dyn Future<Output = T>
196     }
197 
drop(_ptr: *mut (dyn Future<Output = T> + 'a))198     unsafe fn drop(_ptr: *mut (dyn Future<Output = T> + 'a)) {}
199 }
200 
201 unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Pin<&'a mut F>
202 where
203     F: Future<Output = T> + 'a
204 {
into_raw(self) -> *mut (dyn Future<Output = T> + 'a)205     fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
206         unsafe { self.get_unchecked_mut() as *mut dyn Future<Output = T> }
207     }
208 
drop(_ptr: *mut (dyn Future<Output = T> + 'a))209     unsafe fn drop(_ptr: *mut (dyn Future<Output = T> + 'a)) {}
210 }
211 
212 unsafe impl<'a, T> UnsafeFutureObj<'a, T> for Pin<&'a mut (dyn Future<Output = T> + 'a)>
213 {
into_raw(self) -> *mut (dyn Future<Output = T> + 'a)214     fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
215         unsafe { self.get_unchecked_mut() as *mut dyn Future<Output = T> }
216     }
217 
drop(_ptr: *mut (dyn Future<Output = T> + 'a))218     unsafe fn drop(_ptr: *mut (dyn Future<Output = T> + 'a)) {}
219 }
220 
221 #[cfg(feature = "alloc")]
222 mod if_alloc {
223     use super::*;
224     use alloc::boxed::Box;
225 
226     unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F>
227         where F: Future<Output = T> + 'a
228     {
into_raw(self) -> *mut (dyn Future<Output = T> + 'a)229         fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
230             Box::into_raw(self)
231         }
232 
drop(ptr: *mut (dyn Future<Output = T> + 'a))233         unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) {
234             drop(Box::from_raw(ptr as *mut F))
235         }
236     }
237 
238     unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Box<dyn Future<Output = T> + 'a> {
into_raw(self) -> *mut (dyn Future<Output = T> + 'a)239         fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
240             Box::into_raw(self)
241         }
242 
drop(ptr: *mut (dyn Future<Output = T> + 'a))243         unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) {
244             drop(Box::from_raw(ptr))
245         }
246     }
247 
248     unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Box<dyn Future<Output = T> + Send + 'a> {
into_raw(self) -> *mut (dyn Future<Output = T> + 'a)249         fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
250             Box::into_raw(self)
251         }
252 
drop(ptr: *mut (dyn Future<Output = T> + 'a))253         unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) {
254             drop(Box::from_raw(ptr))
255         }
256     }
257 
258     unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Pin<Box<F>>
259     where
260         F: Future<Output = T> + 'a
261     {
into_raw(mut self) -> *mut (dyn Future<Output = T> + 'a)262         fn into_raw(mut self) -> *mut (dyn Future<Output = T> + 'a) {
263             let ptr = unsafe { self.as_mut().get_unchecked_mut() as *mut _ };
264             mem::forget(self);
265             ptr
266         }
267 
drop(ptr: *mut (dyn Future<Output = T> + 'a))268         unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) {
269             drop(Pin::from(Box::from_raw(ptr)))
270         }
271     }
272 
273     unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Pin<Box<dyn Future<Output = T> + 'a>> {
into_raw(mut self) -> *mut (dyn Future<Output = T> + 'a)274         fn into_raw(mut self) -> *mut (dyn Future<Output = T> + 'a) {
275             let ptr = unsafe { self.as_mut().get_unchecked_mut() as *mut _ };
276             mem::forget(self);
277             ptr
278         }
279 
drop(ptr: *mut (dyn Future<Output = T> + 'a))280         unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) {
281             drop(Pin::from(Box::from_raw(ptr)))
282         }
283     }
284 
285     unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Pin<Box<dyn Future<Output = T> + Send + 'a>> {
into_raw(mut self) -> *mut (dyn Future<Output = T> + 'a)286         fn into_raw(mut self) -> *mut (dyn Future<Output = T> + 'a) {
287             let ptr = unsafe { self.as_mut().get_unchecked_mut() as *mut _ };
288             mem::forget(self);
289             ptr
290         }
291 
drop(ptr: *mut (dyn Future<Output = T> + 'a))292         unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) {
293             drop(Pin::from(Box::from_raw(ptr)))
294         }
295     }
296 
297     impl<'a, F: Future<Output = ()> + Send + 'a> From<Box<F>> for FutureObj<'a, ()> {
from(boxed: Box<F>) -> Self298         fn from(boxed: Box<F>) -> Self {
299             FutureObj::new(boxed)
300         }
301     }
302 
303     impl<'a> From<Box<dyn Future<Output = ()> + Send + 'a>> for FutureObj<'a, ()> {
from(boxed: Box<dyn Future<Output = ()> + Send + 'a>) -> Self304         fn from(boxed: Box<dyn Future<Output = ()> + Send + 'a>) -> Self {
305             FutureObj::new(boxed)
306         }
307     }
308 
309     impl<'a, F: Future<Output = ()> + Send + 'a> From<Pin<Box<F>>> for FutureObj<'a, ()> {
from(boxed: Pin<Box<F>>) -> Self310         fn from(boxed: Pin<Box<F>>) -> Self {
311             FutureObj::new(boxed)
312         }
313     }
314 
315     impl<'a> From<Pin<Box<dyn Future<Output = ()> + Send + 'a>>> for FutureObj<'a, ()> {
from(boxed: Pin<Box<dyn Future<Output = ()> + Send + 'a>>) -> Self316         fn from(boxed: Pin<Box<dyn Future<Output = ()> + Send + 'a>>) -> Self {
317             FutureObj::new(boxed)
318         }
319     }
320 
321     impl<'a, F: Future<Output = ()> + 'a> From<Box<F>> for LocalFutureObj<'a, ()> {
from(boxed: Box<F>) -> Self322         fn from(boxed: Box<F>) -> Self {
323             LocalFutureObj::new(boxed)
324         }
325     }
326 
327     impl<'a> From<Box<dyn Future<Output = ()> + 'a>> for LocalFutureObj<'a, ()> {
from(boxed: Box<dyn Future<Output = ()> + 'a>) -> Self328         fn from(boxed: Box<dyn Future<Output = ()> + 'a>) -> Self {
329             LocalFutureObj::new(boxed)
330         }
331     }
332 
333     impl<'a, F: Future<Output = ()> + 'a> From<Pin<Box<F>>> for LocalFutureObj<'a, ()> {
from(boxed: Pin<Box<F>>) -> Self334         fn from(boxed: Pin<Box<F>>) -> Self {
335             LocalFutureObj::new(boxed)
336         }
337     }
338 
339     impl<'a> From<Pin<Box<dyn Future<Output = ()> + 'a>>> for LocalFutureObj<'a, ()> {
from(boxed: Pin<Box<dyn Future<Output = ()> + 'a>>) -> Self340         fn from(boxed: Pin<Box<dyn Future<Output = ()> + 'a>>) -> Self {
341             LocalFutureObj::new(boxed)
342         }
343     }
344 }
345