@@ -70,8 +70,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
70
70
_ => ( ) ,
71
71
}
72
72
73
- let hir_id = self . lower_node_id ( e. id ) ;
74
- self . lower_attrs ( hir_id , & e. attrs ) ;
73
+ let expr_hir_id = self . lower_node_id ( e. id ) ;
74
+ self . lower_attrs ( expr_hir_id , & e. attrs ) ;
75
75
76
76
let kind = match & e. kind {
77
77
ExprKind :: Array ( exprs) => hir:: ExprKind :: Array ( self . lower_exprs ( exprs) ) ,
@@ -175,18 +175,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
175
175
ExprKind :: If ( cond, then, else_opt) => {
176
176
self . lower_expr_if ( cond, then, else_opt. as_deref ( ) )
177
177
}
178
- ExprKind :: While ( cond, body, opt_label) => self . with_loop_scope ( e. id , |this| {
179
- let span = this. mark_span_with_reason ( DesugaringKind :: WhileLoop , e. span , None ) ;
180
- this. lower_expr_while_in_loop_scope ( span, cond, body, * opt_label)
181
- } ) ,
182
- ExprKind :: Loop ( body, opt_label, span) => self . with_loop_scope ( e. id , |this| {
183
- hir:: ExprKind :: Loop (
184
- this. lower_block ( body, false ) ,
185
- this. lower_label ( * opt_label) ,
186
- hir:: LoopSource :: Loop ,
187
- this. lower_span ( * span) ,
188
- )
189
- } ) ,
178
+ ExprKind :: While ( cond, body, opt_label) => {
179
+ self . with_loop_scope ( expr_hir_id, |this| {
180
+ let span =
181
+ this. mark_span_with_reason ( DesugaringKind :: WhileLoop , e. span , None ) ;
182
+ let opt_label = this. lower_label ( * opt_label, e. id , expr_hir_id) ;
183
+ this. lower_expr_while_in_loop_scope ( span, cond, body, opt_label)
184
+ } )
185
+ }
186
+ ExprKind :: Loop ( body, opt_label, span) => {
187
+ self . with_loop_scope ( expr_hir_id, |this| {
188
+ let opt_label = this. lower_label ( * opt_label, e. id , expr_hir_id) ;
189
+ hir:: ExprKind :: Loop (
190
+ this. lower_block ( body, false ) ,
191
+ opt_label,
192
+ hir:: LoopSource :: Loop ,
193
+ this. lower_span ( * span) ,
194
+ )
195
+ } )
196
+ }
190
197
ExprKind :: TryBlock ( body) => self . lower_expr_try_block ( body) ,
191
198
ExprKind :: Match ( expr, arms, kind) => hir:: ExprKind :: Match (
192
199
self . lower_expr ( expr) ,
@@ -212,7 +219,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
212
219
binder,
213
220
* capture_clause,
214
221
e. id ,
215
- hir_id ,
222
+ expr_hir_id ,
216
223
* coroutine_kind,
217
224
fn_decl,
218
225
body,
@@ -223,7 +230,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
223
230
binder,
224
231
* capture_clause,
225
232
e. id ,
226
- hir_id ,
233
+ expr_hir_id ,
227
234
* constness,
228
235
* movability,
229
236
fn_decl,
@@ -250,8 +257,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
250
257
)
251
258
}
252
259
ExprKind :: Block ( blk, opt_label) => {
253
- let opt_label = self . lower_label ( * opt_label) ;
254
- hir:: ExprKind :: Block ( self . lower_block ( blk, opt_label. is_some ( ) ) , opt_label)
260
+ // Different from loops, label of block resolves to block id rather than
261
+ // expr node id.
262
+ let block_hir_id = self . lower_node_id ( blk. id ) ;
263
+ let opt_label = self . lower_label ( * opt_label, blk. id , block_hir_id) ;
264
+ let hir_block = self . arena . alloc ( self . lower_block_noalloc (
265
+ block_hir_id,
266
+ blk,
267
+ opt_label. is_some ( ) ,
268
+ ) ) ;
269
+ hir:: ExprKind :: Block ( hir_block, opt_label)
255
270
}
256
271
ExprKind :: Assign ( el, er, span) => self . lower_expr_assign ( el, er, * span, e. span ) ,
257
272
ExprKind :: AssignOp ( op, el, er) => hir:: ExprKind :: AssignOp (
@@ -354,7 +369,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
354
369
ExprKind :: MacCall ( _) => panic ! ( "{:?} shouldn't exist here" , e. span) ,
355
370
} ;
356
371
357
- hir:: Expr { hir_id, kind, span : self . lower_span ( e. span ) }
372
+ hir:: Expr { hir_id : expr_hir_id , kind, span : self . lower_span ( e. span ) }
358
373
} )
359
374
}
360
375
@@ -504,16 +519,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
504
519
let if_expr = self . expr ( span, if_kind) ;
505
520
let block = self . block_expr ( self . arena . alloc ( if_expr) ) ;
506
521
let span = self . lower_span ( span. with_hi ( cond. span . hi ( ) ) ) ;
507
- let opt_label = self . lower_label ( opt_label) ;
508
522
hir:: ExprKind :: Loop ( block, opt_label, hir:: LoopSource :: While , span)
509
523
}
510
524
511
525
/// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_output(<expr>) }`,
512
526
/// `try { <stmts>; }` into `{ <stmts>; ::std::ops::Try::from_output(()) }`
513
527
/// and save the block id to use it as a break target for desugaring of the `?` operator.
514
528
fn lower_expr_try_block ( & mut self , body : & Block ) -> hir:: ExprKind < ' hir > {
515
- self . with_catch_scope ( body. id , |this| {
516
- let mut block = this. lower_block_noalloc ( body, true ) ;
529
+ let body_hir_id = self . lower_node_id ( body. id ) ;
530
+ self . with_catch_scope ( body_hir_id, |this| {
531
+ let mut block = this. lower_block_noalloc ( body_hir_id, body, true ) ;
517
532
518
533
// Final expression of the block (if present) or `()` with span at the end of block
519
534
let ( try_span, tail_expr) = if let Some ( expr) = block. expr . take ( ) {
@@ -869,7 +884,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
869
884
let x_expr = self . expr_ident ( gen_future_span, x_ident, x_pat_hid) ;
870
885
let ready_field = self . single_pat_field ( gen_future_span, x_pat) ;
871
886
let ready_pat = self . pat_lang_item_variant ( span, hir:: LangItem :: PollReady , ready_field) ;
872
- let break_x = self . with_loop_scope ( loop_node_id , move |this| {
887
+ let break_x = self . with_loop_scope ( loop_hir_id , move |this| {
873
888
let expr_break =
874
889
hir:: ExprKind :: Break ( this. lower_loop_destination ( None ) , Some ( x_expr) ) ;
875
890
this. arena . alloc ( this. expr ( gen_future_span, expr_break) )
@@ -1101,8 +1116,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1101
1116
hir:: CoroutineSource :: Closure ,
1102
1117
) ;
1103
1118
1104
- let hir_id = this. lower_node_id ( coroutine_kind. closure_id ( ) ) ;
1105
- this. maybe_forward_track_caller ( body. span , closure_hir_id, hir_id) ;
1119
+ this. maybe_forward_track_caller ( body. span , closure_hir_id, expr. hir_id ) ;
1106
1120
1107
1121
( parameters, expr)
1108
1122
} ) ;
@@ -1465,26 +1479,37 @@ impl<'hir> LoweringContext<'_, 'hir> {
1465
1479
)
1466
1480
}
1467
1481
1468
- fn lower_label ( & self , opt_label : Option < Label > ) -> Option < Label > {
1482
+ // Record labelled expr's HirId so that we can retrieve it in `lower_jump_destination` without
1483
+ // lowering node id again.
1484
+ fn lower_label (
1485
+ & mut self ,
1486
+ opt_label : Option < Label > ,
1487
+ dest_id : NodeId ,
1488
+ dest_hir_id : hir:: HirId ,
1489
+ ) -> Option < Label > {
1469
1490
let label = opt_label?;
1491
+ self . ident_and_label_to_local_id . insert ( dest_id, dest_hir_id. local_id ) ;
1470
1492
Some ( Label { ident : self . lower_ident ( label. ident ) } )
1471
1493
}
1472
1494
1473
1495
fn lower_loop_destination ( & mut self , destination : Option < ( NodeId , Label ) > ) -> hir:: Destination {
1474
1496
let target_id = match destination {
1475
1497
Some ( ( id, _) ) => {
1476
1498
if let Some ( loop_id) = self . resolver . get_label_res ( id) {
1477
- Ok ( self . lower_node_id ( loop_id) )
1499
+ let local_id = self . ident_and_label_to_local_id [ & loop_id] ;
1500
+ let loop_hir_id = HirId { owner : self . current_hir_id_owner , local_id } ;
1501
+ Ok ( loop_hir_id)
1478
1502
} else {
1479
1503
Err ( hir:: LoopIdError :: UnresolvedLabel )
1480
1504
}
1481
1505
}
1482
- None => self
1483
- . loop_scope
1484
- . map ( |id| Ok ( self . lower_node_id ( id) ) )
1485
- . unwrap_or ( Err ( hir:: LoopIdError :: OutsideLoopScope ) ) ,
1506
+ None => {
1507
+ self . loop_scope . map ( |id| Ok ( id) ) . unwrap_or ( Err ( hir:: LoopIdError :: OutsideLoopScope ) )
1508
+ }
1486
1509
} ;
1487
- let label = self . lower_label ( destination. map ( |( _, label) | label) ) ;
1510
+ let label = destination
1511
+ . map ( |( _, label) | label)
1512
+ . map ( |label| Label { ident : self . lower_ident ( label. ident ) } ) ;
1488
1513
hir:: Destination { label, target_id }
1489
1514
}
1490
1515
@@ -1499,14 +1524,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
1499
1524
}
1500
1525
}
1501
1526
1502
- fn with_catch_scope < T > ( & mut self , catch_id : NodeId , f : impl FnOnce ( & mut Self ) -> T ) -> T {
1527
+ fn with_catch_scope < T > ( & mut self , catch_id : hir :: HirId , f : impl FnOnce ( & mut Self ) -> T ) -> T {
1503
1528
let old_scope = self . catch_scope . replace ( catch_id) ;
1504
1529
let result = f ( self ) ;
1505
1530
self . catch_scope = old_scope;
1506
1531
result
1507
1532
}
1508
1533
1509
- fn with_loop_scope < T > ( & mut self , loop_id : NodeId , f : impl FnOnce ( & mut Self ) -> T ) -> T {
1534
+ fn with_loop_scope < T > ( & mut self , loop_id : hir :: HirId , f : impl FnOnce ( & mut Self ) -> T ) -> T {
1510
1535
// We're no longer in the base loop's condition; we're in another loop.
1511
1536
let was_in_loop_condition = self . is_in_loop_condition ;
1512
1537
self . is_in_loop_condition = false ;
@@ -1658,17 +1683,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
1658
1683
let head_span = self . mark_span_with_reason ( DesugaringKind :: ForLoop , head. span , None ) ;
1659
1684
let pat_span = self . mark_span_with_reason ( DesugaringKind :: ForLoop , pat. span , None ) ;
1660
1685
1686
+ let loop_hir_id = self . lower_node_id ( e. id ) ;
1687
+ let label = self . lower_label ( opt_label, e. id , loop_hir_id) ;
1688
+
1661
1689
// `None => break`
1662
1690
let none_arm = {
1663
- let break_expr = self . with_loop_scope ( e. id , |this| this. expr_break_alloc ( for_span) ) ;
1691
+ let break_expr =
1692
+ self . with_loop_scope ( loop_hir_id, |this| this. expr_break_alloc ( for_span) ) ;
1664
1693
let pat = self . pat_none ( for_span) ;
1665
1694
self . arm ( pat, break_expr)
1666
1695
} ;
1667
1696
1668
1697
// Some(<pat>) => <body>,
1669
1698
let some_arm = {
1670
1699
let some_pat = self . pat_some ( pat_span, pat) ;
1671
- let body_block = self . with_loop_scope ( e. id , |this| this. lower_block ( body, false ) ) ;
1700
+ let body_block =
1701
+ self . with_loop_scope ( loop_hir_id, |this| this. lower_block ( body, false ) ) ;
1672
1702
let body_expr = self . arena . alloc ( self . expr_block ( body_block) ) ;
1673
1703
self . arm ( some_pat, body_expr)
1674
1704
} ;
@@ -1722,12 +1752,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
1722
1752
// `[opt_ident]: loop { ... }`
1723
1753
let kind = hir:: ExprKind :: Loop (
1724
1754
loop_block,
1725
- self . lower_label ( opt_label ) ,
1755
+ label ,
1726
1756
hir:: LoopSource :: ForLoop ,
1727
1757
self . lower_span ( for_span. with_hi ( head. span . hi ( ) ) ) ,
1728
1758
) ;
1729
- let loop_expr =
1730
- self . arena . alloc ( hir:: Expr { hir_id : self . lower_node_id ( e. id ) , kind, span : for_span } ) ;
1759
+ let loop_expr = self . arena . alloc ( hir:: Expr { hir_id : loop_hir_id, kind, span : for_span } ) ;
1731
1760
1732
1761
// `mut iter => { ... }`
1733
1762
let iter_arm = self . arm ( iter_pat, loop_expr) ;
@@ -1867,8 +1896,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
1867
1896
self . arena . alloc ( residual_expr) ,
1868
1897
unstable_span,
1869
1898
) ;
1870
- let ret_expr = if let Some ( catch_node ) = self . catch_scope {
1871
- let target_id = Ok ( self . lower_node_id ( catch_node ) ) ;
1899
+ let ret_expr = if let Some ( catch_id ) = self . catch_scope {
1900
+ let target_id = Ok ( catch_id ) ;
1872
1901
self . arena . alloc ( self . expr (
1873
1902
try_span,
1874
1903
hir:: ExprKind :: Break (
@@ -1922,8 +1951,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
1922
1951
yeeted_span,
1923
1952
) ;
1924
1953
1925
- if let Some ( catch_node ) = self . catch_scope {
1926
- let target_id = Ok ( self . lower_node_id ( catch_node ) ) ;
1954
+ if let Some ( catch_id ) = self . catch_scope {
1955
+ let target_id = Ok ( catch_id ) ;
1927
1956
hir:: ExprKind :: Break ( hir:: Destination { label : None , target_id } , Some ( from_yeet_expr) )
1928
1957
} else {
1929
1958
hir:: ExprKind :: Ret ( Some ( from_yeet_expr) )
0 commit comments