1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#![cfg_attr(feature = "nightly", feature(generator_trait))]

mod generator;
mod generator_state;

pub use generator::Generator;
pub use generator_state::GeneratorState;

#[cfg(feature = "macro")]
/// A procedural macro that may be used to produce a generator type.
///
/// The produced value will be an opaque implementation of
/// `generate::Generator<R>`. `R`, `Generator::Yield` and
/// `Generator::Return` will all be automatically inferred by the
/// compiler. Note that this behaviour is slightly different than
/// a normal nightly-compiled generator.
///
/// # Differences compared to nightly
///
/// The key difference is that nightly generators will *always*
/// implement `Generator<()>` whereas this crate is able to implement
/// `Generator<R>` for any `R`. The following two rules are used to
/// resolve an appropriate `R` to implement for:
///
/// * If `yield` is only ever used in statement position within the
///   body of the generator, then `R` will be `()`.
/// * Otherwise, if `yield` is used in expression position, then let
///   the rust compiler automatically infer the appropriate type for
///   `R`.
///
/// In the latter case, when the rust compiler cannot infer an
/// appropriate type for `R`, then the following error is produced
/// (as of `rustc 1.49.0`):
///
/// ```text
/// error[E0698]: type inside `async` block must be known in this context
///   --> generate-test/src/lib.rs:76:5
///    |
/// 76 | /     generator! {
/// 77 | |         let val = yield;
/// 78 | |     };
///    | |______^ cannot infer type for type parameter `R` declared on the function `yield_future`
///    |
/// ```
///
/// This is because the internal implementation of this macro takes
/// advantage of the state machine transform performed by the compiler
/// within an `async` block in order to build the generator.
///
/// The following error occurs when the compiler cannot infer an
/// appropriate type for `Generator::Yield`:
///
/// ```text
/// error[E0282]: type annotations needed
///   --> generate-test/src/lib.rs:76:5
///    |
/// 76 | /     generator! {
/// 77 | |         ()
/// 78 | |     };
///    | |______^ consider giving this closure parameter a type
///    |
/// ```
pub use generate_derive::generator;

#[doc(hidden)]
pub mod __support;