unrecurse/lib.rs
1#![deny(rust_2018_idioms)]
2#![allow(dead_code)]
3//! ## Unrecurse
4//! **This is in prototype state** As far as author knows the general idea is sound and even passes miri.
5//! but there are still a lot of rough edges internally and in public api.
6//!
7//! Helper to convert recursive approach into iterative.
8//!
9//! This crate consists from following main parts.
10//! - [`RefStack`] struct for direct and granular access to stack. But only supports references for now.
11//! - [`run`] to be able to store a struct that references previous element on stack.
12//! - [`run_async`] to rewrite async recursion without recursion/macros/allocating every future
13//! - [`run_async_backref`] if you have async recursion where current stack frame contains references to previous one
14//!
15//!
16//! The most simple method to use is `run_async(_backref)`.
17//! You can just convert your current recursive function into async fn. Add [`Recursion`]/[`RecursionContext`] parameter.
18//! Use it to invoke recursion and voila. It still looks like a recursion so it is still easy to reason about it
19//! but internally it uses async machinery to execute everything sequentially using a dedicated stack for current state.
20//! But currently quite often futures in rust are not very optimized. So if generated future is too big you might want to
21//! resort to the `run` function which allows you to create your own state to store in internal stack.
22//!
23//! MSRV: 1.60
24
25// todo better examples
26
27// use futures::AsyncReadExt;
28use std::future::Future;
29use std::marker::PhantomData;
30use std::mem::{transmute_copy, ManuallyDrop, MaybeUninit};
31use std::ops::{Deref, DerefMut};
32use std::pin::Pin;
33use std::ptr::NonNull;
34use std::task::Poll;
35
36/// With this struct you can save full state of current iteration including references
37/// so that when you pop that state back you now have full context available
38/// as if you just returned from the function call.
39/// Basically you just push current state into `RefStack`
40/// and then pop back when you need to return to that state.
41/// Exactly what compiler does with regular call stack when you do recursive call.
42/// And what `RefStack` does is sound precisely for that reason,
43/// it just emulates what compiler already does just in a dedicated structure.
44pub struct RefStack<'a, T, Metadata = ()> {
45 // SAFETY:
46 // this is basically a borrow stack in Stacked Borrows sense, so as long as we create
47 // references only from the last pointer, every pointer is derived from previous one
48 // and there are no active references when we pop then everything is sound.
49 // Also that's basically what compiler already does with regular function calls.
50 // Essentially when we call a function all references on previous stack
51 // frame become inactive(pretty much like raw pointers we use here)
52 // and you have only access to function arguments(last element here)
53 stack: Vec<*mut T>,
54 metadata: Vec<Metadata>,
55 phantom: PhantomData<&'a mut T>,
56}
57
58impl<'a, T, M: Default> RefStack<'a, T, M> {
59 pub fn new(init: &'a mut T) -> Self {
60 Self {
61 stack: vec![init],
62 metadata: vec![M::default()],
63 phantom: PhantomData,
64 }
65 }
66
67 /// Pushes new state that was created from previous one with closure.
68 pub fn push_with(&mut self, f: impl FnOnce(&mut T) -> &mut T) {
69 // let curr = self.current.take().unwrap();
70 // self.stack.push(curr as _);
71 let next = f(self.current()) as *mut _;
72 self.stack.push(next);
73 self.metadata.push(M::default())
74 }
75
76 /// Pops state from stack
77 pub fn pop(&mut self) -> Option<&mut T> {
78 self.metadata.pop();
79 // SAFETY: we operate on `&mut self`
80 // so there are no active references into stack at that point
81 // see also struct declaration
82 self.stack.pop().map(|x| unsafe { &mut *x })
83 }
84
85 /// Current reference in the end of a stack
86 pub fn current(&mut self) -> &mut T {
87 // SAFETY:
88 // we can get access only to the last element so it is fine
89 // see also struct declaration
90 unsafe { &mut *self.stack.last().copied().unwrap() }
91 }
92
93 /// Gets additional metadata for current state
94 pub fn meta(&mut self) -> &mut M {
95 self.metadata.last_mut().unwrap()
96 }
97
98 /// Current stack size
99 pub fn len(&self) -> usize {
100 self.stack.len()
101 }
102}
103
104// todo
105// pub struct GenericRefStack<'a, T: 'a, const CHUNK_SIZE: usize = 30> {
106// stack: ChainArena<MaybeUninit<T>, CHUNK_SIZE>,
107// phantom: PhantomData<&'a mut T>,
108// pin: PhantomPinned,
109// }
110//
111// impl<'a, T, const CHUNK_SIZE: usize> GenericRefStack<'a, T, CHUNK_SIZE> {
112// pub fn new(init: T) -> Self {
113// let mut stack = ChainArena::new();
114// stack.push(MaybeUninit::new(init));
115// Self {
116// stack,
117// phantom: PhantomData,
118// pin: PhantomPinned,
119// }
120// }
121//
122// // pub fn push_with<F>(self:Pin<&mut Self>, f: F)
123// // where
124// // F: for<'x> MyFnOnce<&'x mut T>,
125// // F: FnOnce(&'a mut T) -> T + 'static,
126// // {
127// // let this = unsafe { self.get_unchecked_mut() };
128// // // let curr = self.current.take().unwrap();
129// // // self.stack.push(curr as _);
130// // let next = f(this.current_inner());
131// // this.stack.push(MaybeUninit::new(next));
132// // }
133// pub fn loop_with<F>(&mut self, f: F)
134// where
135// T: for<'x> WithLifetime<'x, 'a>,
136// F: for<'x> FnMut(
137// &'x mut <T as WithLifetime<'x, 'a>>::Applied,
138// ) -> Option<<T as WithLifetime<'x, 'a>>::Applied>,
139// F: FnMut(&'a mut T) -> Option<T>,
140// {
141// loop {
142// let curr = self.current_inner();
143// unsafe {
144// match f(curr) {
145// /* ControlFlow::Break(r) => return Some(r), */
146// None => self.pop_inner()?,
147// Some(n) => self.stack.push(MaybeUninit::new(n)),
148// }
149// }
150// }
151// }
152//
153// pub fn advance<'b, F, Y>(&'b mut self, f: F) -> Option<Y>
154// where
155// T: for<'x> WithLifetime<'x, 'a>,
156// Y: for<'x> WithLifetime<'x, 'b>,
157// F: for<'x, 'y> FnOnce(
158// &'x mut <T as WithLifetime<'y, 'a>>::Applied,
159// ) -> Action<
160// <Y as WithLifetime<'x, 'b>>::Applied,
161// <T as WithLifetime<'x, 'a>>::Applied,
162// >,
163// // F: FnOnce(&'a mut T) -> Action<R, T>,
164// {
165// // loop {
166// if self.is_empty() {
167// return None;
168// }
169// let curr = self.current_inner();
170// match f(curr) {
171// Action::Yield(r) => return Some(r),
172// Action::Return(()) => self.pop_inner(),
173// Action::Recurse(n) => self.stack.push(MaybeUninit::new(n)),
174// }
175// // }
176// }
177//
178// pub fn advance_deref<'b, F, Y>(&'b mut self, f: F) -> Option<Y>
179// where
180// T: for<'x> WithLifetime<'x, 'a> + StableDeref,
181// Y: for<'x> WithLifetime<'x, 'b>,
182// F: for<'x, 'y> FnOnce(
183// &'x mut T::Target,
184// ) -> Action<
185// <Y as WithLifetime<'x, 'b>>::Applied,
186// <T as WithLifetime<'x, 'a>>::Applied,
187// >,
188// // F: FnOnce(&'a mut T) -> Action<R, T>,
189// {
190// // loop {
191// if self.is_empty() {
192// return None;
193// }
194// let curr = self.current_inner();
195// match f(curr) {
196// Action::Yield(r) => return Some(r),
197// Action::Return(()) => self.pop_inner(),
198// Action::Recurse(n) => self.stack.push(MaybeUninit::new(n)),
199// }
200// // }
201// }
202//
203// pub fn pop_inner(&mut self) -> Option<T> {
204// unsafe { self.stack.pop().map(|x| x.assume_init()) }
205// }
206//
207// pub fn push_with<F>(mut self: &mut Pin<&mut Self>, f: F)
208// where
209// T: for<'x> WithLifetime<'x, 'a>,
210// F: for<'x, 'y> FnOnce(
211// &'x mut <T as WithLifetime<'y, 'a>>::Applied,
212// ) -> <T as WithLifetime<'x, 'a>>::Applied,
213// F: FnOnce(&'a mut T) -> T,
214// {
215// // let curr = self.current.take().unwrap();
216// // self.stack.push(curr as _);
217// let next = f(self.as_mut().inner().current_inner());
218// self.as_mut().inner().stack.push(MaybeUninit::new(next));
219// }
220//
221// fn inner(self: Pin<&mut Self>) -> &mut Self {
222// unsafe { self.get_unchecked_mut() }
223// }
224//
225// pub fn pop(self: Pin<&mut Self>) -> Option<T> {
226// self.inner().stack.pop().map(|x| unsafe { x.assume_init() })
227// // self.inner().stack.pop().map(|_| ())
228// }
229//
230// fn current_inner(&mut self) -> &'a mut T {
231// unsafe { &mut *(self.stack.last_mut().unwrap().assume_init_mut() as *mut _) }
232// }
233//
234// pub fn current(self: Pin<&mut Self>) -> &mut T {
235// self.inner().current_inner()
236// }
237//
238// pub fn is_empty(&self) -> bool {
239// self.stack.is_empty()
240// }
241// }
242/// Used to rewrite post order processing of recursive data structures in iterative way.
243/// Struct that you want to use as a current state must implement [`WithLifetime`] properly.
244pub fn run<T, F, R: Default>(init: T, mut f: F) -> R
245where
246 T: for<'x> WithLifetime<'x>,
247 F: for<'x, 'y> FnMut(
248 &'x mut <T as WithLifetime<'y>>::Applied,
249 ) -> Action<<T as WithLifetime<'x>>::Applied, R>,
250 // T: for<'x> ShrinkLifetime<'x>,
251 // F: for<'x, 'y> FnMut(
252 // &'x mut <T as ShrinkLifetime<'y>>::BoundApplied,
253 // ) -> Action<<T as ShrinkLifetime<'x>>::BoundApplied, R>,
254{
255 // run2::<_, _, _, ()>(init, f)
256 // }
257 //
258 // pub fn run2<'a, T, F, R: Default, Marker>(init: T, mut f: F) -> R
259 // where
260 // T: for<'x> WithLifetime<'x, 'a, Marker>,
261 // // for<'x> <T as WithLifetime<'x, 'a, Marker>>::Applied: Sized,
262 // F: for<'x, 'y> FnMut(
263 // &'x mut <T as WithLifetime<'y, 'a, Marker>>::Applied,
264 // ) -> Action<<T as WithLifetime<'x, 'a, Marker>>::Applied, R>,
265 // // F: FnMut(&'a mut T) -> Option<T>,
266 // {
267 let mut stack = ChainArena::<_, 30>::new();
268 stack.push(init);
269 loop {
270 let curr = if let Some(x) = stack.last_mut() {
271 x
272 } else {
273 return R::default();
274 };
275 unsafe {
276 match f(core::mem::transmute(curr)) {
277 /* ControlFlow::Break(r) => return Some(r), */
278 Action::Return(()) => {
279 stack.pop();
280 }
281 Action::Yield(r) => return r,
282 Action::Recurse(n) => stack.push(WithLifetime::move_with_lifetime_back(n)),
283 }
284 }
285 }
286}
287
288// pub struct Wrap<'x, T>(MaybeUninit<T>, PhantomData<fn(&'x T) -> &'x ()>);
289// impl<'x, T> Drop for Wrap<'x, T> {
290// fn drop(&mut self) {
291// unsafe { core::ptr::drop_in_place(self.0.as_mut_ptr()) }
292// }
293// }
294// impl<'x, T> Wrap<'x, T>
295// where
296// T: WithLifetime<'x>,
297// {
298// fn from(f: T) -> Self {
299// // Wrap(MaybeUninit::new(f), PhantomData)
300// Wrap(f, PhantomData)
301// }
302//
303// pub fn into_inner(self) -> T::Applied {
304// unsafe { self.0.assume_init().move_with_lifetime() }
305// // unsafe { self.0.as_ptr().read().move_with_lifetime() }
306// }
307// }
308//
309// impl<'x, T> Deref for Wrap<'x, T>
310// where
311// T: WithLifetime<'x>,
312// {
313// type Target = T::Applied;
314//
315// fn deref(&self) -> &Self::Target {
316// // unsafe { self.0.assume_init_ref().with_lifetime() }
317// unsafe { self.0.assume_init_read().with_lifetime() }
318// }
319// }
320// impl<'x, T> DerefMut for Wrap<'x, T>
321// where
322// T: WithLifetime<'x>,
323// {
324// fn deref_mut(&mut self) -> &mut Self::Target {
325// // unsafe { self.0.assume_init_mut().with_lifetime_mut() }
326// unsafe { self.0.assume_init_mut().with_lifetime_mut() }
327// }
328// }
329
330/// Shorthand for `futures::executor::block_on(run_async())`
331/// if you want to rewrite regular recursion using async one
332pub fn run_async_blocking<F, T, R>(init: T, f: F) -> R
333where
334 F: for<'x> AsyncFnMut2<T, Recursion<'x, T, R>, Output = R>,
335{
336 futures_executor::block_on(run_async(init, f))
337}
338
339// /// Shorthand for `futures::executor::block_on(run_async_checked())`
340// /// if you want to rewrite regular recursion using async one
341// pub fn run_async_blocking_checked<F, Fut, T, R>(init: T, mut f: F) -> R
342// where
343// F: FnMut(T, RecursionChecked<T, R>) -> Fut,
344// Fut: Future<Output = Checked<R>>,
345// {
346// futures_executor::block_on(run_async_checked(init, f))
347// }
348
349// unsound, it is possible to move `RecursionChecked` into spawned task
350// and then current future can be cancelled so `RecursionChecked` now contains dangling references
351// async fn run_async_checked<F, Fut, T, R>(init: T, mut f: F) -> R
352// where
353// F: FnMut(T, RecursionChecked<T, R>) -> Fut,
354// Fut: Future<Output = Checked<R>>,
355// {}
356
357/// More capable version of [`run_async`].
358pub async fn run_async_with_data<F, T, R, D>(init: T, data: &mut D, mut f: F) -> R
359where
360 F: for<'x> AsyncFnMut3<T, Data<'x, D>, Recursion<'x, T, R>, Output = R>,
361{
362 // todo rewrite using run_async_backref_with_data when Withlifetime will support marker
363 // it is possible to use qcell::LCell and no unsafe but it would require adding
364 // second lifetime to `Recursion` which might be confusing to users
365 // qcell::LCellOwner::scope(|owner| {
366 let mut result = None;
367 let mut next = None;
368
369 let data = Data(AliasableMut::from(data));
370 let mut ret = RecursionChecked::new(&mut next, &mut result);
371 let mut ret = AliasableMut::from(&mut ret);
372 let mut stack = ChainArena::<_, 30>::new();
373 let arg = init;
374
375 // let mut ret = RecursionChecked(
376 // unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(None)).into()) },
377 // unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(None)).into()) },
378 // );
379 unsafe {
380 stack.push(f.call(arg, data.copy(), core::ptr::read(&ret)));
381 }
382 loop {
383 // SAFETY: ChainArena does not move elements even when pushed into so it is safe to Pin the element
384 let poll = futures_util::poll!(unsafe { Pin::new_unchecked(stack.last_mut().unwrap()) });
385 if let Poll::Ready(returned) = poll {
386 stack.pop();
387 if stack.is_empty() {
388 return returned;
389 }
390 unsafe {
391 core::ptr::write(ret.1.as_ptr(), Some(returned));
392 }
393 } else {
394 let next = unsafe { ret.0.as_mut().take() };
395 if let Some(arg) = next {
396 // let ret = Recursion(&next, &result);
397 // let arg = unsafe { core::mem::transmute_copy(&arg) };
398 unsafe {
399 stack.push(f.call(arg, data.copy(), core::ptr::read(&ret)));
400 }
401 } else {
402 // not our return so forward waiting
403 futures_util::pending!();
404 }
405 }
406 }
407 // })
408}
409
410/// Function to invoke async recursion without `Box`ing every future.
411/// Often you can already rewrite your async recursion with `futures::stream::unfold`.
412/// But it has some limitations,
413/// `run_async` on the other hand has exactly same capabilities as a regular async recursion.
414/// You can also use it as a simpler version of [`run`].
415///
416/// Internally it allocates initial 30-elements buffer(number will be customizable in the next versions) of futures on stack.
417/// And then if recursion is deeper than that it will allocate linked list of such buffers to allow deep recursion.
418///
419/// #### Warning
420/// Due to bugs in compiler currently it only supports `F` to be an `async fn`.
421/// Nevertheless there is still possibility to access additional data with [`run_async_with_data`].
422pub async fn run_async<'a, F, T, R>(init: T, mut f: F) -> R
423where
424 F: for<'x> AsyncFnMut2<T, Recursion<'x, T, R>, Output = R>,
425{
426 async fn delegator<T, F, R>(arg: T, mut f: Data<'_, F>, rec: Recursion<'_, T, R>) -> R
427 where
428 F: for<'x> AsyncFnMut2<T, Recursion<'x, T, R>, Output = R>,
429 {
430 f.access_with(|f: &mut _| f.call(arg, rec)).await
431 }
432 run_async_with_data(init, &mut f, delegator).await
433}
434
435struct SendSyncPtr<T>(*mut T);
436impl<T> Clone for SendSyncPtr<T> {
437 fn clone(&self) -> Self {
438 SendSyncPtr(self.0)
439 }
440}
441impl<T> Copy for SendSyncPtr<T> {}
442unsafe impl<T: Send> Send for SendSyncPtr<T> {}
443unsafe impl<T: Sync> Sync for SendSyncPtr<T> {}
444
445/// Same as [`run_async`] but allows to run recursion where current state/future has references into previous one.
446///
447/// #### Warning
448/// Due to bugs in compiler currently it only supports `F` to be an `async fn`.
449/// Nevertheless there is still possibility to access additional data with [`run_async_backref_with_data`].
450// `R` can also be `WithLifetime` here, but i could not find any realistic use-cases where it is necessary,
451// so it would just require user to implement `WithLifetime` for `R` for no reason
452pub async fn run_async_backref<F, T, R>(init: T, mut f: F) -> R
453where
454 T: for<'x> WithLifetime<'x>,
455 F: for<'x> AsyncFnMut2<
456 <T as WithLifetime<'x>>::Applied,
457 RecursionContext<'x, T, R>,
458 Output = R,
459 >,
460{
461 fn delegator<'a, T, F, R>(
462 arg: <T as WithLifetime<'a>>::Applied,
463 mut f: Data<'a, F>,
464 rec: RecursionContext<'a, T, R>,
465 ) -> impl Future<Output = R> + 'a
466 where
467 T: for<'x> WithLifetime<'x>,
468 F: for<'x> AsyncFnMut2<
469 <T as WithLifetime<'x>>::Applied,
470 RecursionContext<'x, T, R>,
471 Output = R,
472 >,
473 {
474 f.access_with(|f: &mut _| f.call(arg, rec))
475 }
476 run_async_backref_with_data(init, &mut f, delegator).await
477}
478
479/// Workaround for a compiler bug
480pub struct ForceFutureSend<SendMarkers, Fut>(Fut, PhantomData<SendMarkers>);
481unsafe impl<M: Send, F> Send for ForceFutureSend<M, F> {}
482impl<M, F: Future> Future for ForceFutureSend<M, F> {
483 type Output = F::Output;
484
485 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
486 //SAFETY: just a simple delegation
487 unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().0) }.poll(cx)
488 }
489}
490
491struct SendWrapper<T, Marker>(T, PhantomData<Marker>);
492unsafe impl<T, Marker: Send> Send for SendWrapper<T, Marker> {}
493
494/// Version of [`run_async_backref`] that supports additional data to pass into
495pub fn run_async_backref_with_data<'b, 'a: 'b, T: 'a, F: 'a, R: 'a, D: 'a>(
496 init: T,
497 data: &'b mut D,
498 mut f: F,
499) -> ForceFutureSend<(D, T, R, F), impl Future<Output = R> + Captures<'a> + 'b>
500where
501 T: for<'x> WithLifetime<'x>,
502 F: for<'x> AsyncFnMut3<
503 // Wrap<'x, T>,
504 <T as WithLifetime<'x>>::Applied,
505 Data<'x, D>,
506 RecursionContext<'x, T, R>,
507 Output = R,
508 >,
509{
510 // let mut result = None;
511 // let mut next = None;
512
513 // stupid rust compiler has another bug such that it can't properly evaluate Sendness of this future
514 // there is a very ugly workaround for that to work so the future is definitely `Send`
515 // in future if there are going to be significant changes here don't forget to check if it still being Send
516 ForceFutureSend(
517 async move {
518 let arg = init;
519
520 let mut ctx_data = WakerData {
521 outer_waker: GetOuterWaker.await,
522 arg: None::<T>,
523 result: None::<R>,
524 };
525 let waker = waker_with_data(&mut ctx_data);
526 let data = Data(AliasableMut::from(data));
527 let mut ctx = Context::from_waker(&waker);
528 let mut stack = ChainArena::<_, 30>::new();
529
530 stack.push(f.call(
531 //SAFETY: same as RefStack
532 unsafe { arg.move_with_lifetime() },
533 data.copy(),
534 RecursionContext(PhantomData),
535 ));
536
537 loop {
538 // SAFETY: ChainArena does not move elements even when pushed into so it is safe to Pin the element
539 // todo make safe api for ChainArena to pin elements
540 let fut = unsafe { Pin::new_unchecked(stack.last_mut().unwrap()) };
541 let poll = fut.poll(&mut ctx);
542 // SAFETY: can't access `ctx_data` directly because in StackedBorrows it would invalidate pointers inside ctx
543 let ctx_data = unsafe { get_waker_data::<WakerData<T, R>>(&mut ctx) };
544 if let Poll::Ready(returned) = poll {
545 // let returned = unsafe { WithLifetime::move_with_lifetime_back(returned) };
546 stack.pop();
547 if stack.is_empty() {
548 return returned;
549 }
550 ctx_data.result = Some(returned);
551 } else {
552 if let Some(arg) = ctx_data.arg.take() {
553 // let ret = Recursion(&next, &result);
554 // let arg = unsafe { core::mem::transmute_copy(&arg) };
555 stack.push(f.call(
556 //SAFETY: same as RefStack
557 unsafe { arg.move_with_lifetime() },
558 data.copy(),
559 RecursionContext(PhantomData),
560 ));
561 } else {
562 // not our return so forward waiting
563 futures_util::pending!();
564 }
565 }
566 }
567 },
568 PhantomData,
569 )
570}
571//todo potentially should be more optimized version but something is wrong
572// with futures optimizer in rust so it is worse
573//
574// / Same as [`run_async_backref`] but allows to get access to additional data.
575// pub async fn run_async_backref_with_data<'a, F, T, R, D>(init: T, data: &'a mut D, mut f: F) -> R
576// where
577// T: for<'x> WithLifetime<'x>,
578// F: for<'x> AsyncFnMut3<
579// <T as WithLifetime<'x>>::Applied,
580// Data<'x, D>,
581// RecursionContext2<'x, T, R>,
582// Output = R,
583// >,
584// {
585// // let mut result = None;
586// // let mut next = None;
587// let mut arg = init;
588//
589// let mut stack = ChainArena::<_, 30>::new();
590// let data_ptr = data as *mut D;
591// let stack_ptr: *mut _ = &mut stack;
592// // let data = Data(AliasableMut::from(data));
593// let cb_called = Cell::new(false);
594// let cb_called = &cb_called;
595// let mut callback = move |arg: T| unsafe {
596// cb_called.set(true);
597// let fut = f.call(
598// arg.move_with_lifetime(),
599// Data(AliasableMut::from(&mut *data_ptr)),
600// RecursionContext2(PhantomData),
601// );
602// unsafe { &mut *stack_ptr }.push(fut);
603// };
604// fn cast_cb<T>(arg: &mut impl FnMut(T)) -> &mut (dyn 'static + FnMut(T)) {
605// unsafe { core::mem::transmute(arg as &mut dyn FnMut(T)) }
606// }
607//
608// let callback_ptr = cast_cb(&mut callback);
609// let mut ctx_data = WakerData2 {
610// callback: callback_ptr,
611// result: MaybeUninit::<R>::uninit(),
612// outer_waker: GetOuterWaker.await,
613// };
614// let waker = waker_with_data(&mut ctx_data);
615// let mut ctx = Context::from_waker(&waker);
616// // let mut ret = RecursionContext::<T, R>(PhantomData);
617// // let mut ret = RecursionRef(AliasableMut::from(&mut ret));
618//
619// unsafe {
620// (&mut *callback_ptr)(arg);
621// }
622// loop {
623// //fixme, technically unsound, make ChainArena as actual arena that works via immutable reference
624// let stack = unsafe { &mut *stack_ptr };
625// // SAFETY: ChainArena does not move elements even when pushed into so it is safe to Pin the element
626// let fut = unsafe { Pin::new_unchecked(stack.last_mut().unwrap()) };
627// let poll = fut.poll(&mut ctx);
628// let ctx_data = unsafe { get_waker_data2::<WakerData2<T, R>>(&mut ctx) };
629// if let Poll::Ready(returned) = poll {
630// // let returned = unsafe { WithLifetime::move_with_lifetime_back(returned) };
631// stack.pop();
632// if stack.is_empty() {
633// return returned;
634// }
635// ctx_data.result.write(returned);
636// } else {
637// if cb_called.get() {
638// cb_called.set(false);
639// continue;
640// }
641// //not our return so forward waiting
642// futures_util::pending!();
643// }
644// }
645// }
646
647/// Reference to outer data to access from recursive future.
648pub struct Data<'a, T>(AliasableMut<'a, T>);
649// unsafe impl<'a, T: Send> Send for Data<'a, T> {}
650// you can't do anything with shared reference to `Data` so we can always implement Sync
651// unsafe impl<'a, T: Send> Sync for Data<'a, T> {}
652impl<'a, T> Data<'a, T> {
653 fn copy(&self) -> Self {
654 //SAFETY: there can't be multiple `Data`s dereferenced at the same time
655 // because you can't keep reference to `T` across await points
656 unsafe { core::ptr::read(self) }
657 }
658 /// Reference to `T` must not be held across await point so
659 /// the only way to access it is with callback
660 pub fn access_with<F, R>(&mut self, f: F) -> R
661 where
662 F: FnOnce(&mut T) -> R,
663 {
664 f(&mut self.0)
665 }
666}
667
668// macro_rules! hrtb_check{
669// ( for<'x,'y> |$arg1:ident : $arg1_ty:ty, $arg1:ident : RecursionRef<'x > | -> ) ={
670//
671// }
672// }
673
674// pub fn blocking_run_with_backref<'a, F, T, R>(init: T, mut f: F) -> R
675// where
676// T: for<'x> WithLifetime<'x, 'a>,
677// F: for<'x> AsyncFnMut<T, RecursionRef<'x, T, R>, Output=R>,
678// {}
679//
680// pub fn blocking_run_with_backref_inner<'a, F, T, R, Marker>(init: T, mut f: F) -> R
681// where
682// T: for<'x> WithLifetime<'x, 'a, Marker>,
683// R: for<'x> WithLifetime<'x, 'a, Marker>,
684// F: for<'x> AsyncFnMut<
685// <T as WithLifetime<'x, 'a, Marker>>::Applied,
686// RecursionRef<'x, T, R>,
687// Output=<R as WithLifetime<'x, 'a, Marker>>::Applied,
688// >,
689// {
690// let waker = futures::task::noop_waker_ref();
691// let mut ctx = std::task::Context::from_waker(waker);
692// let result = Cell::new(None);
693// let next = Cell::new(None);
694//
695// let mut stack = ChainArena::<_, 30>::new();
696// let mut arg = init;
697//
698// let ret = Recursion(&next, &result);
699// stack.push(f.call(arg, ret));
700// loop {
701// // println!("{}", stack.dbg_len());
702// let poll = unsafe { Pin::new_unchecked(stack.last_mut().unwrap()).poll(&mut ctx) };
703// if let Poll::Ready(returned) = poll {
704// // println!("ready");
705// stack.pop();
706// if stack.is_empty() {
707// return returned;
708// }
709// result.set(Some(returned));
710// } else {
711// // println!("pending");
712// if let Some(arg) = next.take() {
713// let ret = Recursion(&next, &result);
714// // let arg = unsafe { core::mem::transmute_copy(&arg) };
715// stack.push(f.call(arg, ret));
716// }
717// }
718// }
719// }
720
721// pub async fn async_run<F,T,R>(init:T, f: F)
722// where
723// F: for<'x> AsyncFnMut<T, Result<'x, T, R>,Output=R>,
724// {
725//
726// }
727
728/// Helper struct to invoke async recursion
729pub type Recursion<'x, T, R> = AliasableMut<'x, RecursionChecked<T, R>>;
730
731#[doc(hidden)]
732pub struct RecursionChecked<T, R>(NonNull<Option<T>>, NonNull<Option<R>>);
733unsafe impl<T: Send, R: Send> Send for RecursionChecked<T, R> {}
734unsafe impl<T: Send, R: Send> Sync for RecursionChecked<T, R> {}
735
736impl<T, R> RecursionChecked<T, R> {
737 fn new(next: &mut Option<T>, result: &mut Option<R>) -> Self {
738 RecursionChecked(next.into(), result.into())
739 }
740 fn copy(&self) -> Self {
741 RecursionChecked(self.0, self.1)
742 }
743 /// Invokes recursive async call
744 pub fn recurse(&mut self, arg: T) -> impl Future<Output = R> + '_ {
745 unsafe {
746 *self.0.as_mut() = Some(arg);
747 }
748 async move {
749 // i have no idea why miri requires pointer to be copied before pending!
750 // but it passes miri now ¯\_(ツ)_/¯
751 let ptr = SendSyncPtr(self.1.as_ptr());
752 futures_util::pending!();
753 unsafe { (&mut *ptr.0).take().unwrap() }
754 }
755 }
756
757 /// Prevents moving out `RecursionChecked` from the closure
758 pub fn into_return(self, ret: R) -> Checked<R> {
759 Checked(ret)
760 }
761}
762
763/// Marker to indicate that `RecursionChecked` has been consumed.
764/// Created by `RecursionChecked::into_return`.
765pub struct Checked<R>(R);
766
767// --------------------------------------------------------------------------------------------
768//
769// unsound because it will be possible to move out reference into previous future
770// and previous future will be freed after this function ends, so use after free
771// async fn run_async_backref_checked<F, Fut, T, R>(init: T, mut f: F) -> R
772// where
773// F: FnMut(PtrMut<T>, RecursionRefChecked<T, R>) -> Fut,
774// Fut: Future<Output = Checked<R>>,
775// {
776// todo!()
777// }
778struct RecursionRefChecked<T, R>(NonNull<Option<T>>, NonNull<Option<R>>);
779unsafe impl<T: Send, R: Send> Send for RecursionRefChecked<T, R> {}
780unsafe impl<T: Send, R: Send> Sync for RecursionRefChecked<T, R> {}
781
782impl<T, R> RecursionRefChecked<T, R> {
783 fn new(next: &mut Option<T>, result: &mut Option<R>) -> Self {
784 RecursionRefChecked(next.into(), result.into())
785 }
786 fn copy(&self) -> Self {
787 RecursionRefChecked(self.0, self.1)
788 }
789
790 pub fn recurse<'a>(&'a mut self, arg: T::Applied) -> impl Future<Output = R> + 'a
791 where
792 T: WithLifetime<'a>,
793 {
794 unsafe {
795 *self.0.as_mut() = Some(WithLifetime::move_with_lifetime_back(arg));
796 }
797 async move {
798 futures_util::pending!();
799 unsafe { self.1.as_mut().take().unwrap() }
800 }
801 }
802
803 pub fn into_return<'a, 'b>(self, ret: R, _ptr: PtrMut<T>) -> Checked<R> {
804 Checked(ret)
805 }
806}
807struct PtrMut<T>(NonNull<T>);
808impl<T> Deref for PtrMut<T> {
809 type Target = T;
810
811 fn deref(&self) -> &Self::Target {
812 unsafe { self.0.as_ref() }
813 }
814}
815impl<T> DerefMut for PtrMut<T> {
816 fn deref_mut(&mut self) -> &mut Self::Target {
817 unsafe { self.0.as_mut() }
818 }
819}
820
821// ------------------------------------
822
823#[doc(hidden)]
824pub trait Captures<'x> {}
825impl<'x, T> Captures<'x> for T {}
826
827/// Helper trait to be able to use HRTBs with async closures
828pub trait AsyncFnMut2<T, U> {
829 type Future: Future<Output = Self::Output>;
830 type Output;
831 fn call(&mut self, arg: T, arg2: U) -> Self::Future;
832}
833
834impl<T, U, F, R: Future> AsyncFnMut2<T, U> for F
835where
836 F: FnMut(T, U) -> R,
837{
838 type Future = R;
839 type Output = R::Output;
840
841 fn call(&mut self, arg: T, arg2: U) -> Self::Future {
842 self(arg, arg2)
843 }
844}
845
846/// Helper trait to be able to use HRTBs with async closures
847pub trait AsyncFnMut3<T, U, V> {
848 type Future: Future<Output = Self::Output>;
849 type Output;
850 fn call(&mut self, arg: T, arg2: U, arg3: V) -> Self::Future;
851}
852
853impl<T, U, V, F, R> AsyncFnMut3<T, U, V> for F
854where
855 F: FnMut(T, U, V) -> R,
856 R: Future,
857{
858 type Future = R;
859 type Output = R::Output;
860
861 fn call(&mut self, arg: T, arg2: U, arg3: V) -> Self::Future {
862 self(arg, arg2, arg3)
863 }
864}
865
866// pub trait AsyncFnOnce<T> {
867// type Future: Future<Output = Self::Output>;
868// type Output;
869// fn call(self, arg: T) -> Self::Future;
870// }
871//
872// impl<T, F, R: Future> AsyncFnOnce<T> for F
873// where
874// F: FnOnce(T) -> R,
875// {
876// type Future = R;
877// type Output = R::Output;
878//
879// fn call(self, arg: T) -> Self::Future {
880// self(arg)
881// }
882// }
883
884use core::task::{Context, RawWaker, RawWakerVTable, Waker};
885
886unsafe fn rwclone(ptr: *const ()) -> RawWaker {
887 // ideally we should have just copied vtable when creating our Waker
888 // but it is impossible to do soundly until `waker_getters` feature stabilized
889 // As i understood Waker is always being cloned when being used for waking
890 // So if cloning returns suitable Waker then futures that require outer executor
891 // will behave properly. So here we invoke clone of saved Waker
892 core::mem::transmute((&*(ptr as *const Waker)).clone())
893}
894
895unsafe fn rwwake(_p: *const ()) {}
896
897unsafe fn rwwakebyref(_p: *const ()) {}
898
899unsafe fn rwdrop(_p: *const ()) {}
900
901static VTABLE: RawWakerVTable = RawWakerVTable::new(rwclone, rwwake, rwwakebyref, rwdrop);
902
903fn waker_with_data<T>(data: *mut T) -> Waker {
904 unsafe { Waker::from_raw(RawWaker::new(data as *mut T as *mut (), &VTABLE)) }
905}
906
907/// Continuously poll a future until it returns `Poll::Ready`. This is not normally how an
908/// executor should work, because it runs the CPU at 100%.
909// pub fn spin_on<F: Future, D>(data: &mut D, future: F) -> F::Output {
910// pin_utils::pin_mut!(future);
911// let waker = &waker_with_data(data);
912// let mut cx = Context::from_waker(waker);
913// loop {
914// if let Poll::Ready(output) = future.as_mut().poll(&mut cx) {
915// return output;
916// }
917// }
918// }
919struct WakerData2<T, R> {
920 outer_waker: Waker,
921 callback: *mut dyn FnMut(T),
922 result: MaybeUninit<R>,
923}
924
925struct RecursionContext2<'a, T, R>(PhantomData<*mut &'a mut (T, R)>);
926impl<'x, T, R> RecursionContext2<'x, T, R> {
927 pub fn recurse<'a, Out: 'a>(&'a mut self, arg: Out) -> impl Future<Output = R> + 'a
928 where
929 T: WithLifetime<'a, Applied = Out>,
930 {
931 // let state = false;
932 // let mut arg = ManuallyDrop::new(arg);
933 async move {
934 // if state {
935 let callback = futures_util::future::poll_fn(|ctx| {
936 Poll::Ready(unsafe { get_waker_data::<WakerData2<T, R>>(ctx).callback })
937 })
938 .await;
939 unsafe { (&mut *callback)(WithLifetime::move_with_lifetime_back(arg)) };
940 futures_util::pending!();
941 // } else {
942 futures_util::future::poll_fn(|ctx| {
943 Poll::Ready(unsafe {
944 get_waker_data::<WakerData2<T, R>>(ctx)
945 .result
946 .as_ptr()
947 .read()
948 })
949 })
950 .await
951 // unsafe { data.result.assume_init_read() }
952 // }
953 }
954 }
955}
956
957struct WakerData<T, R> {
958 outer_waker: Waker,
959 arg: Option<T>,
960 // todo, no need for option, check if MaybeUninit actually improves something
961 result: Option<R>,
962}
963
964/// Helper struct to invoke async recursion with references to previous state
965pub struct RecursionContext<'a, T, R>(PhantomData<fn(&'a mut (T, R)) -> &'a ()>);
966
967impl<'x, T, R> RecursionContext<'x, T, R> {
968 pub fn recurse<'a>(&'a mut self, arg: T::Applied) -> RecursionFuture<'a, T::Applied, R>
969 where
970 T: WithLifetime<'a>,
971 {
972 RecursionFuture(Some(arg), PhantomData)
973 }
974}
975
976/// Future returned from [`RecursionContext::recurse`]
977pub struct RecursionFuture<'a, T, R>(Option<T>, PhantomData<PhantomData<fn(&'a mut R) -> &'a ()>>);
978impl<'x, T: Unpin, R> Future for RecursionFuture<'x, T, R> {
979 type Output = R;
980
981 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
982 // SAFETY: because of HRTB lifetime we know that we are inside `run_async*` call
983 // so `WakerData` is valid
984 // but when in future scoped async will be a thing it would be possible to cause UB
985 // but we can prevent it by checking that we are still in suitable context via
986 // ptr::eq(cx.waker().as_raw().vtable(),&VTABLE);
987 // although it currently requires nightly features so it is not enabled right now
988 let data = unsafe { get_waker_data::<WakerData<T, R>>(cx) };
989
990 if let t @ Some(_) = self.0.take() {
991 data.arg = t;
992 Poll::Pending
993 } else {
994 Poll::Ready(data.result.take().unwrap())
995 }
996 }
997}
998
999unsafe fn get_waker_data<'a, D>(cx: &'a mut Context<'_>) -> &'a mut D {
1000 // technically not guaranteed to sound,
1001 // but it's a temporary solution until waker_getters feature is stabilized
1002 &mut **(cx.waker() as *const _ as *const *mut D)
1003}
1004
1005struct GetOuterWaker;
1006impl Future for GetOuterWaker {
1007 type Output = Waker;
1008
1009 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1010 Poll::Ready(cx.waker().clone())
1011 }
1012}
1013
1014// /// Struct to delegate future to the outer executor
1015// pub struct WithExecutor<Fut, T, R>(pub Fut, WakerData<T, R>);
1016// impl<Fut: Future, T, R> Future for WithExecutor<Fut, T, R> {
1017// type Output = Fut::Output;
1018//
1019// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1020// let (inner, data) = unsafe {
1021// let this = self.get_unchecked_mut();
1022// (Pin::new_unchecked(&mut this.0), &mut this.1)
1023// };
1024// let outer_waker = cx.waker().clone();
1025// data.outer_waker = outer_waker;
1026// let waker = waker_with_data(data);
1027// let mut ctx = Context::from_waker(&waker);
1028// inner.poll(&mut ctx)
1029// }
1030// }
1031
1032/// Indicates what action should be performed on stack afterwards
1033pub enum Action<T, Y = (), R = ()> {
1034 /// Pushes state to the internal stack. Equivalent of doing a recursive call.
1035 Recurse(T),
1036 /// Stops everything and yields from whole recursion process.
1037 /// Whether the current stack is preserved depends on a function being used.
1038 Yield(Y),
1039 /// Pops state from stack. Equivalent of returning from recursion call.
1040 Return(R),
1041}
1042
1043struct ChainArena<T, const CHUNK_SIZE: usize> {
1044 // filled: Cell<usize>,
1045 buf: arrayvec::ArrayVec<T, CHUNK_SIZE>,
1046 next: Option<Box<Self>>,
1047}
1048
1049impl<T, const CHUNK_SIZE: usize> ChainArena<T, CHUNK_SIZE> {
1050 fn new() -> Self {
1051 Self {
1052 buf: arrayvec::ArrayVec::new(),
1053 next: None,
1054 }
1055 }
1056
1057 fn push(&mut self, el: T) {
1058 self.buf.try_push(el).unwrap_or_else(|e| {
1059 if let Err(err) = self
1060 .next
1061 .get_or_insert_with(|| Box::new(Self::new()))
1062 .buf
1063 .try_push(e.element())
1064 {
1065 let next = self.next.replace(Box::new(Self::new()));
1066 self.next.as_deref_mut().unwrap().next = next;
1067 self.next
1068 .as_deref_mut()
1069 .unwrap()
1070 .buf
1071 .try_push(err.element())
1072 .expect("should be able to push in empty ArrayVec");
1073 }
1074 });
1075 }
1076
1077 fn pop(&mut self) -> Option<T> {
1078 // let buf = &mut self.buf;
1079
1080 let tmp = self
1081 .next
1082 .as_deref_mut()
1083 .and_then(|x| x.buf.pop())
1084 .or_else(|| self.buf.pop());
1085
1086 if let Some(next) = self.next.as_deref_mut() {
1087 if next.buf.len() == 0 {
1088 let tmp = self.next.take();
1089 self.next = tmp.unwrap().next.take();
1090 }
1091 }
1092 tmp
1093 }
1094
1095 fn last_mut(&mut self) -> Option<&mut T> {
1096 self.next
1097 .as_deref_mut()
1098 .and_then(|x| x.buf.last_mut())
1099 .or_else(|| self.buf.last_mut())
1100 }
1101
1102 fn is_empty(&self) -> bool {
1103 self.buf.is_empty()
1104 }
1105
1106 fn dbg_len(&self) -> usize {
1107 self.buf.len() + self.next.as_ref().map_or(0, |x| x.dbg_len())
1108 }
1109}
1110
1111// explicit Drop exists to drop stuff in reverse order
1112impl<T, const CHUNK_SIZE: usize> Drop for ChainArena<T, CHUNK_SIZE> {
1113 fn drop(&mut self) {
1114 while self.pop().is_some() {}
1115 }
1116}
1117
1118#[cfg(test)]
1119mod test {
1120 use crate::ChainArena;
1121
1122 #[test]
1123 fn test_cap1() {
1124 test_cap::<1>();
1125 test_cap::<2>();
1126 test_cap::<10>();
1127 test_cap::<20>();
1128 }
1129
1130 fn test_cap<const SIZE: usize>() {
1131 let mut x = ChainArena::<_, SIZE>::new();
1132 for i in 0..10 {
1133 x.push(i);
1134 assert_eq!(*x.last_mut().unwrap(), i);
1135 }
1136
1137 for i in (0..10).rev() {
1138 assert_eq!(*x.last_mut().unwrap(), i);
1139 assert_eq!(x.pop(), Some(i));
1140 }
1141 }
1142}
1143//
1144// pub trait MyFnOnce<T> {
1145// type Output;
1146//
1147// fn call(self, arg: T) -> Self::Output;
1148// }
1149//
1150// impl<T, F, O> MyFnOnce<T> for F
1151// where
1152// F: FnOnce(T) -> O,
1153// {
1154// type Output = O;
1155//
1156// fn call(self, arg: T) -> Self::Output {
1157// self(arg)
1158// }
1159// }
1160
1161// struct BorrowHList<'a, Head, Tail>(pub Head, MaybeUninit<Tail>);
1162//
1163// struct Nil;
1164//
1165// impl<'a, H> BorrowHList<'a, H, Nil> {
1166// pub fn new(first: H) -> Self {
1167// Self(first, Nil, PhantomData)
1168// }
1169// }
1170//
1171// impl<'a, H, T> BorrowHList<'a, H, T> {
1172// pub fn push_with<F, R>(self, next: F) -> BorrowHList<'a, R, Self>
1173// where
1174// H: for<'x> WithLifetime<'x, 'a>,
1175// R: for<'x> WithLifetime<'x, 'a>,
1176// F: FnOnce(&'a mut H) -> R + 'static,
1177// {
1178// BorrowHList()
1179// }
1180//
1181// pub fn pop(self) -> T {
1182// unsafe { self.1.assume_init() }
1183// }
1184// }
1185
1186// todo add marker to allow implementations on foreign traits
1187/// Trait to be able to apply HRTBs to arbitrary types
1188/// Can be safely implemented by users for their own types.
1189/// Soundness is ensured by the sealed `Check` trait which is implemented in a way
1190/// that allows only correct `WithLifetime` implementations.
1191///
1192/// Note that if multiple lifetimes are involved the lifetime that is being changed must be the smallest one.
1193/// You might need to add corresponding bounds when implementing it.
1194/// It is a temporary limitation caused by a compiler bug.
1195/// For example notice additional `'b: 'this` here that makes sure that `'this` is smallest lifetime here.
1196/// ```rust
1197/// # use unrecurse::{Lifetime, WithLifetime};
1198/// struct Test<'a, 'b>(&'a (),&'b ());
1199/// impl<'applied, 'this, 'b: 'this> WithLifetime<'applied> for Test<'this, 'b> {
1200/// type Lifetime = Lifetime<'this>;
1201/// type Applied = Test<'applied, 'b>;
1202/// }
1203///
1204/// fn test<T: for<'x> WithLifetime<'x>>() {}
1205/// fn call<'a, 'b: 'a>() {
1206/// test::<Test<'a, 'b>>();
1207/// }
1208/// ```
1209/// It does impose some limitations(in this case `'b: 'a` bound on `call` that shouldn't be needed),
1210/// but in practice it is pretty rare to cause actual problems.
1211pub trait WithLifetime<'a, T = &'a Self>: Check<Self::Lifetime> /*+ HasGeneric*/ {
1212 /// There is no way to have an associated lifetime in Rust.
1213 /// This type acts as a workaround for that.
1214 /// [`Lifetime`] struct is the only suitable type here.
1215 type Lifetime: LifetimeMarker;
1216 /// This should be a `Self` but with [`Self::Lifetime`] lifetime changed to `'a`.
1217 /// Otherwise you will get a compile error
1218 type Applied;
1219 #[doc(hidden)]
1220 unsafe fn with_lifetime(&self) -> &Self::Applied {
1221 transmute_copy(&self)
1222 }
1223
1224 #[doc(hidden)]
1225 unsafe fn with_lifetime_mut(mut self: &mut Self) -> &mut Self::Applied {
1226 transmute_copy(&mut self)
1227 }
1228
1229 #[doc(hidden)]
1230 unsafe fn move_with_lifetime(self) -> Self::Applied
1231 where
1232 Self: Sized,
1233 Self::Applied: Sized,
1234 {
1235 let this = ManuallyDrop::new(self);
1236 let res = transmute_copy(&*this);
1237 res
1238 }
1239
1240 #[doc(hidden)]
1241 unsafe fn move_with_lifetime_back(this: Self::Applied) -> Self
1242 where
1243 Self: Sized,
1244 Self::Applied: Sized,
1245 {
1246 let this = ManuallyDrop::new(this);
1247 let res = transmute_copy(&*this);
1248 res
1249 }
1250}
1251
1252/// Type that represents associated lifetime in [`WithLifetime::Lifetime`]
1253pub struct Lifetime<'a>(PhantomData<*mut &'a ()>);
1254
1255use private::Check;
1256use private::LifetimeMarker;
1257
1258mod private {
1259 use super::*;
1260
1261 pub trait LifetimeMarker {}
1262 impl<'a> LifetimeMarker for Lifetime<'a> {}
1263
1264 pub trait Check<L: LifetimeMarker> {}
1265 impl<'b, T> Check<Lifetime<'b>> for T where
1266 T: WithLifetime<'b, Lifetime = Lifetime<'b>, Applied = Self> + 'b // <T as HasGeneric>::Generic: 'b,
1267 {
1268 }
1269}
1270
1271// usable with HRTBs,
1272// /// Due to bug in compiler HRTB with `WithLifetime` trait does not work,
1273// /// so workaround is to use a separate trait with implied weaker bounds.
1274// /// Unfortunately due to another bug in compiler blanket implementation of that trait also does not work properly.
1275// /// So you need to duplicate the implementation of `WithLifetime` for `ShrinkLifetime`.
1276// ///
1277// ///
1278// pub trait ShrinkLifetime<'a, T = &'a <Self as HasGeneric>::Generic>:
1279// WithLifetime<Lifetime<'a>, Applied = Self::BoundApplied> + HasGeneric
1280// // + WithLifetime<Lifetime<'a>, Lifetime = Lifetime<'a>, Applied = Self>
1281// {
1282// type BoundApplied: WithLifetime<Self::Lifetime, Lifetime = Lifetime<'a>, Applied = Self>;
1283// }
1284
1285// trait ShrinkLifetime<'a>: WithLifetime<Lifetime<'a>> {
1286// type BoundApplied: WithLifetime<Self::Lifetime, Lifetime = Lifetime<'a>, Applied = Self>;
1287// }
1288
1289// /// Workaround for some compiler limitations when checking HRTBs.
1290// pub trait HasGeneric {
1291// /// This should be a tuple of generics that are bound by the lifetime you are going to change in `WithLifetime`
1292// /// Otherwise you will get a ``error[E0311]: the parameter type `T` may not live long enough``
1293// /// E.g. if you have `&'a mut T` and you are changing `'a` lifetime, then `Generic` should be `T`
1294// /// if you have `&'a &'b()` and you are changing `'a` lifetime, then `Generic` should be
1295// /// some type with `'b` lifetime, for example `&'b ()`.
1296// /// Note that in latter case due to compiler bugs you will need to explicitly write out generic
1297// /// parameter of `Withlifetime` trait.
1298// /// ```text
1299// /// impl<'a,'b,'new> WithLifetime<'new,&'new &'b ()> for &'a &'b (){
1300// /// ```
1301// type Generic;
1302// }
1303// pub trait ImplicitBound<'a, T = &'a <Self as HasGeneric>::Generic>: HasGeneric {}
1304// impl<'a, T: HasGeneric> ImplicitBound<'a> for T {}
1305
1306// pub trait ImplicitGeneric<T: LifetimeMarkerExt<Self>,> {}
1307
1308// impl<'a, T, Appl> ShrinkLifetime<'a> for T
1309// where
1310// T: WithLifetime<Lifetime<'a>, Applied = Appl>,
1311// Appl: WithLifetime<Self::Lifetime, Lifetime = Lifetime<'a>, Applied = Self>,
1312// {
1313// type BoundApplied = Appl;
1314// }
1315
1316// pub unsafe trait Tid<'a>: 'a {
1317// fn self_id(&self) -> TypeId;
1318// fn id() -> TypeId
1319// where
1320// Self: Sized;
1321// }
1322
1323// unsafe impl<'a, T: 'a> Tid<'a> for T
1324// where
1325// T: WithLifetime<Lifetime<'static>, Lifetime = Lifetime<'a>>,
1326// <T as WithLifetime<Lifetime<'static>>>::Applied: 'static
1327// {
1328// fn self_id(&self) -> TypeId {
1329// Self::id()
1330// }
1331// fn id() -> TypeId
1332// where
1333// Self: Sized,
1334// {
1335// TypeId::of::<T::Applied>()
1336// }
1337// }
1338
1339// trait WithLifetimeSuper<'a>: WithLifetime<'a> + WithLifetimeGeneric<>
1340
1341impl<'applied, 'this, T> WithLifetime<'applied> for &'this T {
1342 type Lifetime = Lifetime<'this>;
1343 type Applied = &'applied T;
1344}
1345//
1346// impl<'this, T> HasGeneric for &'this T {
1347// type Generic = (T);
1348// }
1349// impl<'a, 'this, T> ShrinkLifetime<'a> for &'this T {
1350// type BoundApplied = &'a T;
1351// }
1352
1353impl<'applied, 'this, T> WithLifetime<'applied> for &'this mut T {
1354 type Lifetime = Lifetime<'this>;
1355 type Applied = &'applied mut T;
1356}
1357
1358// impl<'this, T> HasGeneric for &'this mut T {
1359// type Generic = T;
1360// }
1361// impl<'a, 'this, T> ShrinkLifetime<'a> for &'this mut T {
1362// type BoundApplied = &'a mut T;
1363// }
1364
1365impl<'applied> WithLifetime<'applied> for () {
1366 type Lifetime = Lifetime<'applied>;
1367 type Applied = ();
1368}
1369
1370// impl HasGeneric for () {
1371// type Generic = ();
1372// }
1373// impl<'a> ShrinkLifetime<'a> for () {
1374// type BoundApplied = ();
1375// }
1376
1377macro_rules! std_impl {
1378 ($($type:tt)+) => {
1379 impl<'a, 'this,T> WithLifetime<'a> for $($type)+<'this, T> {
1380 type Lifetime = Lifetime<'this>;
1381 type Applied = $($type)+<'a, T>;
1382 }
1383 };
1384}
1385
1386std_impl! {core::cell::Ref}
1387std_impl! {core::cell::RefMut}
1388std_impl! {std::sync::MutexGuard}
1389std_impl! {std::sync::RwLockReadGuard}
1390std_impl! {std::sync::RwLockWriteGuard}
1391
1392// this was initial idea but it had two lifetimes which created some problems
1393// but it more clearly represents the idea so
1394mod old {
1395 /// Trait that indicates that the type has a lifetime and that lifetime can be manipulated in type-system.
1396 /// Sealed `Check` trait allows `WithLifetime` to be a safe to implement trait.
1397 ///
1398 /// `Marker` type parameter allows to implement `WithLifetime` on foreign traits by defining your own marker type.
1399 /// But it is not yet used by this crate so just ignore it for now.
1400 pub trait WithLifetime<'applied, 'this, Marker = ()/*, const LIFETIME_INDEX: usize = 0*/>:
1401 Check<'this, Marker>
1402 {
1403 /// This should be a `Self` but with `'this` lifetime changed to `'applied`
1404 type Applied: WithLifetime<'this, 'applied, Marker, Applied=Self>;
1405
1406 #[doc(hidden)]
1407 unsafe fn with_lifetime(&self) -> &Self::Applied {
1408 transmute_copy(&self)
1409 }
1410
1411 #[doc(hidden)]
1412 unsafe fn with_lifetime_mut(mut self: &mut Self) -> &mut Self::Applied {
1413 transmute_copy(&mut self)
1414 }
1415
1416 #[doc(hidden)]
1417 unsafe fn move_with_lifetime(self) -> Self::Applied
1418 where
1419 Self: Sized,
1420 Self::Applied: Sized,
1421 {
1422 let this = ManuallyDrop::new(self);
1423 let res = transmute_copy(&*this);
1424 res
1425 }
1426
1427 #[doc(hidden)]
1428 unsafe fn move_with_lifetime_back(this: Self::Applied) -> Self
1429 where
1430 Self: Sized,
1431 Self::Applied: Sized,
1432 {
1433 let this = ManuallyDrop::new(this);
1434 let res = transmute_copy(&*this);
1435 res
1436 }
1437 }
1438
1439 use private::Check;
1440 use std::mem::{transmute_copy, ManuallyDrop};
1441
1442 mod private {
1443 pub trait Check<'a, Marker>: 'a {}
1444
1445 impl<'a, Marker, T /*+ ?Sized*/> Check<'a, Marker> for T where
1446 T: super::WithLifetime<'a, 'a, Marker, Applied = Self>
1447 {
1448 }
1449 }
1450
1451 impl<'applied, 'this, T> WithLifetime<'applied, 'this> for &'this T
1452 where
1453 T: 'applied + 'this,
1454 {
1455 type Applied = &'applied T;
1456 }
1457
1458 impl<'applied, 'this> WithLifetime<'applied, 'this> for () {
1459 type Applied = ();
1460 }
1461
1462 impl<'applied, 'this, T: 'applied + 'this> WithLifetime<'applied, 'this> for &'this mut T {
1463 type Applied = &'applied mut T;
1464 }
1465
1466 struct Identity;
1467
1468 impl<'applied, 'this, T: 'applied + 'this> WithLifetime<'applied, 'this, Identity> for T {
1469 type Applied = T;
1470 }
1471}
1472
1473// trait BorrowStack<'a> {
1474// fn push()
1475// }
1476
1477// impl<T,M> Index<usize> for RefStack<'_, T,M>{
1478// type Output = M;
1479//
1480// fn index(&self, index: usize) -> &Self::Output {
1481// unsafe { &*self.metadata[index] }
1482// }
1483// }
1484// impl<T,M> IndexMut<usize> for RefStack<'_, T,M>{
1485// fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1486// unsafe { &mut *self.metadata[index] }
1487// }
1488// }
1489
1490//temporary copy from `aliasable` until they publish fixed version
1491#[doc(hidden)]
1492pub struct AliasableMut<'a, T: ?Sized> {
1493 inner: NonNull<T>,
1494 _lifetime: PhantomData<&'a mut T>,
1495}
1496
1497impl<'a, T: ?Sized> AliasableMut<'a, T> {
1498 /// Construct an `AliasableMut` from an `&mut`.
1499 #[inline]
1500 pub fn from_unique(ptr: &'a mut T) -> Self {
1501 Self {
1502 inner: NonNull::from(ptr),
1503 _lifetime: PhantomData,
1504 }
1505 }
1506}
1507impl<'a, T: ?Sized> From<&'a mut T> for AliasableMut<'a, T> {
1508 fn from(ptr: &'a mut T) -> Self {
1509 Self::from_unique(ptr)
1510 }
1511}
1512
1513impl<T: ?Sized> Deref for AliasableMut<'_, T> {
1514 type Target = T;
1515
1516 #[inline]
1517 fn deref(&self) -> &Self::Target {
1518 // SAFETY: It is the callers responsibility to make sure that there are no `&mut`
1519 // references at this point.
1520 unsafe { self.inner.as_ref() }
1521 }
1522}
1523
1524impl<T: ?Sized> DerefMut for AliasableMut<'_, T> {
1525 #[inline]
1526 fn deref_mut(&mut self) -> &mut Self::Target {
1527 // SAFETY: It is the callers responsibility to make sure that there are no `&mut`
1528 // references at this point.
1529 unsafe { self.inner.as_mut() }
1530 }
1531}
1532unsafe impl<T: ?Sized> Send for AliasableMut<'_, T> where T: Send {}
1533unsafe impl<T: ?Sized> Sync for AliasableMut<'_, T> where T: Sync {}