about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2022-04-21 23:47:39 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2022-05-27 01:51:31 +0300
commit5bf23f64cce3877434da31e74e376186986903a2 (patch)
tree0660c716fab908b0ae60c7beaa86ceda97f571fb
parent490324f7b29d5f1a1e063a563045d790091ed639 (diff)
downloadrust-5bf23f64cce3877434da31e74e376186986903a2.tar.gz
rust-5bf23f64cce3877434da31e74e376186986903a2.zip
libcore: Add `iter::from_generator` which is like `iter::from_fn`, but for coroutines instead of functions
-rw-r--r--compiler/rustc_data_structures/src/lib.rs25
-rw-r--r--compiler/rustc_metadata/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs4
-rw-r--r--library/core/src/iter/mod.rs6
-rw-r--r--library/core/src/iter/sources.rs8
-rw-r--r--library/core/src/iter/sources/from_generator.rs43
-rw-r--r--src/test/ui/async-await/issue-68112.stderr4
-rw-r--r--src/test/ui/async-await/partial-drop-partial-reinit.stderr2
-rw-r--r--src/test/ui/chalkify/bugs/async.stderr8
9 files changed, 67 insertions, 34 deletions
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 76ae17f28c6..0d072046d58 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -13,8 +13,6 @@
 #![feature(control_flow_enum)]
 #![feature(core_intrinsics)]
 #![feature(extend_one)]
-#![feature(generator_trait)]
-#![feature(generators)]
 #![feature(let_else)]
 #![feature(hash_raw_entry)]
 #![feature(hasher_prefixfree_extras)]
@@ -114,9 +112,6 @@ pub mod unhash;
 pub use ena::undo_log;
 pub use ena::unify;
 
-use std::ops::{Generator, GeneratorState};
-use std::pin::Pin;
-
 pub struct OnDrop<F: Fn()>(pub F);
 
 impl<F: Fn()> OnDrop<F> {
@@ -135,26 +130,6 @@ impl<F: Fn()> Drop for OnDrop<F> {
     }
 }
 
-struct IterFromGenerator<G>(G);
-
-impl<G: Generator<Return = ()> + Unpin> Iterator for IterFromGenerator<G> {
-    type Item = G::Yield;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        match Pin::new(&mut self.0).resume(()) {
-            GeneratorState::Yielded(n) => Some(n),
-            GeneratorState::Complete(_) => None,
-        }
-    }
-}
-
-/// An adapter for turning a generator closure into an iterator, similar to `iter::from_fn`.
-pub fn iter_from_generator<G: Generator<Return = ()> + Unpin>(
-    generator: G,
-) -> impl Iterator<Item = G::Yield> {
-    IterFromGenerator(generator)
-}
-
 // See comments in src/librustc_middle/lib.rs
 #[doc(hidden)]
 pub fn __noop_fix_for_27438() {}
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 4c5d13dfa6c..eb008fd2693 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -3,6 +3,7 @@
 #![feature(drain_filter)]
 #![feature(generators)]
 #![feature(generic_associated_types)]
+#![feature(iter_from_generator)]
 #![feature(let_chains)]
 #![feature(let_else)]
 #![feature(nll)]
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 63103061c9c..339d2fc0867 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -4,7 +4,6 @@ use crate::rmeta::*;
 
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
-use rustc_data_structures::iter_from_generator;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator};
 use rustc_hir as hir;
