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