@@ -1712,24 +1712,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
17121712 // `mut iter => { ... }`
17131713 let iter_arm = self . arm ( iter_pat, loop_expr) ;
17141714
1715- let into_iter_expr = match loop_kind {
1715+ let match_expr = match loop_kind {
17161716 ForLoopKind :: For => {
17171717 // `::std::iter::IntoIterator::into_iter(<head>)`
1718- self . expr_call_lang_item_fn (
1718+ let into_iter_expr = self . expr_call_lang_item_fn (
17191719 head_span,
17201720 hir:: LangItem :: IntoIterIntoIter ,
17211721 arena_vec ! [ self ; head] ,
1722- )
1722+ ) ;
1723+
1724+ self . arena . alloc ( self . expr_match (
1725+ for_span,
1726+ into_iter_expr,
1727+ arena_vec ! [ self ; iter_arm] ,
1728+ hir:: MatchSource :: ForLoopDesugar ,
1729+ ) )
17231730 }
1724- // ` unsafe { Pin::new_unchecked(&mut into_async_iter(<head>)) }`
1731+ // `match into_async_iter(<head>) { ref mut iter => match unsafe { Pin::new_unchecked(iter) } { ... } }`
17251732 ForLoopKind :: ForAwait => {
1726- // `::core::async_iter::IntoAsyncIterator::into_async_iter(<head>)`
1727- let iter = self . expr_call_lang_item_fn (
1728- head_span,
1729- hir:: LangItem :: IntoAsyncIterIntoIter ,
1730- arena_vec ! [ self ; head] ,
1731- ) ;
1732- let iter = self . expr_mut_addr_of ( head_span, iter) ;
1733+ let iter_ident = iter;
1734+ let ( async_iter_pat, async_iter_pat_id) =
1735+ self . pat_ident_binding_mode ( head_span, iter_ident, hir:: BindingMode :: REF_MUT ) ;
1736+ let iter = self . expr_ident_mut ( head_span, iter_ident, async_iter_pat_id) ;
17331737 // `Pin::new_unchecked(...)`
17341738 let iter = self . arena . alloc ( self . expr_call_lang_item_fn_mut (
17351739 head_span,
@@ -1738,17 +1742,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
17381742 ) ) ;
17391743 // `unsafe { ... }`
17401744 let iter = self . arena . alloc ( self . expr_unsafe ( iter) ) ;
1741- iter
1745+ let inner_match_expr = self . arena . alloc ( self . expr_match (
1746+ for_span,
1747+ iter,
1748+ arena_vec ! [ self ; iter_arm] ,
1749+ hir:: MatchSource :: ForLoopDesugar ,
1750+ ) ) ;
1751+
1752+ // `::core::async_iter::IntoAsyncIterator::into_async_iter(<head>)`
1753+ let iter = self . expr_call_lang_item_fn (
1754+ head_span,
1755+ hir:: LangItem :: IntoAsyncIterIntoIter ,
1756+ arena_vec ! [ self ; head] ,
1757+ ) ;
1758+ let iter_arm = self . arm ( async_iter_pat, inner_match_expr) ;
1759+ self . arena . alloc ( self . expr_match (
1760+ for_span,
1761+ iter,
1762+ arena_vec ! [ self ; iter_arm] ,
1763+ hir:: MatchSource :: ForLoopDesugar ,
1764+ ) )
17421765 }
17431766 } ;
17441767
1745- let match_expr = self . arena . alloc ( self . expr_match (
1746- for_span,
1747- into_iter_expr,
1748- arena_vec ! [ self ; iter_arm] ,
1749- hir:: MatchSource :: ForLoopDesugar ,
1750- ) ) ;
1751-
17521768 // This is effectively `{ let _result = ...; _result }`.
17531769 // The construct was introduced in #21984 and is necessary to make sure that
17541770 // temporaries in the `head` expression are dropped and do not leak to the
0 commit comments