@@ -39,6 +38,7 @@ use rustc_span::{
 use rustc_target::abi::VariantIdx;
 use std::borrow::Borrow;
 use std::hash::Hash;
+use std::iter;
 use std::num::NonZeroUsize;
 use tracing::{debug, trace};
 
@@ -1134,7 +1134,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             // Encode this here because we don't do it in encode_def_ids.
             record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
         } else {
-            record_array!(self.tables.children[def_id] <- iter_from_generator(|| {
+            record_array!(self.tables.children[def_id] <- iter::from_generator(|| {
                 for item_id in md.item_ids {
                     match tcx.hir().item(*item_id).kind {
                         // Foreign items are planted into their parent modules
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index 22b76ea66ff..15362d2330a 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -362,6 +362,12 @@ pub use self::traits::Iterator;
 )]
 pub use self::range::Step;
 
+#[unstable(
+    feature = "iter_from_generator",
+    issue = "43122",
+    reason = "generators are unstable"
+)]
+pub use self::sources::from_generator;
 #[stable(feature = "iter_empty", since = "1.2.0")]
 pub use self::sources::{empty, Empty};
 #[stable(feature = "iter_from_fn", since = "1.34.0")]
diff --git a/library/core/src/iter/sources.rs b/library/core/src/iter/sources.rs
index 37b6f2e2565..d34772cd304 100644
--- a/library/core/src/iter/sources.rs
+++ b/library/core/src/iter/sources.rs
@@ -1,5 +1,6 @@
 mod empty;
 mod from_fn;
+mod from_generator;
 mod once;
 mod once_with;
 mod repeat;
@@ -21,6 +22,13 @@ pub use self::repeat_with::{repeat_with, RepeatWith};
 #[stable(feature = "iter_from_fn", since = "1.34.0")]
 pub use self::from_fn::{from_fn, FromFn};
 
+#[unstable(
+    feature = "iter_from_generator",
+    issue = "43122",
+    reason = "generators are unstable"
+)]
+pub use self::from_generator::from_generator;
+
 #[stable(feature = "iter_successors", since = "1.34.0")]
 pub use self::successors::{successors, Successors};
 
diff --git a/library/core/src/iter/sources/from_generator.rs b/library/core/src/iter/sources/from_generator.rs
new file mode 100644
index 00000000000..8e7cbd34a4f
--- /dev/null
+++ b/library/core/src/iter/sources/from_generator.rs
@@ -0,0 +1,43 @@
+use crate::ops::{Generator, GeneratorState};
+use crate::pin::Pin;
+
+/// Creates a new iterator where each iteration calls the provided generator.
+///
+/// Similar to [`iter::from_fn`].
+///
+/// [`iter::from_fn`]: crate::iter::from_fn
+///
+/// # Examples
+///
+/// ```
+/// #![feature(generators)]
+/// #![feature(iter_from_generator)]
+///
+/// let it = std::iter::from_generator(|| {
+///     yield 1;
+///     yield 2;
+///     yield 3;
+/// });
+/// let v: Vec<_> = it.collect();
+/// assert_eq!(v, [1, 2, 3]);
+/// ```
+#[inline]
+#[unstable(feature = "iter_from_generator", issue = "43122", reason = "generators are unstable")]
+pub fn from_generator<G: Generator<Return = ()> + Unpin>(
+    generator: G,
+) -> impl Iterator<Item = G::Yield> {
+    FromGenerator(generator)
+}
+
+struct FromGenerator<G>(G);
+
+impl<G: Generator<Return = ()> + Unpin> Iterator for FromGenerator<G> {
+    type Item = G::Yield;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match Pin::new(&mut self.0).resume(()) {
+            GeneratorState::Yielded(n) => Some(n),
+            GeneratorState::Complete(()) => None,
+        }
+    }
+}
diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr
index 36b7f2e4558..28d94b14ac9 100644
--- a/src/test/ui/async-await/issue-68112.stderr
+++ b/src/test/ui/async-await/issue-68112.stderr
@@ -43,13 +43,13 @@ LL |     require_send(send_fut);
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
    = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36]`
-   = note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36]>`
+   = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36]>`
    = note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
    = note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
    = note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
    = note: required because it appears within the type `{ResumeTy, impl Future<Output = Arc<RefCell<i32>>>, (), i32, Ready<i32>}`
    = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6]`
-   = note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6]>`
+   = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6]>`
    = note: required because it appears within the type `impl Future<Output = ()>`
 note: required by a bound in `require_send`
   --> $DIR/issue-68112.rs:11:25
diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.stderr b/src/test/ui/async-await/partial-drop-partial-reinit.stderr
index 7c074b07c3d..a1c4957e984 100644
--- a/src/test/ui/async-await/partial-drop-partial-reinit.stderr
+++ b/src/test/ui/async-await/partial-drop-partial-reinit.stderr
@@ -13,7 +13,7 @@ LL | async fn foo() {
    = note: required because it appears within the type `(NotSend,)`
    = note: required because it appears within the type `{ResumeTy, (NotSend,), impl Future<Output = ()>, ()}`
    = note: required because it appears within the type `[static generator@$DIR/partial-drop-partial-reinit.rs:22:16: 27:2]`
-   = note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/partial-drop-partial-reinit.rs:22:16: 27:2]>`
+   = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/partial-drop-partial-reinit.rs:22:16: 27:2]>`
    = note: required because it appears within the type `impl Future<Output = ()>`
    = note: required because it appears within the type `impl Future<Output = ()>`
 note: required by a bound in `gimme_send`
diff --git a/src/test/ui/chalkify/bugs/async.stderr b/src/test/ui/chalkify/bugs/async.stderr
index e6a72c72dd3..5b7ca8d46cf 100644
--- a/src/test/ui/chalkify/bugs/async.stderr
+++ b/src/test/ui/chalkify/bugs/async.stderr
@@ -7,11 +7,11 @@ LL | |     x
 LL | | }
    | |_^ the trait `Generator<ResumeTy>` is not implemented for `[static generator@$DIR/async.rs:7:29: 9:2]`
    |
-note: required by a bound in `from_generator`
+note: required by a bound in `std::future::from_generator`
   --> $SRC_DIR/core/src/future/mod.rs:LL:COL
    |
 LL |     T: Generator<ResumeTy, Yield = ()>,
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `from_generator`
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `std::future::from_generator`
 
 error[E0280]: the requirement `<[static generator@$DIR/async.rs:7:29: 9:2] as Generator<ResumeTy>>::Yield == ()` is not satisfied
   --> $DIR/async.rs:7:29
@@ -22,11 +22,11 @@ LL | |     x
 LL | | }
    | |_^
    |
-note: required by a bound in `from_generator`
+note: required by a bound in `std::future::from_generator`
   --> $SRC_DIR/core/src/future/mod.rs:LL:COL
    |
 LL |     T: Generator<ResumeTy, Yield = ()>,
-   |                            ^^^^^^^^^^ required by this bound in `from_generator`
+   |                            ^^^^^^^^^^ required by this bound in `std::future::from_generator`
 
 error[E0280]: the requirement `<impl Future<Output = u32> as Future>::Output == u32` is not satisfied
   --> $DIR/async.rs:7:29