genawaiter/stack/
macros.rs

1/**
2Creates a generator on the stack.
3
4This macro is deprecated. Use [`let_gen!`] or [`let_gen_using!`] instead.
5
6[`let_gen!`]: stack/macro.let_gen.html
7[`let_gen_using!`]: stack/macro.let_gen_using.html
8*/
9#[macro_export]
10#[deprecated = "Use `let_gen_using!()` instead."]
11macro_rules! generator_mut {
12    ($name:ident, $producer:expr $(,)?) => {
13        $crate::stack::let_gen_using!($name, $producer);
14    };
15}
16
17/**
18Creates a generator on the stack unsafely.
19
20This macro is deprecated. Use [`let_gen!`] or [`let_gen_using!`] instead.
21
22[`let_gen!`]: stack/macro.let_gen.html
23[`let_gen_using!`]: stack/macro.let_gen_using.html
24*/
25#[macro_export]
26#[deprecated = "Use `let_gen_using!()` instead."]
27macro_rules! unsafe_create_generator {
28    ($name:ident, $producer:expr $(,)?) => {
29        let mut generator_state = $crate::stack::Shelf::new();
30        #[allow(unused_mut)]
31        let mut $name =
32            unsafe { $crate::stack::Gen::new(&mut generator_state, $producer) };
33    };
34}
35
36#[cfg(test)]
37mod tests {
38    use crate::{
39        ops::GeneratorState,
40        stack::{Co, Gen, Shelf},
41    };
42
43    /// This test proves that `Gen::new` is actually unsafe.
44    #[test]
45    #[ignore = "compile-only test"]
46    fn unsafety() {
47        async fn shenanigans(co: Co<'_, i32>) -> Co<'_, i32> {
48            co
49        }
50
51        let mut shelf = Shelf::new();
52        let mut gen = unsafe { Gen::new(&mut shelf, shenanigans) };
53
54        // Get the `co` out of the generator (don't try this at home).
55        let escaped_co = match gen.resume() {
56            GeneratorState::Yielded(_) => panic!(),
57            GeneratorState::Complete(co) => co,
58        };
59        // Drop the generator. This drops the airlock (inside the state), but `co` still
60        // holds a reference to the airlock.
61        drop(gen);
62        // Now we're able to use an invalidated reference.
63        let _ = escaped_co.yield_(10);
64    }
65}
66
67#[allow(dead_code)]
68mod doctests {
69    /**
70    ```compile_fail
71    use genawaiter::{stack::{let_gen_using, Co}, Generator};
72
73    async fn producer(co: Co<'_, i32>) {}
74
75    fn create_generator() -> impl Generator {
76        let_gen_using!(gen, producer);
77        gen
78    }
79    ```
80    */
81    fn generator_cannot_escape() {}
82
83    /**
84    This test is exactly the same as above, but doesn't trigger the failure.
85
86    ```
87    use genawaiter::{stack::{let_gen_using, Co}, Generator};
88
89    async fn producer(co: Co<'_, i32>) {}
90
91    fn create_generator() { // -> impl Generator {
92        let_gen_using!(gen, producer);
93        // gen
94    }
95    ```
96    */
97    fn generator_cannot_escape_baseline() {}
98}