about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <ericholk@microsoft.com>2023-12-18 17:08:19 -0800
committerEric Holk <ericholk@microsoft.com>2023-12-22 11:01:06 -0800
commitacb6f17adf78f79db10ec189d719380d35cacee7 (patch)
tree6808592eec58adf4cdc2fa44fa6c8c9083c37e6d
parent8e34391d6a6e924cbea588d7e418b39aaebb6616 (diff)
downloadrust-acb6f17adf78f79db10ec189d719380d35cacee7.tar.gz
rust-acb6f17adf78f79db10ec189d719380d35cacee7.zip
Use `IntoAsyncIterator` in `for await` loop desugaring
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs20
-rw-r--r--compiler/rustc_hir/src/lang_items.rs1
-rw-r--r--library/core/src/async_iter/async_iter.rs1
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;
 }