@@ -176,23 +176,34 @@ fn resolve_block<'tcx>(
176176 visitor. cx = prev_cx;
177177}
178178
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+ }
187197
198+ fn resolve_arm < ' tcx > ( visitor : & mut ScopeResolutionVisitor < ' tcx > , arm : & ' tcx hir:: Arm < ' tcx > ) {
188199 let prev_cx = visitor. cx ;
189200
190201 visitor. enter_node_scope_with_dtor ( arm. hir_id . local_id , true ) ;
191202 visitor. cx . var_parent = visitor. cx . parent ;
192203
193204 resolve_pat ( visitor, arm. pat ) ;
194205 if let Some ( guard) = arm. guard {
195- resolve_expr ( visitor, guard, ! has_let_expr ( guard ) ) ;
206+ resolve_cond ( visitor, guard) ;
196207 }
197208 resolve_expr ( visitor, arm. body , false ) ;
198209
@@ -420,7 +431,7 @@ fn resolve_expr<'tcx>(
420431 } ;
421432 visitor. enter_scope ( Scope { local_id : then. hir_id . local_id , data } ) ;
422433 visitor. cx . var_parent = visitor. cx . parent ;
423- visitor . visit_expr ( cond) ;
434+ resolve_cond ( visitor , cond) ;
424435 resolve_expr ( visitor, then, true ) ;
425436 visitor. cx = expr_cx;
426437 resolve_expr ( visitor, otherwise, true ) ;
@@ -435,7 +446,7 @@ fn resolve_expr<'tcx>(
435446 } ;
436447 visitor. enter_scope ( Scope { local_id : then. hir_id . local_id , data } ) ;
437448 visitor. cx . var_parent = visitor. cx . parent ;
438- visitor . visit_expr ( cond) ;
449+ resolve_cond ( visitor , cond) ;
439450 resolve_expr ( visitor, then, true ) ;
440451 visitor. cx = expr_cx;
441452 }
0 commit comments