Skip to content

Commit 2d9f2ea

Browse files
matthewjasperc410-f3r
authored andcommitted
Use correct drop scopes for if expressions
1 parent c0490a2 commit 2d9f2ea

File tree

3 files changed

+75
-7
lines changed

3 files changed

+75
-7
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -443,9 +443,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
443443
else_opt: Option<&Expr>,
444444
) -> hir::ExprKind<'hir> {
445445
let cond = self.lower_expr(cond);
446-
let then = self.arena.alloc(self.lower_block_expr(then));
447-
let els = else_opt.map(|els| self.lower_expr(els));
448-
hir::ExprKind::If(cond, then, els)
446+
let wrapped_cond = match cond.kind {
447+
hir::ExprKind::Let(..) => cond,
448+
_ => self.expr_drop_temps(cond.span, cond, AttrVec::new()),
449+
};
450+
let then_expr = self.lower_block_expr(then);
451+
if let Some(rslt) = else_opt {
452+
hir::ExprKind::If(
453+
wrapped_cond,
454+
self.arena.alloc(then_expr),
455+
Some(self.lower_expr(rslt)),
456+
)
457+
} else {
458+
hir::ExprKind::If(wrapped_cond, self.arena.alloc(then_expr), None)
459+
}
449460
}
450461

451462
fn lower_expr_if_let(

compiler/rustc_mir_build/src/build/matches/mod.rs

+41
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,47 @@ use std::convert::TryFrom;
3535
use std::mem;
3636

3737
impl<'a, 'tcx> Builder<'a, 'tcx> {
38+
pub(crate) fn then_else_blocks(
39+
&mut self,
40+
mut block: BasicBlock,
41+
expr: ExprRef<'tcx>,
42+
source_info: SourceInfo,
43+
) -> (BasicBlock, BasicBlock) {
44+
let this = self;
45+
let expr = this.hir.mirror(expr);
46+
let expr_span = expr.span;
47+
48+
match expr.kind {
49+
ExprKind::Scope { region_scope, lint_level, value } => {
50+
let region_scope = (region_scope, source_info);
51+
let then_block;
52+
let else_block = unpack!(
53+
then_block = this.in_scope(region_scope, lint_level, |this| {
54+
let (then_block, else_block) =
55+
this.then_else_blocks(block, value, source_info);
56+
then_block.and(else_block)
57+
})
58+
);
59+
(then_block, else_block)
60+
}
61+
ExprKind::Let { expr, pat } => {
62+
// TODO: Use correct span.
63+
this.lower_let(block, &expr, &pat, expr_span)
64+
}
65+
_ => {
66+
let local_scope = Some(this.local_scope());
67+
let place =
68+
unpack!(block = this.as_temp(block, local_scope, expr, Mutability::Mut));
69+
let operand = Operand::Move(Place::from(place));
70+
let then_block = this.cfg.start_new_block();
71+
let else_block = this.cfg.start_new_block();
72+
let term = TerminatorKind::if_(this.hir.tcx(), operand, then_block, else_block);
73+
this.cfg.terminate(block, source_info, term);
74+
(then_block, else_block)
75+
}
76+
}
77+
}
78+
3879
/// Generates MIR for a `match` expression.
3980
///
4081
/// The MIR that we generate for a match looks like this.

compiler/rustc_passes/src/region.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -233,14 +233,12 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
233233
terminating(r.hir_id.local_id);
234234
}
235235

236-
hir::ExprKind::If(ref expr, ref then, Some(ref otherwise)) => {
237-
terminating(expr.hir_id.local_id);
236+
hir::ExprKind::If(_, ref then, Some(ref otherwise)) => {
238237
terminating(then.hir_id.local_id);
239238
terminating(otherwise.hir_id.local_id);
240239
}
241240

242-
hir::ExprKind::If(ref expr, ref then, None) => {
243-
terminating(expr.hir_id.local_id);
241+
hir::ExprKind::If(_, ref then, None) => {
244242
terminating(then.hir_id.local_id);
245243
}
246244

@@ -392,6 +390,24 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
392390
}
393391
}
394392

393+
hir::ExprKind::If(ref cond, ref then, Some(ref otherwise)) => {
394+
// FIXME(matthewjasper): ideally the scope we use here would only
395+
// contain the condition and then expression. This works, but
396+
// can result in some extra drop flags.
397+
visitor.cx.var_parent = visitor.cx.parent;
398+
visitor.visit_expr(cond);
399+
visitor.cx.var_parent = prev_cx.var_parent;
400+
visitor.visit_expr(then);
401+
visitor.visit_expr(otherwise);
402+
}
403+
404+
hir::ExprKind::If(ref cond, ref then, None) => {
405+
visitor.cx.var_parent = visitor.cx.parent;
406+
visitor.visit_expr(cond);
407+
visitor.cx.var_parent = prev_cx.var_parent;
408+
visitor.visit_expr(then);
409+
}
410+
395411
_ => intravisit::walk_expr(visitor, expr),
396412
}
397413

0 commit comments

Comments
 (0)