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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
/// The result of a generator resumption. /// /// This enum is returned from the `Generator::resume` method and indicates the /// possible return values of a generator. Currently this corresponds to either /// a suspension point (`Yielded`) or a termination point (`Complete`). #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] #[lang = "generator_state"] #[unstable(feature = "generator_trait", issue = "43122")] pub enum GeneratorState<Y, R> { /// The generator suspended with a value. /// /// This state indicates that a generator has been suspended, and typically /// corresponds to a `yield` statement. The value provided in this variant /// corresponds to the expression passed to `yield` and allows generators to /// provide a value each time they yield. Yielded(Y), /// The generator completed with a return value. /// /// This state indicates that a generator has finished execution with the /// provided value. Once a generator has returned `Complete` it is /// considered a programmer error to call `resume` again. Complete(R), } /// The trait implemented by builtin generator types. /// /// Generators, also commonly referred to as coroutines, are currently an /// experimental language feature in Rust. Added in [RFC 2033] generators are /// currently intended to primarily provide a building block for async/await /// syntax but will likely extend to also providing an ergonomic definition for /// iterators and other primitives. /// /// The syntax and semantics for generators is unstable and will require a /// further RFC for stabilization. At this time, though, the syntax is /// closure-like: /// /// ```rust /// #![feature(generators, generator_trait)] /// /// use std::ops::{Generator, GeneratorState}; /// /// fn main() { /// let mut generator = || { /// yield 1; /// return "foo" /// }; /// /// match unsafe { generator.resume() } { /// GeneratorState::Yielded(1) => {} /// _ => panic!("unexpected return from resume"), /// } /// match unsafe { generator.resume() } { /// GeneratorState::Complete("foo") => {} /// _ => panic!("unexpected return from resume"), /// } /// } /// ``` /// /// More documentation of generators can be found in the unstable book. /// /// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033 #[lang = "generator"] #[unstable(feature = "generator_trait", issue = "43122")] #[fundamental] pub trait Generator { /// The type of value this generator yields. /// /// This associated type corresponds to the `yield` expression and the /// values which are allowed to be returned each time a generator yields. /// For example an iterator-as-a-generator would likely have this type as /// `T`, the type being iterated over. type Yield; /// The type of value this generator returns. /// /// This corresponds to the type returned from a generator either with a /// `return` statement or implicitly as the last expression of a generator /// literal. For example futures would use this as `Result<T, E>` as it /// represents a completed future. type Return; /// Resumes the execution of this generator. /// /// This function will resume execution of the generator or start execution /// if it hasn't already. This call will return back into the generator's /// last suspension point, resuming execution from the latest `yield`. The /// generator will continue executing until it either yields or returns, at /// which point this function will return. /// /// The function is unsafe because it can be used on an immovable generator. /// After such a call, the immovable generator must not move again, but /// this is not enforced by the compiler. /// /// # Return value /// /// The `GeneratorState` enum returned from this function indicates what /// state the generator is in upon returning. If the `Yielded` variant is /// returned then the generator has reached a suspension point and a value /// has been yielded out. Generators in this state are available for /// resumption at a later point. /// /// If `Complete` is returned then the generator has completely finished /// with the value provided. It is invalid for the generator to be resumed /// again. /// /// # Panics /// /// This function may panic if it is called after the `Complete` variant has /// been returned previously. While generator literals in the language are /// guaranteed to panic on resuming after `Complete`, this is not guaranteed /// for all implementations of the `Generator` trait. unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return>; } #[unstable(feature = "generator_trait", issue = "43122")] impl<T> Generator for &mut T where T: Generator + ?Sized { type Yield = T::Yield; type Return = T::Return; unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> { (**self).resume() } }