@@ -176,23 +176,34 @@ fn resolve_block<'tcx>(
176
176
visitor. cx = prev_cx;
177
177
}
178
178
179
- fn resolve_arm < ' tcx > ( visitor : & mut ScopeResolutionVisitor < ' tcx > , arm : & ' tcx hir:: Arm < ' tcx > ) {
180
- fn has_let_expr ( expr : & Expr < ' _ > ) -> bool {
181
- match & expr. kind {
182
- hir:: ExprKind :: Binary ( _, lhs, rhs) => has_let_expr ( lhs) || has_let_expr ( rhs) ,
183
- hir:: ExprKind :: Let ( ..) => true ,
184
- _ => false ,
185
- }
186
- }
179
+ /// Resolve a condition from an `if` expression or match guard so that it is a terminating scope
180
+ /// if it doesn't contain `let` expressions.
181
+ fn resolve_cond < ' tcx > ( visitor : & mut ScopeResolutionVisitor < ' tcx > , cond : & ' tcx hir:: Expr < ' tcx > ) {
182
+ let terminate = match cond. kind {
183
+ // Temporaries for `let` expressions must live into the success branch.
184
+ hir:: ExprKind :: Let ( _) => false ,
185
+ // Logical operator chains are handled in `resolve_expr`. The operators themselves have no
186
+ // intermediate value to drop, and operands will be wrapped in terminating scopes.
187
+ hir:: ExprKind :: Binary (
188
+ source_map:: Spanned { node : hir:: BinOpKind :: And | hir:: BinOpKind :: Or , .. } ,
189
+ _,
190
+ _,
191
+ ) => false ,
192
+ // Otherwise, conditions should always drop their temporaries.
193
+ _ => true ,
194
+ } ;
195
+ resolve_expr ( visitor, cond, terminate) ;
196
+ }
187
197
198
+ fn resolve_arm < ' tcx > ( visitor : & mut ScopeResolutionVisitor < ' tcx > , arm : & ' tcx hir:: Arm < ' tcx > ) {
188
199
let prev_cx = visitor. cx ;
189
200
190
201
visitor. enter_node_scope_with_dtor ( arm. hir_id . local_id , true ) ;
191
202
visitor. cx . var_parent = visitor. cx . parent ;
192
203
193
204
resolve_pat ( visitor, arm. pat ) ;
194
205
if let Some ( guard) = arm. guard {
195
- resolve_expr ( visitor, guard, ! has_let_expr ( guard ) ) ;
206
+ resolve_cond ( visitor, guard) ;
196
207
}
197
208
resolve_expr ( visitor, arm. body , false ) ;
198
209
@@ -420,7 +431,7 @@ fn resolve_expr<'tcx>(
420
431
} ;
421
432
visitor. enter_scope ( Scope { local_id : then. hir_id . local_id , data } ) ;
422
433
visitor. cx . var_parent = visitor. cx . parent ;
423
- visitor . visit_expr ( cond) ;
434
+ resolve_cond ( visitor , cond) ;
424
435
resolve_expr ( visitor, then, true ) ;
425
436
visitor. cx = expr_cx;
426
437
resolve_expr ( visitor, otherwise, true ) ;
@@ -435,7 +446,7 @@ fn resolve_expr<'tcx>(
435
446
} ;
436
447
visitor. enter_scope ( Scope { local_id : then. hir_id . local_id , data } ) ;
437
448
visitor. cx . var_parent = visitor. cx . parent ;
438
- visitor . visit_expr ( cond) ;
449
+ resolve_cond ( visitor , cond) ;
439
450
resolve_expr ( visitor, then, true ) ;
440
451
visitor. cx = expr_cx;
441
452
}
0 commit comments