]> git.lizzy.rs Git - rust.git/blob - src/libcore/ops/generator.rs
Auto merge of #54718 - froydnj:aarch64-ci, r=alexcrichton
[rust.git] / src / libcore / ops / generator.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /// The result of a generator resumption.
12 ///
13 /// This enum is returned from the `Generator::resume` method and indicates the
14 /// possible return values of a generator. Currently this corresponds to either
15 /// a suspension point (`Yielded`) or a termination point (`Complete`).
16 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
17 #[lang = "generator_state"]
18 #[unstable(feature = "generator_trait", issue = "43122")]
19 pub enum GeneratorState<Y, R> {
20     /// The generator suspended with a value.
21     ///
22     /// This state indicates that a generator has been suspended, and typically
23     /// corresponds to a `yield` statement. The value provided in this variant
24     /// corresponds to the expression passed to `yield` and allows generators to
25     /// provide a value each time they yield.
26     Yielded(Y),
27
28     /// The generator completed with a return value.
29     ///
30     /// This state indicates that a generator has finished execution with the
31     /// provided value. Once a generator has returned `Complete` it is
32     /// considered a programmer error to call `resume` again.
33     Complete(R),
34 }
35
36 /// The trait implemented by builtin generator types.
37 ///
38 /// Generators, also commonly referred to as coroutines, are currently an
39 /// experimental language feature in Rust. Added in [RFC 2033] generators are
40 /// currently intended to primarily provide a building block for async/await
41 /// syntax but will likely extend to also providing an ergonomic definition for
42 /// iterators and other primitives.
43 ///
44 /// The syntax and semantics for generators is unstable and will require a
45 /// further RFC for stabilization. At this time, though, the syntax is
46 /// closure-like:
47 ///
48 /// ```rust
49 /// #![feature(generators, generator_trait)]
50 ///
51 /// use std::ops::{Generator, GeneratorState};
52 ///
53 /// fn main() {
54 ///     let mut generator = || {
55 ///         yield 1;
56 ///         return "foo"
57 ///     };
58 ///
59 ///     match unsafe { generator.resume() } {
60 ///         GeneratorState::Yielded(1) => {}
61 ///         _ => panic!("unexpected return from resume"),
62 ///     }
63 ///     match unsafe { generator.resume() } {
64 ///         GeneratorState::Complete("foo") => {}
65 ///         _ => panic!("unexpected return from resume"),
66 ///     }
67 /// }
68 /// ```
69 ///
70 /// More documentation of generators can be found in the unstable book.
71 ///
72 /// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
73 #[lang = "generator"]
74 #[unstable(feature = "generator_trait", issue = "43122")]
75 #[fundamental]
76 pub trait Generator {
77     /// The type of value this generator yields.
78     ///
79     /// This associated type corresponds to the `yield` expression and the
80     /// values which are allowed to be returned each time a generator yields.
81     /// For example an iterator-as-a-generator would likely have this type as
82     /// `T`, the type being iterated over.
83     type Yield;
84
85     /// The type of value this generator returns.
86     ///
87     /// This corresponds to the type returned from a generator either with a
88     /// `return` statement or implicitly as the last expression of a generator
89     /// literal. For example futures would use this as `Result<T, E>` as it
90     /// represents a completed future.
91     type Return;
92
93     /// Resumes the execution of this generator.
94     ///
95     /// This function will resume execution of the generator or start execution
96     /// if it hasn't already. This call will return back into the generator's
97     /// last suspension point, resuming execution from the latest `yield`. The
98     /// generator will continue executing until it either yields or returns, at
99     /// which point this function will return.
100     ///
101     /// The function is unsafe because it can be used on an immovable generator.
102     /// After such a call, the immovable generator must not move again, but
103     /// this is not enforced by the compiler.
104     ///
105     /// # Return value
106     ///
107     /// The `GeneratorState` enum returned from this function indicates what
108     /// state the generator is in upon returning. If the `Yielded` variant is
109     /// returned then the generator has reached a suspension point and a value
110     /// has been yielded out. Generators in this state are available for
111     /// resumption at a later point.
112     ///
113     /// If `Complete` is returned then the generator has completely finished
114     /// with the value provided. It is invalid for the generator to be resumed
115     /// again.
116     ///
117     /// # Panics
118     ///
119     /// This function may panic if it is called after the `Complete` variant has
120     /// been returned previously. While generator literals in the language are
121     /// guaranteed to panic on resuming after `Complete`, this is not guaranteed
122     /// for all implementations of the `Generator` trait.
123     unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return>;
124 }
125
126 #[unstable(feature = "generator_trait", issue = "43122")]
127 impl<T> Generator for &mut T
128     where T: Generator + ?Sized
129 {
130     type Yield = T::Yield;
131     type Return = T::Return;
132     unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> {
133         (**self).resume()
134     }
135 }