Rollup merge of #119222 - eholk:into-async-iterator, r=compiler-errors,dtolnay
Add `IntoAsyncIterator` This introduces the `IntoAsyncIterator` trait and uses it in the desugaring of the unstable `for await` loop syntax. This is mostly added for symmetry with `Iterator` and `IntoIterator`. r? `@compiler-errors` cc `@rust-lang/libs-api,` `@rust-lang/wg-async`
This commit is contained in:
commit
eef023c806
@ -1814,7 +1814,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
arena_vec![self; head],
|
arena_vec![self; head],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ForLoopKind::ForAwait => self.arena.alloc(head),
|
// ` unsafe { Pin::new_unchecked(&mut into_async_iter(<head>)) }`
|
||||||
|
ForLoopKind::ForAwait => {
|
||||||
|
// `::core::async_iter::IntoAsyncIterator::into_async_iter(<head>)`
|
||||||
|
let iter = self.expr_call_lang_item_fn(
|
||||||
|
head_span,
|
||||||
|
hir::LangItem::IntoAsyncIterIntoIter,
|
||||||
|
arena_vec![self; head],
|
||||||
|
);
|
||||||
|
let iter = self.expr_mut_addr_of(head_span, iter);
|
||||||
|
// `Pin::new_unchecked(...)`
|
||||||
|
let iter = self.arena.alloc(self.expr_call_lang_item_fn_mut(
|
||||||
|
head_span,
|
||||||
|
hir::LangItem::PinNewUnchecked,
|
||||||
|
arena_vec![self; iter],
|
||||||
|
));
|
||||||
|
// `unsafe { ... }`
|
||||||
|
let iter = self.arena.alloc(self.expr_unsafe(iter));
|
||||||
|
iter
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let match_expr = self.arena.alloc(self.expr_match(
|
let match_expr = self.arena.alloc(self.expr_match(
|
||||||
|
@ -308,6 +308,7 @@ language_item_table! {
|
|||||||
FuturePoll, sym::poll, future_poll_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
FuturePoll, sym::poll, future_poll_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||||
|
|
||||||
AsyncIteratorPollNext, sym::async_iterator_poll_next, async_iterator_poll_next, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0);
|
AsyncIteratorPollNext, sym::async_iterator_poll_next, async_iterator_poll_next, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0);
|
||||||
|
IntoAsyncIterIntoIter, sym::into_async_iter_into_iter, into_async_iter_into_iter, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0);
|
||||||
|
|
||||||
Option, sym::Option, option_type, Target::Enum, GenericRequirement::None;
|
Option, sym::Option, option_type, Target::Enum, GenericRequirement::None;
|
||||||
OptionSome, sym::Some, option_some_variant, Target::Variant, GenericRequirement::None;
|
OptionSome, sym::Some, option_some_variant, Target::Variant, GenericRequirement::None;
|
||||||
|
@ -135,3 +135,26 @@ impl<T> Poll<Option<T>> {
|
|||||||
#[lang = "AsyncGenFinished"]
|
#[lang = "AsyncGenFinished"]
|
||||||
pub const FINISHED: Self = Poll::Ready(None);
|
pub const FINISHED: Self = Poll::Ready(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert something into an async iterator
|
||||||
|
#[unstable(feature = "async_iterator", issue = "79024")]
|
||||||
|
pub trait IntoAsyncIterator {
|
||||||
|
/// The type of the item yielded by the iterator
|
||||||
|
type Item;
|
||||||
|
/// The type of the resulting iterator
|
||||||
|
type IntoAsyncIter: AsyncIterator<Item = Self::Item>;
|
||||||
|
|
||||||
|
/// Converts `self` into an async iterator
|
||||||
|
#[cfg_attr(not(bootstrap), lang = "into_async_iter_into_iter")]
|
||||||
|
fn into_async_iter(self) -> Self::IntoAsyncIter;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "async_iterator", issue = "79024")]
|
||||||
|
impl<I: AsyncIterator> IntoAsyncIterator for I {
|
||||||
|
type Item = I::Item;
|
||||||
|
type IntoAsyncIter = I;
|
||||||
|
|
||||||
|
fn into_async_iter(self) -> Self::IntoAsyncIter {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -124,5 +124,5 @@
|
|||||||
mod async_iter;
|
mod async_iter;
|
||||||
mod from_iter;
|
mod from_iter;
|
||||||
|
|
||||||
pub use async_iter::AsyncIterator;
|
pub use async_iter::{AsyncIterator, IntoAsyncIterator};
|
||||||
pub use from_iter::{from_iter, FromIter};
|
pub use from_iter::{from_iter, FromIter};
|
||||||
|
17
library/core/tests/async_iter/mod.rs
Normal file
17
library/core/tests/async_iter/mod.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use core::async_iter::{self, AsyncIterator, IntoAsyncIterator};
|
||||||
|
use core::pin::pin;
|
||||||
|
use core::task::Poll;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn into_async_iter() {
|
||||||
|
let async_iter = async_iter::from_iter(0..3);
|
||||||
|
let mut async_iter = pin!(async_iter.into_async_iter());
|
||||||
|
|
||||||
|
let waker = core::task::Waker::noop();
|
||||||
|
let mut cx = &mut core::task::Context::from_waker(&waker);
|
||||||
|
|
||||||
|
assert_eq!(async_iter.as_mut().poll_next(&mut cx), Poll::Ready(Some(0)));
|
||||||
|
assert_eq!(async_iter.as_mut().poll_next(&mut cx), Poll::Ready(Some(1)));
|
||||||
|
assert_eq!(async_iter.as_mut().poll_next(&mut cx), Poll::Ready(Some(2)));
|
||||||
|
assert_eq!(async_iter.as_mut().poll_next(&mut cx), Poll::Ready(None));
|
||||||
|
}
|
@ -4,6 +4,8 @@
|
|||||||
#![feature(array_windows)]
|
#![feature(array_windows)]
|
||||||
#![feature(ascii_char)]
|
#![feature(ascii_char)]
|
||||||
#![feature(ascii_char_variants)]
|
#![feature(ascii_char_variants)]
|
||||||
|
#![feature(async_iter_from_iter)]
|
||||||
|
#![feature(async_iterator)]
|
||||||
#![feature(bigint_helper_methods)]
|
#![feature(bigint_helper_methods)]
|
||||||
#![feature(cell_update)]
|
#![feature(cell_update)]
|
||||||
#![feature(const_align_offset)]
|
#![feature(const_align_offset)]
|
||||||
@ -55,6 +57,7 @@
|
|||||||
#![feature(maybe_uninit_write_slice)]
|
#![feature(maybe_uninit_write_slice)]
|
||||||
#![feature(maybe_uninit_uninit_array_transpose)]
|
#![feature(maybe_uninit_uninit_array_transpose)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
|
#![feature(noop_waker)]
|
||||||
#![feature(numfmt)]
|
#![feature(numfmt)]
|
||||||
#![feature(num_midpoint)]
|
#![feature(num_midpoint)]
|
||||||
#![feature(isqrt)]
|
#![feature(isqrt)]
|
||||||
@ -125,6 +128,7 @@ mod any;
|
|||||||
mod array;
|
mod array;
|
||||||
mod ascii;
|
mod ascii;
|
||||||
mod asserting;
|
mod asserting;
|
||||||
|
mod async_iter;
|
||||||
mod atomic;
|
mod atomic;
|
||||||
mod bool;
|
mod bool;
|
||||||
mod cell;
|
mod cell;
|
||||||
|
@ -33,7 +33,14 @@ error[E0223]: ambiguous associated type
|
|||||||
--> $DIR/issue-109071.rs:15:22
|
--> $DIR/issue-109071.rs:15:22
|
||||||
|
|
|
|
||||||
LL | fn T() -> Option<Self::Item> {}
|
LL | fn T() -> Option<Self::Item> {}
|
||||||
| ^^^^^^^^^^ help: use fully-qualified syntax: `<Windows<T> as IntoIterator>::Item`
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: use fully-qualified syntax
|
||||||
|
|
|
||||||
|
LL | fn T() -> Option<<Windows<T> as IntoAsyncIterator>::Item> {}
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
LL | fn T() -> Option<<Windows<T> as IntoIterator>::Item> {}
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -5,22 +5,17 @@ LL | let iter = core::async_iter::from_iter(0..3);
|
|||||||
| ---- move occurs because `iter` has type `FromIter<std::ops::Range<i32>>`, which does not implement the `Copy` trait
|
| ---- move occurs because `iter` has type `FromIter<std::ops::Range<i32>>`, which does not implement the `Copy` trait
|
||||||
LL | let mut count = 0;
|
LL | let mut count = 0;
|
||||||
LL | for await i in iter {
|
LL | for await i in iter {
|
||||||
| -------------------
|
| ---- `iter` moved due to this method call
|
||||||
| | |
|
|
||||||
| | value moved here
|
|
||||||
| inside of this loop
|
|
||||||
...
|
...
|
||||||
LL | for await i in iter {
|
LL | for await i in iter {
|
||||||
| ^^^^ value used here after move
|
| ^^^^ value used here after move
|
||||||
|
|
|
|
||||||
help: consider cloning the value if the performance cost is acceptable
|
note: `into_async_iter` takes ownership of the receiver `self`, which moves `iter`
|
||||||
|
--> $SRC_DIR/core/src/async_iter/async_iter.rs:LL:COL
|
||||||
|
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
||||||
|
|
|
|
||||||
LL | for await i in iter.clone() {
|
LL | for await i in iter.clone() {
|
||||||
| ++++++++
|
| ++++++++
|
||||||
help: borrow this binding in the pattern to avoid moving the value
|
|
||||||
|
|
|
||||||
LL | for await i in ref iter {
|
|
||||||
| +++
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -2,7 +2,14 @@ error[E0223]: ambiguous associated type
|
|||||||
--> $DIR/suggest-trait-in-ufcs-in-hrtb.rs:5:38
|
--> $DIR/suggest-trait-in-ufcs-in-hrtb.rs:5:38
|
||||||
|
|
|
|
||||||
LL | impl<S> Foo for Bar<S> where for<'a> <&'a S>::Item: Foo {}
|
LL | impl<S> Foo for Bar<S> where for<'a> <&'a S>::Item: Foo {}
|
||||||
| ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<&'a S as IntoIterator>::Item`
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: use fully-qualified syntax
|
||||||
|
|
|
||||||
|
LL | impl<S> Foo for Bar<S> where for<'a> <&'a S as IntoAsyncIterator>::Item: Foo {}
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
LL | impl<S> Foo for Bar<S> where for<'a> <&'a S as IntoIterator>::Item: Foo {}
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -2,7 +2,14 @@ error[E0223]: ambiguous associated type
|
|||||||
--> $DIR/issue-110052.rs:6:30
|
--> $DIR/issue-110052.rs:6:30
|
||||||
|
|
|
|
||||||
LL | for<'iter> dyn Validator<<&'iter I>::Item>:,
|
LL | for<'iter> dyn Validator<<&'iter I>::Item>:,
|
||||||
| ^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<&'iter I as IntoIterator>::Item`
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: use fully-qualified syntax
|
||||||
|
|
|
||||||
|
LL | for<'iter> dyn Validator<<&'iter I as IntoAsyncIterator>::Item>:,
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
LL | for<'iter> dyn Validator<<&'iter I as IntoIterator>::Item>:,
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user