Skip to content

Commit

Permalink
Unrolled build for rust-lang#119222
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#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`
  • Loading branch information
rust-timer committed Dec 23, 2023
2 parents 495203b + aaa3e76 commit c2d0fda
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 14 deletions.
20 changes: 19 additions & 1 deletion compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1803,7 +1803,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
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(
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ language_item_table! {
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);
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;
OptionSome, sym::Some, option_some_variant, Target::Variant, GenericRequirement::None;
Expand Down
23 changes: 23 additions & 0 deletions library/core/src/async_iter/async_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,26 @@ impl<T> Poll<Option<T>> {
#[lang = "AsyncGenFinished"]
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
}
}
2 changes: 1 addition & 1 deletion library/core/src/async_iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,5 @@
mod async_iter;
mod from_iter;

pub use async_iter::AsyncIterator;
pub use async_iter::{AsyncIterator, IntoAsyncIterator};
pub use from_iter::{from_iter, FromIter};
17 changes: 17 additions & 0 deletions library/core/tests/async_iter/mod.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 4 additions & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#![feature(array_windows)]
#![feature(ascii_char)]
#![feature(ascii_char_variants)]
#![feature(async_iter_from_iter)]
#![feature(async_iterator)]
#![feature(bigint_helper_methods)]
#![feature(cell_update)]
#![feature(const_align_offset)]
Expand Down Expand Up @@ -55,6 +57,7 @@
#![feature(maybe_uninit_write_slice)]
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(min_specialization)]
#![feature(noop_waker)]
#![feature(numfmt)]
#![feature(num_midpoint)]
#![feature(isqrt)]
Expand Down Expand Up @@ -125,6 +128,7 @@ mod any;
mod array;
mod ascii;
mod asserting;
mod async_iter;
mod atomic;
mod bool;
mod cell;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ error[E0223]: ambiguous associated type
--> $DIR/issue-109071.rs:15:22
|
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

Expand Down
13 changes: 4 additions & 9 deletions tests/ui/async-await/for-await-consumes-iter.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
LL | let mut count = 0;
LL | for await i in iter {
| -------------------
| | |
| | value moved here
| inside of this loop
| ---- `iter` moved due to this method call
...
LL | for await i in iter {
| ^^^^ 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() {
| ++++++++
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

Expand Down
9 changes: 8 additions & 1 deletion tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ error[E0223]: ambiguous associated type
--> $DIR/suggest-trait-in-ufcs-in-hrtb.rs:5:38
|
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

Expand Down
9 changes: 8 additions & 1 deletion tests/ui/typeck/issue-110052.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ error[E0223]: ambiguous associated type
--> $DIR/issue-110052.rs:6:30
|
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

Expand Down

0 comments on commit c2d0fda

Please sign in to comment.