@@ -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. 
512524fn  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