@@ -1407,9 +1407,11 @@ impl<'db> ExprCollector<'db> {
14071407 }
14081408 }
14091409 ast:: Expr :: ClosureExpr ( e) => self . with_label_rib ( RibKind :: Closure , |this| {
1410- this. with_binding_owner ( |this| {
1410+ this. with_binding_owner_and_return ( |this| {
14111411 let mut args = Vec :: new ( ) ;
14121412 let mut arg_types = Vec :: new ( ) ;
1413+ // For coroutine closures, the body, aka. the coroutine is the bindings owner, and not the closure.
1414+ let mut body_is_bindings_owner = false ;
14131415 if let Some ( pl) = e. param_list ( ) {
14141416 let num_params = pl. params ( ) . count ( ) ;
14151417 args. reserve_exact ( num_params) ;
@@ -1460,6 +1462,7 @@ impl<'db> ExprCollector<'db> {
14601462 // It will be fixed in capture analysis.
14611463 capture_by : CaptureBy :: Ref ,
14621464 } ) ;
1465+ body_is_bindings_owner = true ;
14631466
14641467 ClosureKind :: AsyncClosure
14651468 } else {
@@ -1469,7 +1472,7 @@ impl<'db> ExprCollector<'db> {
14691472 if e. move_token ( ) . is_some ( ) { CaptureBy :: Value } else { CaptureBy :: Ref } ;
14701473 this. is_lowering_coroutine = prev_is_lowering_coroutine;
14711474 this. current_try_block = prev_try_block;
1472- this. alloc_expr (
1475+ let closure = this. alloc_expr (
14731476 Expr :: Closure {
14741477 args : args. into ( ) ,
14751478 arg_types : arg_types. into ( ) ,
@@ -1479,7 +1482,9 @@ impl<'db> ExprCollector<'db> {
14791482 capture_by,
14801483 } ,
14811484 syntax_ptr,
1482- )
1485+ ) ;
1486+
1487+ ( if body_is_bindings_owner { body } else { closure } , closure)
14831488 } )
14841489 } ) ,
14851490 ast:: Expr :: BinExpr ( e) => {
@@ -1781,13 +1786,24 @@ impl<'db> ExprCollector<'db> {
17811786 }
17821787 }
17831788
1784- fn with_binding_owner ( & mut self , create_expr : impl FnOnce ( & mut Self ) -> ExprId ) -> ExprId {
1789+ /// The callback should return two exprs: the first is the bindings owner, the second is the expr to return.
1790+ fn with_binding_owner_and_return (
1791+ & mut self ,
1792+ create_expr : impl FnOnce ( & mut Self ) -> ( ExprId , ExprId ) ,
1793+ ) -> ExprId {
17851794 let prev_unowned_bindings_len = self . unowned_bindings . len ( ) ;
1786- let expr_id = create_expr ( self ) ;
1795+ let ( bindings_owner , expr_to_return ) = create_expr ( self ) ;
17871796 for binding in self . unowned_bindings . drain ( prev_unowned_bindings_len..) {
1788- self . store . binding_owners . insert ( binding, expr_id ) ;
1797+ self . store . binding_owners . insert ( binding, bindings_owner ) ;
17891798 }
1790- expr_id
1799+ expr_to_return
1800+ }
1801+
1802+ fn with_binding_owner ( & mut self , create_expr : impl FnOnce ( & mut Self ) -> ExprId ) -> ExprId {
1803+ self . with_binding_owner_and_return ( move |this| {
1804+ let expr = create_expr ( this) ;
1805+ ( expr, expr)
1806+ } )
17911807 }
17921808
17931809 /// Desugar `try { <stmts>; <expr> }` into `'<new_label>: { <stmts>; ::std::ops::Try::from_output(<expr>) }`,
0 commit comments