Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move {core,std}::stream::Stream to {core,std}::async_iter::AsyncIterator #93613

Merged
merged 1 commit into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
#![stable(feature = "rust1", since = "1.0.0")]

use core::any::Any;
use core::async_iter::AsyncIterator;
use core::borrow;
use core::cmp::Ordering;
use core::convert::{From, TryFrom};
Expand All @@ -149,7 +150,6 @@ use core::ops::{
};
use core::pin::Pin;
use core::ptr::{self, Unique};
use core::stream::Stream;
use core::task::{Context, Poll};

#[cfg(not(no_global_oom_handling))]
Expand Down Expand Up @@ -1992,8 +1992,8 @@ where
}
}

#[unstable(feature = "async_stream", issue = "79024")]
impl<S: ?Sized + Stream + Unpin> Stream for Box<S> {
#[unstable(feature = "async_iterator", issue = "79024")]
impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for Box<S> {
type Item = S::Item;

fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
#![feature(array_chunks)]
#![feature(array_methods)]
#![feature(array_windows)]
#![feature(async_stream)]
#![feature(async_iterator)]
#![feature(coerce_unsized)]
#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
#![feature(const_box)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,50 @@ use crate::task::{Context, Poll};

/// An interface for dealing with asynchronous iterators.
///
/// This is the main stream trait. For more about the concept of streams
/// This is the main async iterator trait. For more about the concept of async iterators
/// generally, please see the [module-level documentation]. In particular, you
/// may want to know how to [implement `Stream`][impl].
/// may want to know how to [implement `AsyncIterator`][impl].
///
/// [module-level documentation]: index.html
/// [impl]: index.html#implementing-stream
#[unstable(feature = "async_stream", issue = "79024")]
#[must_use = "streams do nothing unless polled"]
pub trait Stream {
/// The type of items yielded by the stream.
/// [impl]: index.html#implementing-async-iterator
#[unstable(feature = "async_iterator", issue = "79024")]
#[must_use = "async iterators do nothing unless polled"]
pub trait AsyncIterator {
/// The type of items yielded by the async iterator.
type Item;

/// Attempt to pull out the next value of this stream, registering the
/// Attempt to pull out the next value of this async iterator, registering the
/// current task for wakeup if the value is not yet available, and returning
/// `None` if the stream is exhausted.
/// `None` if the async iterator is exhausted.
///
/// # Return value
///
/// There are several possible return values, each indicating a distinct
/// stream state:
/// async iterator state:
///
/// - `Poll::Pending` means that this stream's next value is not ready
/// - `Poll::Pending` means that this async iterator's next value is not ready
/// yet. Implementations will ensure that the current task will be notified
/// when the next value may be ready.
///
/// - `Poll::Ready(Some(val))` means that the stream has successfully
/// - `Poll::Ready(Some(val))` means that the async iterator has successfully
/// produced a value, `val`, and may produce further values on subsequent
/// `poll_next` calls.
///
/// - `Poll::Ready(None)` means that the stream has terminated, and
/// - `Poll::Ready(None)` means that the async iterator has terminated, and
/// `poll_next` should not be invoked again.
///
/// # Panics
///
/// Once a stream has finished (returned `Ready(None)` from `poll_next`), calling its
/// Once an async iterator has finished (returned `Ready(None)` from `poll_next`), calling its
/// `poll_next` method again may panic, block forever, or cause other kinds of
/// problems; the `Stream` trait places no requirements on the effects of
/// problems; the `AsyncIterator` trait places no requirements on the effects of
/// such a call. However, as the `poll_next` method is not marked `unsafe`,
/// Rust's usual rules apply: calls must never cause undefined behavior
/// (memory corruption, incorrect use of `unsafe` functions, or the like),
/// regardless of the stream's state.
/// regardless of the async iterator's state.
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;

/// Returns the bounds on the remaining length of the stream.
/// Returns the bounds on the remaining length of the async iterator.
///
/// Specifically, `size_hint()` returns a tuple where the first element
/// is the lower bound, and the second element is the upper bound.
Expand All @@ -58,12 +58,12 @@ pub trait Stream {
///
/// # Implementation notes
///
/// It is not enforced that a stream implementation yields the declared
/// number of elements. A buggy stream may yield less than the lower bound
/// It is not enforced that an async iterator implementation yields the declared
/// number of elements. A buggy async iterator may yield less than the lower bound
/// or more than the upper bound of elements.
///
/// `size_hint()` is primarily intended to be used for optimizations such as
/// reserving space for the elements of the stream, but must not be
/// reserving space for the elements of the async iterator, but must not be
/// trusted to e.g., omit bounds checks in unsafe code. An incorrect
/// implementation of `size_hint()` should not lead to memory safety
/// violations.
Expand All @@ -72,15 +72,15 @@ pub trait Stream {
/// because otherwise it would be a violation of the trait's protocol.
///
/// The default implementation returns <code>(0, [None])</code> which is correct for any
/// stream.
/// async iterator.
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}

#[unstable(feature = "async_stream", issue = "79024")]
impl<S: ?Sized + Stream + Unpin> Stream for &mut S {
#[unstable(feature = "async_iterator", issue = "79024")]
impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for &mut S {
type Item = S::Item;

fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Expand All @@ -92,16 +92,16 @@ impl<S: ?Sized + Stream + Unpin> Stream for &mut S {
}
}

#[unstable(feature = "async_stream", issue = "79024")]
impl<P> Stream for Pin<P>
#[unstable(feature = "async_iterator", issue = "79024")]
impl<P> AsyncIterator for Pin<P>
where
P: DerefMut,
P::Target: Stream,
P::Target: AsyncIterator,
{
type Item = <P::Target as Stream>::Item;
type Item = <P::Target as AsyncIterator>::Item;

fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
<P::Target as Stream>::poll_next(self.as_deref_mut(), cx)
<P::Target as AsyncIterator>::poll_next(self.as_deref_mut(), cx)
}

fn size_hint(&self) -> (usize, Option<usize>) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
use crate::pin::Pin;

use crate::stream::Stream;
use crate::async_iter::AsyncIterator;
use crate::task::{Context, Poll};

/// A stream that was created from iterator.
/// An async iterator that was created from iterator.
///
/// This stream is created by the [`from_iter`] function.
/// This async iterator is created by the [`from_iter`] function.
/// See it documentation for more.
///
/// [`from_iter`]: fn.from_iter.html
#[unstable(feature = "stream_from_iter", issue = "81798")]
#[unstable(feature = "async_iter_from_iter", issue = "81798")]
#[derive(Clone, Debug)]
pub struct FromIter<I> {
iter: I,
}

#[unstable(feature = "stream_from_iter", issue = "81798")]
#[unstable(feature = "async_iter_from_iter", issue = "81798")]
impl<I> Unpin for FromIter<I> {}

/// Converts an iterator into a stream.
#[unstable(feature = "stream_from_iter", issue = "81798")]
/// Converts an iterator into an async iterator.
#[unstable(feature = "async_iter_from_iter", issue = "81798")]
pub fn from_iter<I: IntoIterator>(iter: I) -> FromIter<I::IntoIter> {
FromIter { iter: iter.into_iter() }
}

#[unstable(feature = "stream_from_iter", issue = "81798")]
impl<I: Iterator> Stream for FromIter<I> {
#[unstable(feature = "async_iter_from_iter", issue = "81798")]
impl<I: Iterator> AsyncIterator for FromIter<I> {
type Item = I::Item;

fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,82 +1,81 @@
//! Composable asynchronous iteration.
//!
//! If futures are asynchronous values, then streams are asynchronous
//! iterators. If you've found yourself with an asynchronous collection of some kind,
//! If you've found yourself with an asynchronous collection of some kind,
//! and needed to perform an operation on the elements of said collection,
//! you'll quickly run into 'streams'. Streams are heavily used in idiomatic
//! asynchronous Rust code, so it's worth becoming familiar with them.
//! you'll quickly run into 'async iterators'. Async Iterators are heavily used in
//! idiomatic asynchronous Rust code, so it's worth becoming familiar with them.
//!
//! Before explaining more, let's talk about how this module is structured:
//!
//! # Organization
//!
//! This module is largely organized by type:
//!
//! * [Traits] are the core portion: these traits define what kind of streams
//! * [Traits] are the core portion: these traits define what kind of async iterators
//! exist and what you can do with them. The methods of these traits are worth
//! putting some extra study time into.
//! * Functions provide some helpful ways to create some basic streams.
//! * Functions provide some helpful ways to create some basic async iterators.
//! * Structs are often the return types of the various methods on this
//! module's traits. You'll usually want to look at the method that creates
//! the `struct`, rather than the `struct` itself. For more detail about why,
//! see '[Implementing Stream](#implementing-stream)'.
//! see '[Implementing Async Iterator](#implementing-async-iterator)'.
//!
//! [Traits]: #traits
//!
//! That's it! Let's dig into streams.
//! That's it! Let's dig into async iterators.
//!
//! # Stream
//! # Async Iterators
//!
//! The heart and soul of this module is the [`Stream`] trait. The core of
//! [`Stream`] looks like this:
//! The heart and soul of this module is the [`AsyncIterator`] trait. The core of
//! [`AsyncIterator`] looks like this:
//!
//! ```
//! # use core::task::{Context, Poll};
//! # use core::pin::Pin;
//! trait Stream {
//! trait AsyncIterator {
//! type Item;
//! fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
//! }
//! ```
//!
//! Unlike `Iterator`, `Stream` makes a distinction between the [`poll_next`]
//! method which is used when implementing a `Stream`, and a (to-be-implemented)
//! `next` method which is used when consuming a stream. Consumers of `Stream`
//! Unlike `Iterator`, `AsyncIterator` makes a distinction between the [`poll_next`]
//! method which is used when implementing an `AsyncIterator`, and a (to-be-implemented)
//! `next` method which is used when consuming an async iterator. Consumers of `AsyncIterator`
//! only need to consider `next`, which when called, returns a future which
//! yields `Option<Stream::Item>`.
//! yields `Option<AsyncIterator::Item>`.
//!
//! The future returned by `next` will yield `Some(Item)` as long as there are
//! elements, and once they've all been exhausted, will yield `None` to indicate
//! that iteration is finished. If we're waiting on something asynchronous to
//! resolve, the future will wait until the stream is ready to yield again.
//! resolve, the future will wait until the async iterator is ready to yield again.
//!
//! Individual streams may choose to resume iteration, and so calling `next`
//! Individual async iterators may choose to resume iteration, and so calling `next`
//! again may or may not eventually yield `Some(Item)` again at some point.
//!
//! [`Stream`]'s full definition includes a number of other methods as well,
//! [`AsyncIterator`]'s full definition includes a number of other methods as well,
//! but they are default methods, built on top of [`poll_next`], and so you get
//! them for free.
//!
//! [`Poll`]: super::task::Poll
//! [`poll_next`]: Stream::poll_next
//! [`poll_next`]: AsyncIterator::poll_next
//!
//! # Implementing Stream
//! # Implementing Async Iterator
//!
//! Creating a stream of your own involves two steps: creating a `struct` to
//! hold the stream's state, and then implementing [`Stream`] for that
//! Creating an async iterator of your own involves two steps: creating a `struct` to
//! hold the async iterator's state, and then implementing [`AsyncIterator`] for that
//! `struct`.
//!
//! Let's make a stream named `Counter` which counts from `1` to `5`:
//! Let's make an async iterator named `Counter` which counts from `1` to `5`:
//!
//! ```no_run
//! #![feature(async_stream)]
//! # use core::stream::Stream;
//! #![feature(async_iterator)]
//! # use core::async_iter::AsyncIterator;
//! # use core::task::{Context, Poll};
//! # use core::pin::Pin;
//!
//! // First, the struct:
//!
//! /// A stream which counts from one to five
//! /// An async iterator which counts from one to five
//! struct Counter {
//! count: usize,
//! }
Expand All @@ -90,9 +89,9 @@
//! }
//! }
//!
//! // Then, we implement `Stream` for our `Counter`:
//! // Then, we implement `AsyncIterator` for our `Counter`:
//!
//! impl Stream for Counter {
//! impl AsyncIterator for Counter {
//! // we will be counting with usize
//! type Item = usize;
//!
Expand All @@ -113,17 +112,17 @@
//!
//! # Laziness
//!
//! Streams are *lazy*. This means that just creating a stream doesn't _do_ a
//! whole lot. Nothing really happens until you call `poll_next`. This is
//! sometimes a source of confusion when creating a stream solely for its side
//! Async iterators are *lazy*. This means that just creating an async iterator doesn't
//! _do_ a whole lot. Nothing really happens until you call `poll_next`. This is
//! sometimes a source of confusion when creating an async iterator solely for its side
//! effects. The compiler will warn us about this kind of behavior:
//!
//! ```text
//! warning: unused result that must be used: streams do nothing unless polled
//! warning: unused result that must be used: async iterators do nothing unless polled
//! ```

mod async_iter;
mod from_iter;
mod stream;

pub use async_iter::AsyncIterator;
pub use from_iter::{from_iter, FromIter};
pub use stream::Stream;
4 changes: 2 additions & 2 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ pub mod ops;
pub mod any;
pub mod array;
pub mod ascii;
#[unstable(feature = "async_iterator", issue = "79024")]
pub mod async_iter;
pub mod cell;
pub mod char;
pub mod ffi;
Expand All @@ -315,8 +317,6 @@ pub mod panic;
pub mod panicking;
pub mod pin;
pub mod result;
#[unstable(feature = "async_stream", issue = "79024")]
pub mod stream;
pub mod sync;

pub mod fmt;
Expand Down
6 changes: 3 additions & 3 deletions library/core/src/panic/unwind_safe.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::async_iter::AsyncIterator;
use crate::cell::UnsafeCell;
use crate::fmt;
use crate::future::Future;
use crate::ops::{Deref, DerefMut};
use crate::pin::Pin;
use crate::ptr::{NonNull, Unique};
use crate::stream::Stream;
use crate::task::{Context, Poll};

/// A marker trait which represents "panic safe" types in Rust.
Expand Down Expand Up @@ -290,8 +290,8 @@ impl<F: Future> Future for AssertUnwindSafe<F> {
}
}

#[unstable(feature = "async_stream", issue = "79024")]
impl<S: Stream> Stream for AssertUnwindSafe<S> {
#[unstable(feature = "async_iterator", issue = "79024")]
impl<S: AsyncIterator> AsyncIterator for AssertUnwindSafe<S> {
type Item = S::Item;

fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
Expand Down
Loading