diff options
| author | Eric Holk <ericholk@microsoft.com> | 2023-12-18 17:08:19 -0800 |
|---|---|---|
| committer | Eric Holk <ericholk@microsoft.com> | 2023-12-22 11:01:06 -0800 |
| commit | acb6f17adf78f79db10ec189d719380d35cacee7 (patch) | |
| tree | 6808592eec58adf4cdc2fa44fa6c8c9083c37e6d | |
| parent | 8e34391d6a6e924cbea588d7e418b39aaebb6616 (diff) | |
| download | rust-acb6f17adf78f79db10ec189d719380d35cacee7.tar.gz rust-acb6f17adf78f79db10ec189d719380d35cacee7.zip | |
Use `IntoAsyncIterator` in `for await` loop desugaring
| -rw-r--r-- | compiler/rustc_ast_lowering/src/expr.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/lang_items.rs | 1 | ||||
| -rw-r--r-- | library/core/src/async_iter/async_iter.rs | 1 |
3 files changed, 21 insertions, 1 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 2d61f3bceec..a384601a24d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -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( diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 7691cd11c4f..3f3b57ba94f 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -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; diff --git a/library/core/src/async_iter/async_iter.rs b/library/core/src/async_iter/async_iter.rs index 9ef74991dbb..d5282514cc6 100644 --- a/library/core/src/async_iter/async_iter.rs +++ b/library/core/src/async_iter/async_iter.rs @@ -145,6 +145,7 @@ pub trait IntoAsyncIterator { 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; } |
