1
- use super :: { ImplTraitContext , LoweringContext , ParamMode , ParenthesizedGenericArgs } ;
1
+ use super :: {
2
+ ConditionScope , ImplTraitContext , LoweringContext , ParamMode , ParenthesizedGenericArgs ,
3
+ } ;
2
4
3
5
use rustc_ast:: attr;
4
6
use rustc_ast:: ptr:: P as AstP ;
@@ -15,6 +17,8 @@ use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
15
17
use rustc_span:: symbol:: { sym, Ident , Symbol } ;
16
18
use rustc_span:: { hygiene:: ForLoopLoc , DUMMY_SP } ;
17
19
20
+ use std:: mem;
21
+
18
22
impl < ' hir > LoweringContext < ' _ , ' hir > {
19
23
fn lower_exprs ( & mut self , exprs : & [ AstP < Expr > ] ) -> & ' hir [ hir:: Expr < ' hir > ] {
20
24
self . arena . alloc_from_iter ( exprs. iter ( ) . map ( |x| self . lower_expr_mut ( x) ) )
@@ -87,7 +91,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
87
91
hir:: ExprKind :: AddrOf ( k, m, ohs)
88
92
}
89
93
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
+ )
91
106
}
92
107
ExprKind :: If ( ref cond, ref then, ref else_opt) => {
93
108
self . lower_expr_if ( cond, then, else_opt. as_deref ( ) )
@@ -354,14 +369,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
354
369
then : & Block ,
355
370
else_opt : Option < & Expr > ,
356
371
) -> 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) ) ;
358
373
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)
365
377
}
366
378
367
379
// If `cond` kind is `let`, returns `let`. Otherwise, wraps and returns `cond`
@@ -400,7 +412,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
400
412
body : & Block ,
401
413
opt_label : Option < Label > ,
402
414
) -> 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) ) ;
404
416
let new_cond = self . manage_let_cond ( lowered_cond) ;
405
417
let then = self . lower_block_expr ( body) ;
406
418
let expr_break = self . expr_break ( span, ThinVec :: new ( ) ) ;
@@ -473,7 +485,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
473
485
if let ExprKind :: Let ( ref pat, ref scrutinee, _) = cond. kind {
474
486
hir:: Guard :: IfLet ( self . lower_pat ( pat) , self . lower_expr ( scrutinee) )
475
487
} 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)
477
490
}
478
491
} ) ;
479
492
let hir_id = self . next_id ( ) ;
@@ -732,7 +745,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
732
745
( body_id, generator_option)
733
746
} ) ;
734
747
735
- // Lower outside new scope to preserve `is_in_loop_condition `.
748
+ // Lower outside new scope to preserve `condition_scope `.
736
749
let fn_decl = self . lower_fn_decl ( decl, None , false , None ) ;
737
750
738
751
hir:: ExprKind :: Closure ( capture_clause, fn_decl, body_id, fn_decl_span, generator_option)
@@ -1132,7 +1145,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1132
1145
}
1133
1146
1134
1147
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 ) {
1136
1149
hir:: Destination {
1137
1150
label : None ,
1138
1151
target_id : Err ( hir:: LoopIdError :: UnlabeledCfInWhileCondition ) ,
@@ -1160,8 +1173,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
1160
1173
1161
1174
fn with_loop_scope < T > ( & mut self , loop_id : NodeId , f : impl FnOnce ( & mut Self ) -> T ) -> T {
1162
1175
// 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 ) ;
1165
1177
1166
1178
let len = self . loop_scopes . len ( ) ;
1167
1179
self . loop_scopes . push ( loop_id) ;
@@ -1175,19 +1187,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
1175
1187
1176
1188
self . loop_scopes . pop ( ) . unwrap ( ) ;
1177
1189
1178
- self . is_in_loop_condition = was_in_loop_condition ;
1190
+ self . condition_scope = condition_scope ;
1179
1191
1180
1192
result
1181
1193
}
1182
1194
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) ) ;
1187
1201
let result = f ( self ) ;
1188
-
1189
- self . is_in_loop_condition = was_in_loop_condition;
1190
-
1202
+ self . condition_scope = condition_scope;
1191
1203
result
1192
1204
}
1193
1205
0 commit comments