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}