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