@@ -70,8 +70,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
7070 _ => ( ) ,
7171 }
7272
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 ) ;
7575
7676 let kind = match & e. kind {
7777 ExprKind :: Array ( exprs) => hir:: ExprKind :: Array ( self . lower_exprs ( exprs) ) ,
@@ -175,18 +175,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
175175 ExprKind :: If ( cond, then, else_opt) => {
176176 self . lower_expr_if ( cond, then, else_opt. as_deref ( ) )
177177 }
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+ }
190197 ExprKind :: TryBlock ( body) => self . lower_expr_try_block ( body) ,
191198 ExprKind :: Match ( expr, arms, kind) => hir:: ExprKind :: Match (
192199 self . lower_expr ( expr) ,
@@ -212,7 +219,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
212219 binder,
213220 * capture_clause,
214221 e. id ,
215- hir_id ,
222+ expr_hir_id ,
216223 * coroutine_kind,
217224 fn_decl,
218225 body,
@@ -223,7 +230,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
223230 binder,
224231 * capture_clause,
225232 e. id ,
226- hir_id ,
233+ expr_hir_id ,
227234 * constness,
228235 * movability,
229236 fn_decl,
@@ -250,8 +257,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
250257 )
251258 }
252259 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+ hir:: ExprKind :: Block (
265+ self . lower_block_with_hir_id ( blk, block_hir_id, opt_label. is_some ( ) ) ,
266+ opt_label,
267+ )
255268 }
256269 ExprKind :: Assign ( el, er, span) => self . lower_expr_assign ( el, er, * span, e. span ) ,
257270 ExprKind :: AssignOp ( op, el, er) => hir:: ExprKind :: AssignOp (
@@ -352,7 +365,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
352365 ExprKind :: MacCall ( _) => panic ! ( "{:?} shouldn't exist here" , e. span) ,
353366 } ;
354367
355- hir:: Expr { hir_id, kind, span : self . lower_span ( e. span ) }
368+ hir:: Expr { hir_id : expr_hir_id , kind, span : self . lower_span ( e. span ) }
356369 } )
357370 }
358371
@@ -502,16 +515,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
502515 let if_expr = self . expr ( span, if_kind) ;
503516 let block = self . block_expr ( self . arena . alloc ( if_expr) ) ;
504517 let span = self . lower_span ( span. with_hi ( cond. span . hi ( ) ) ) ;
505- let opt_label = self . lower_label ( opt_label) ;
506518 hir:: ExprKind :: Loop ( block, opt_label, hir:: LoopSource :: While , span)
507519 }
508520
509521 /// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_output(<expr>) }`,
510522 /// `try { <stmts>; }` into `{ <stmts>; ::std::ops::Try::from_output(()) }`
511523 /// and save the block id to use it as a break target for desugaring of the `?` operator.
512524 fn lower_expr_try_block ( & mut self , body : & Block ) -> hir:: ExprKind < ' hir > {
513- self . with_catch_scope ( body. id , |this| {
514- let mut block = this. lower_block_noalloc ( body, true ) ;
525+ let body_hir_id = self . lower_node_id ( body. id ) ;
526+ self . with_catch_scope ( body_hir_id, |this| {
527+ let mut block = this. lower_block_noalloc ( body_hir_id, body, true ) ;
515528
516529 // Final expression of the block (if present) or `()` with span at the end of block
517530 let ( try_span, tail_expr) = if let Some ( expr) = block. expr . take ( ) {
@@ -869,7 +882,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
869882 let x_expr = self . expr_ident ( gen_future_span, x_ident, x_pat_hid) ;
870883 let ready_field = self . single_pat_field ( gen_future_span, x_pat) ;
871884 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| {
885+ let break_x = self . with_loop_scope ( loop_hir_id , move |this| {
873886 let expr_break =
874887 hir:: ExprKind :: Break ( this. lower_loop_destination ( None ) , Some ( x_expr) ) ;
875888 this. arena . alloc ( this. expr ( gen_future_span, expr_break) )
@@ -1101,8 +1114,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11011114 hir:: CoroutineSource :: Closure ,
11021115 ) ;
11031116
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) ;
1117+ this. maybe_forward_track_caller ( body. span , closure_hir_id, expr. hir_id ) ;
11061118
11071119 ( parameters, expr)
11081120 } ) ;
@@ -1462,26 +1474,37 @@ impl<'hir> LoweringContext<'_, 'hir> {
14621474 )
14631475 }
14641476
1465- fn lower_label ( & self , opt_label : Option < Label > ) -> Option < Label > {
1477+ // Record labelled expr's HirId so that we can retrieve it in `lower_jump_destination` without
1478+ // lowering node id again.
1479+ fn lower_label (
1480+ & mut self ,
1481+ opt_label : Option < Label > ,
1482+ dest_id : NodeId ,
1483+ dest_hir_id : hir:: HirId ,
1484+ ) -> Option < Label > {
14661485 let label = opt_label?;
1486+ self . labelled_node_id_to_local_id . insert ( dest_id, dest_hir_id. local_id ) ;
14671487 Some ( Label { ident : self . lower_ident ( label. ident ) } )
14681488 }
14691489
14701490 fn lower_loop_destination ( & mut self , destination : Option < ( NodeId , Label ) > ) -> hir:: Destination {
14711491 let target_id = match destination {
14721492 Some ( ( id, _) ) => {
14731493 if let Some ( loop_id) = self . resolver . get_label_res ( id) {
1474- Ok ( self . lower_node_id ( loop_id) )
1494+ let local_id = self . labelled_node_id_to_local_id [ & loop_id] ;
1495+ let loop_hir_id = HirId { owner : self . current_hir_id_owner , local_id } ;
1496+ Ok ( loop_hir_id)
14751497 } else {
14761498 Err ( hir:: LoopIdError :: UnresolvedLabel )
14771499 }
14781500 }
1479- None => self
1480- . loop_scope
1481- . map ( |id| Ok ( self . lower_node_id ( id) ) )
1482- . unwrap_or ( Err ( hir:: LoopIdError :: OutsideLoopScope ) ) ,
1501+ None => {
1502+ self . loop_scope . map ( |id| Ok ( id) ) . unwrap_or ( Err ( hir:: LoopIdError :: OutsideLoopScope ) )
1503+ }
14831504 } ;
1484- let label = self . lower_label ( destination. map ( |( _, label) | label) ) ;
1505+ let label = destination
1506+ . map ( |( _, label) | label)
1507+ . map ( |label| Label { ident : self . lower_ident ( label. ident ) } ) ;
14851508 hir:: Destination { label, target_id }
14861509 }
14871510
@@ -1496,14 +1519,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
14961519 }
14971520 }
14981521
1499- fn with_catch_scope < T > ( & mut self , catch_id : NodeId , f : impl FnOnce ( & mut Self ) -> T ) -> T {
1522+ fn with_catch_scope < T > ( & mut self , catch_id : hir :: HirId , f : impl FnOnce ( & mut Self ) -> T ) -> T {
15001523 let old_scope = self . catch_scope . replace ( catch_id) ;
15011524 let result = f ( self ) ;
15021525 self . catch_scope = old_scope;
15031526 result
15041527 }
15051528
1506- fn with_loop_scope < T > ( & mut self , loop_id : NodeId , f : impl FnOnce ( & mut Self ) -> T ) -> T {
1529+ fn with_loop_scope < T > ( & mut self , loop_id : hir :: HirId , f : impl FnOnce ( & mut Self ) -> T ) -> T {
15071530 // We're no longer in the base loop's condition; we're in another loop.
15081531 let was_in_loop_condition = self . is_in_loop_condition ;
15091532 self . is_in_loop_condition = false ;
@@ -1655,17 +1678,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
16551678 let head_span = self . mark_span_with_reason ( DesugaringKind :: ForLoop , head. span , None ) ;
16561679 let pat_span = self . mark_span_with_reason ( DesugaringKind :: ForLoop , pat. span , None ) ;
16571680
1681+ let loop_hir_id = self . lower_node_id ( e. id ) ;
1682+ let label = self . lower_label ( opt_label, e. id , loop_hir_id) ;
1683+
16581684 // `None => break`
16591685 let none_arm = {
1660- let break_expr = self . with_loop_scope ( e. id , |this| this. expr_break_alloc ( for_span) ) ;
1686+ let break_expr =
1687+ self . with_loop_scope ( loop_hir_id, |this| this. expr_break_alloc ( for_span) ) ;
16611688 let pat = self . pat_none ( for_span) ;
16621689 self . arm ( pat, break_expr)
16631690 } ;
16641691
16651692 // Some(<pat>) => <body>,
16661693 let some_arm = {
16671694 let some_pat = self . pat_some ( pat_span, pat) ;
1668- let body_block = self . with_loop_scope ( e. id , |this| this. lower_block ( body, false ) ) ;
1695+ let body_block =
1696+ self . with_loop_scope ( loop_hir_id, |this| this. lower_block ( body, false ) ) ;
16691697 let body_expr = self . arena . alloc ( self . expr_block ( body_block) ) ;
16701698 self . arm ( some_pat, body_expr)
16711699 } ;
@@ -1719,12 +1747,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
17191747 // `[opt_ident]: loop { ... }`
17201748 let kind = hir:: ExprKind :: Loop (
17211749 loop_block,
1722- self . lower_label ( opt_label ) ,
1750+ label ,
17231751 hir:: LoopSource :: ForLoop ,
17241752 self . lower_span ( for_span. with_hi ( head. span . hi ( ) ) ) ,
17251753 ) ;
1726- let loop_expr =
1727- self . arena . alloc ( hir:: Expr { hir_id : self . lower_node_id ( e. id ) , kind, span : for_span } ) ;
1754+ let loop_expr = self . arena . alloc ( hir:: Expr { hir_id : loop_hir_id, kind, span : for_span } ) ;
17281755
17291756 // `mut iter => { ... }`
17301757 let iter_arm = self . arm ( iter_pat, loop_expr) ;
@@ -1864,8 +1891,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
18641891 self . arena . alloc ( residual_expr) ,
18651892 unstable_span,
18661893 ) ;
1867- let ret_expr = if let Some ( catch_node ) = self . catch_scope {
1868- let target_id = Ok ( self . lower_node_id ( catch_node ) ) ;
1894+ let ret_expr = if let Some ( catch_id ) = self . catch_scope {
1895+ let target_id = Ok ( catch_id ) ;
18691896 self . arena . alloc ( self . expr (
18701897 try_span,
18711898 hir:: ExprKind :: Break (
@@ -1919,8 +1946,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
19191946 yeeted_span,
19201947 ) ;
19211948
1922- if let Some ( catch_node ) = self . catch_scope {
1923- let target_id = Ok ( self . lower_node_id ( catch_node ) ) ;
1949+ if let Some ( catch_id ) = self . catch_scope {
1950+ let target_id = Ok ( catch_id ) ;
19241951 hir:: ExprKind :: Break ( hir:: Destination { label : None , target_id } , Some ( from_yeet_expr) )
19251952 } else {
19261953 hir:: ExprKind :: Ret ( Some ( from_yeet_expr) )
0 commit comments