@@ -1712,24 +1712,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
1712
1712
// `mut iter => { ... }`
1713
1713
let iter_arm = self . arm ( iter_pat, loop_expr) ;
1714
1714
1715
- let into_iter_expr = match loop_kind {
1715
+ let match_expr = match loop_kind {
1716
1716
ForLoopKind :: For => {
1717
1717
// `::std::iter::IntoIterator::into_iter(<head>)`
1718
- self . expr_call_lang_item_fn (
1718
+ let into_iter_expr = self . expr_call_lang_item_fn (
1719
1719
head_span,
1720
1720
hir:: LangItem :: IntoIterIntoIter ,
1721
1721
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
+ ) )
1723
1730
}
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) } { ... } }`
1725
1732
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) ;
1733
1737
// `Pin::new_unchecked(...)`
1734
1738
let iter = self . arena . alloc ( self . expr_call_lang_item_fn_mut (
1735
1739
head_span,
@@ -1738,17 +1742,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
1738
1742
) ) ;
1739
1743
// `unsafe { ... }`
1740
1744
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
+ ) )
1742
1765
}
1743
1766
} ;
1744
1767
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
-
1752
1768
// This is effectively `{ let _result = ...; _result }`.
1753
1769
// The construct was introduced in #21984 and is necessary to make sure that
1754
1770
// temporaries in the `head` expression are dropped and do not leak to the
0 commit comments