@@ -28,9 +28,9 @@ use crate::{
28
28
data:: adt:: StructKind ,
29
29
db:: DefDatabase ,
30
30
hir:: {
31
- dummy_expr_id, Array , Binding , BindingAnnotation , BindingId , ClosureKind , Expr , ExprId ,
32
- Label , LabelId , Literal , MatchArm , Movability , Pat , PatId , RecordFieldPat , RecordLitField ,
33
- Statement ,
31
+ dummy_expr_id, Array , Binding , BindingAnnotation , BindingId , CaptureBy , ClosureKind , Expr ,
32
+ ExprId , Label , LabelId , Literal , MatchArm , Movability , Pat , PatId , RecordFieldPat ,
33
+ RecordLitField , Statement ,
34
34
} ,
35
35
item_scope:: BuiltinShadowMode ,
36
36
lang_item:: LangItem ,
@@ -67,6 +67,7 @@ pub(super) fn lower(
67
67
is_lowering_assignee_expr : false ,
68
68
is_lowering_generator : false ,
69
69
label_ribs : Vec :: new ( ) ,
70
+ current_binding_owner : None ,
70
71
}
71
72
. collect ( params, body, is_async_fn)
72
73
}
@@ -92,6 +93,7 @@ struct ExprCollector<'a> {
92
93
93
94
// resolution
94
95
label_ribs : Vec < LabelRib > ,
96
+ current_binding_owner : Option < ExprId > ,
95
97
}
96
98
97
99
#[ derive( Clone , Debug ) ]
@@ -461,6 +463,8 @@ impl ExprCollector<'_> {
461
463
}
462
464
}
463
465
ast:: Expr :: ClosureExpr ( e) => self . with_label_rib ( RibKind :: Closure , |this| {
466
+ let ( result_expr_id, prev_binding_owner) =
467
+ this. initialize_binding_owner ( syntax_ptr) ;
464
468
let mut args = Vec :: new ( ) ;
465
469
let mut arg_types = Vec :: new ( ) ;
466
470
if let Some ( pl) = e. param_list ( ) {
@@ -494,17 +498,19 @@ impl ExprCollector<'_> {
494
498
ClosureKind :: Closure
495
499
} ;
496
500
this. is_lowering_generator = prev_is_lowering_generator;
497
-
498
- this. alloc_expr (
499
- Expr :: Closure {
500
- args : args. into ( ) ,
501
- arg_types : arg_types. into ( ) ,
502
- ret_type,
503
- body,
504
- closure_kind,
505
- } ,
506
- syntax_ptr,
507
- )
501
+ let capture_by =
502
+ if e. move_token ( ) . is_some ( ) { CaptureBy :: Value } else { CaptureBy :: Ref } ;
503
+ this. is_lowering_generator = prev_is_lowering_generator;
504
+ this. current_binding_owner = prev_binding_owner;
505
+ this. body . exprs [ result_expr_id] = Expr :: Closure {
506
+ args : args. into ( ) ,
507
+ arg_types : arg_types. into ( ) ,
508
+ ret_type,
509
+ body,
510
+ closure_kind,
511
+ capture_by,
512
+ } ;
513
+ result_expr_id
508
514
} ) ,
509
515
ast:: Expr :: BinExpr ( e) => {
510
516
let op = e. op_kind ( ) ;
@@ -545,7 +551,17 @@ impl ExprCollector<'_> {
545
551
ArrayExprKind :: Repeat { initializer, repeat } => {
546
552
let initializer = self . collect_expr_opt ( initializer) ;
547
553
let repeat = self . with_label_rib ( RibKind :: Constant , |this| {
548
- this. collect_expr_opt ( repeat)
554
+ if let Some ( repeat) = repeat {
555
+ let ( id, prev_owner) =
556
+ this. initialize_binding_owner ( AstPtr :: new ( & repeat) ) ;
557
+ let tmp = this. collect_expr ( repeat) ;
558
+ this. body . exprs [ id] =
559
+ mem:: replace ( & mut this. body . exprs [ tmp] , Expr :: Missing ) ;
560
+ this. current_binding_owner = prev_owner;
561
+ id
562
+ } else {
563
+ this. missing_expr ( )
564
+ }
549
565
} ) ;
550
566
self . alloc_expr (
551
567
Expr :: Array ( Array :: Repeat { initializer, repeat } ) ,
@@ -592,6 +608,16 @@ impl ExprCollector<'_> {
592
608
} )
593
609
}
594
610
611
+ fn initialize_binding_owner (
612
+ & mut self ,
613
+ syntax_ptr : AstPtr < ast:: Expr > ,
614
+ ) -> ( ExprId , Option < ExprId > ) {
615
+ let result_expr_id = self . alloc_expr ( Expr :: Missing , syntax_ptr) ;
616
+ let prev_binding_owner = self . current_binding_owner . take ( ) ;
617
+ self . current_binding_owner = Some ( result_expr_id) ;
618
+ ( result_expr_id, prev_binding_owner)
619
+ }
620
+
595
621
/// Desugar `try { <stmts>; <expr> }` into `'<new_label>: { <stmts>; ::std::ops::Try::from_output(<expr>) }`,
596
622
/// `try { <stmts>; }` into `'<new_label>: { <stmts>; ::std::ops::Try::from_output(()) }`
597
623
/// and save the `<new_label>` to use it as a break target for desugaring of the `?` operator.
@@ -1272,7 +1298,12 @@ impl ExprCollector<'_> {
1272
1298
}
1273
1299
1274
1300
fn alloc_binding ( & mut self , name : Name , mode : BindingAnnotation ) -> BindingId {
1275
- self . body . bindings . alloc ( Binding { name, mode, definitions : SmallVec :: new ( ) } )
1301
+ self . body . bindings . alloc ( Binding {
1302
+ name,
1303
+ mode,
1304
+ definitions : SmallVec :: new ( ) ,
1305
+ owner : self . current_binding_owner ,
1306
+ } )
1276
1307
}
1277
1308
1278
1309
fn alloc_pat ( & mut self , pat : Pat , ptr : PatPtr ) -> PatId {
0 commit comments