1- use super :: { ImplTraitContext , LoweringContext , ParamMode , ParenthesizedGenericArgs } ;
1+ use super :: {
2+ ConditionScope , ImplTraitContext , LoweringContext , ParamMode , ParenthesizedGenericArgs ,
3+ } ;
24
35use rustc_ast:: attr;
46use rustc_ast:: ptr:: P as AstP ;
@@ -15,6 +17,8 @@ use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
1517use rustc_span:: symbol:: { sym, Ident , Symbol } ;
1618use rustc_span:: { hygiene:: ForLoopLoc , DUMMY_SP } ;
1719
20+ use std:: mem;
21+
1822impl < ' hir > LoweringContext < ' _ , ' hir > {
1923 fn lower_exprs ( & mut self , exprs : & [ AstP < Expr > ] ) -> & ' hir [ hir:: Expr < ' hir > ] {
2024 self . arena . alloc_from_iter ( exprs. iter ( ) . map ( |x| self . lower_expr_mut ( x) ) )
@@ -87,7 +91,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
8791 hir:: ExprKind :: AddrOf ( k, m, ohs)
8892 }
8993 ExprKind :: Let ( ref pat, ref scrutinee, span) => {
90- hir:: ExprKind :: Let ( self . lower_pat ( pat) , self . lower_expr ( scrutinee) , span)
94+ let source = match self . condition_scope {
95+ Some ( ConditionScope :: Guard ) => hir:: LetSource :: Guard ,
96+ Some ( ConditionScope :: If ) => hir:: LetSource :: If ,
97+ Some ( ConditionScope :: While ) => hir:: LetSource :: While ,
98+ _ => hir:: LetSource :: Local ,
99+ } ;
100+ hir:: ExprKind :: Let (
101+ self . lower_pat ( pat) ,
102+ self . lower_expr ( scrutinee) ,
103+ span,
104+ source,
105+ )
91106 }
92107 ExprKind :: If ( ref cond, ref then, ref else_opt) => {
93108 self . lower_expr_if ( cond, then, else_opt. as_deref ( ) )
@@ -354,14 +369,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
354369 then : & Block ,
355370 else_opt : Option < & Expr > ,
356371 ) -> hir:: ExprKind < ' hir > {
357- let lowered_cond = self . lower_expr ( cond) ;
372+ let lowered_cond = self . with_condition_scope ( ConditionScope :: If , |t| t . lower_expr ( cond) ) ;
358373 let new_cond = self . manage_let_cond ( lowered_cond) ;
359- let then_expr = self . lower_block_expr ( then) ;
360- if let Some ( rslt) = else_opt {
361- hir:: ExprKind :: If ( new_cond, self . arena . alloc ( then_expr) , Some ( self . lower_expr ( rslt) ) )
362- } else {
363- hir:: ExprKind :: If ( new_cond, self . arena . alloc ( then_expr) , None )
364- }
374+ let then_expr = self . arena . alloc ( self . lower_block_expr ( then) ) ;
375+ let else_opt = else_opt. map ( |e| self . lower_expr ( e) ) ;
376+ hir:: ExprKind :: If ( new_cond, then_expr, else_opt)
365377 }
366378
367379 // If `cond` kind is `let`, returns `let`. Otherwise, wraps and returns `cond`
@@ -400,7 +412,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
400412 body : & Block ,
401413 opt_label : Option < Label > ,
402414 ) -> hir:: ExprKind < ' hir > {
403- let lowered_cond = self . with_loop_condition_scope ( |t| t. lower_expr ( cond) ) ;
415+ let lowered_cond = self . with_condition_scope ( ConditionScope :: While , |t| t. lower_expr ( cond) ) ;
404416 let new_cond = self . manage_let_cond ( lowered_cond) ;
405417 let then = self . lower_block_expr ( body) ;
406418 let expr_break = self . expr_break ( span, ThinVec :: new ( ) ) ;
@@ -473,7 +485,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
473485 if let ExprKind :: Let ( ref pat, ref scrutinee, _) = cond. kind {
474486 hir:: Guard :: IfLet ( self . lower_pat ( pat) , self . lower_expr ( scrutinee) )
475487 } else {
476- hir:: Guard :: If ( self . lower_expr ( cond) )
488+ let cond = self . with_condition_scope ( ConditionScope :: Guard , |t| t. lower_expr ( cond) ) ;
489+ hir:: Guard :: If ( cond)
477490 }
478491 } ) ;
479492 let hir_id = self . next_id ( ) ;
@@ -732,7 +745,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
732745 ( body_id, generator_option)
733746 } ) ;
734747
735- // Lower outside new scope to preserve `is_in_loop_condition `.
748+ // Lower outside new scope to preserve `condition_scope `.
736749 let fn_decl = self . lower_fn_decl ( decl, None , false , None ) ;
737750
738751 hir:: ExprKind :: Closure ( capture_clause, fn_decl, body_id, fn_decl_span, generator_option)
@@ -1132,7 +1145,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11321145 }
11331146
11341147 fn lower_jump_destination ( & mut self , id : NodeId , opt_label : Option < Label > ) -> hir:: Destination {
1135- if self . is_in_loop_condition && opt_label . is_none ( ) {
1148+ if opt_label . is_none ( ) && self . condition_scope == Some ( ConditionScope :: While ) {
11361149 hir:: Destination {
11371150 label : None ,
11381151 target_id : Err ( hir:: LoopIdError :: UnlabeledCfInWhileCondition ) ,
@@ -1160,8 +1173,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11601173
11611174 fn with_loop_scope < T > ( & mut self , loop_id : NodeId , f : impl FnOnce ( & mut Self ) -> T ) -> T {
11621175 // We're no longer in the base loop's condition; we're in another loop.
1163- let was_in_loop_condition = self . is_in_loop_condition ;
1164- self . is_in_loop_condition = false ;
1176+ let condition_scope = mem:: take ( & mut self . condition_scope ) ;
11651177
11661178 let len = self . loop_scopes . len ( ) ;
11671179 self . loop_scopes . push ( loop_id) ;
@@ -1175,19 +1187,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
11751187
11761188 self . loop_scopes . pop ( ) . unwrap ( ) ;
11771189
1178- self . is_in_loop_condition = was_in_loop_condition ;
1190+ self . condition_scope = condition_scope ;
11791191
11801192 result
11811193 }
11821194
1183- fn with_loop_condition_scope < T > ( & mut self , f : impl FnOnce ( & mut Self ) -> T ) -> T {
1184- let was_in_loop_condition = self . is_in_loop_condition ;
1185- self . is_in_loop_condition = true ;
1186-
1195+ fn with_condition_scope < T > (
1196+ & mut self ,
1197+ condition_scope : ConditionScope ,
1198+ f : impl FnOnce ( & mut Self ) -> T ,
1199+ ) -> T {
1200+ let condition_scope = mem:: replace ( & mut self . condition_scope , Some ( condition_scope) ) ;
11871201 let result = f ( self ) ;
1188-
1189- self . is_in_loop_condition = was_in_loop_condition;
1190-
1202+ self . condition_scope = condition_scope;
11911203 result
11921204 }
11931205
0 commit comments