Skip to content

Commit d4e343c

Browse files
authored
Unrolled build for rust-lang#122063
Rollup merge of rust-lang#122063 - Zalathar:lower-if, r=oli-obk Make the lowering of `thir::ExprKind::If` easier to follow This targets a few code patterns that I found very confusing when I first tried to understand what this code is doing. No functional changes. I recommend looking at the changes individually, with whitespace hidden.
2 parents d03b986 + 250e697 commit d4e343c

File tree

1 file changed

+45
-36
lines changed
  • compiler/rustc_mir_build/src/build/expr

1 file changed

+45
-36
lines changed

compiler/rustc_mir_build/src/build/expr/into.rs

+45-36
Original file line numberDiff line numberDiff line change
@@ -58,52 +58,61 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5858
this.thir[scrutinee].span,
5959
),
6060
ExprKind::If { cond, then, else_opt, if_then_scope } => {
61-
let then_blk;
6261
let then_span = this.thir[then].span;
6362
let then_source_info = this.source_info(then_span);
6463
let condition_scope = this.local_scope();
6564

66-
let mut else_blk = unpack!(
67-
then_blk = this.in_scope(
68-
(if_then_scope, then_source_info),
69-
LintLevel::Inherited,
70-
|this| {
71-
let source_info = if this.is_let(cond) {
72-
let variable_scope =
73-
this.new_source_scope(then_span, LintLevel::Inherited, None);
74-
this.source_scope = variable_scope;
75-
SourceInfo { span: then_span, scope: variable_scope }
76-
} else {
77-
this.source_info(then_span)
78-
};
79-
let (then_block, else_block) =
80-
this.in_if_then_scope(condition_scope, then_span, |this| {
81-
let then_blk = unpack!(this.then_else_break(
82-
block,
83-
cond,
84-
Some(condition_scope), // Temp scope
85-
condition_scope,
86-
source_info,
87-
true, // Declare `let` bindings normally
88-
));
89-
90-
this.expr_into_dest(destination, then_blk, then)
91-
});
92-
then_block.and(else_block)
93-
},
94-
)
65+
let then_and_else_blocks = this.in_scope(
66+
(if_then_scope, then_source_info),
67+
LintLevel::Inherited,
68+
|this| {
69+
// FIXME: Does this need extra logic to handle let-chains?
70+
let source_info = if this.is_let(cond) {
71+
let variable_scope =
72+
this.new_source_scope(then_span, LintLevel::Inherited, None);
73+
this.source_scope = variable_scope;
74+
SourceInfo { span: then_span, scope: variable_scope }
75+
} else {
76+
this.source_info(then_span)
77+
};
78+
79+
// Lower the condition, and have it branch into `then` and `else` blocks.
80+
let (then_block, else_block) =
81+
this.in_if_then_scope(condition_scope, then_span, |this| {
82+
let then_blk = unpack!(this.then_else_break(
83+
block,
84+
cond,
85+
Some(condition_scope), // Temp scope
86+
condition_scope,
87+
source_info,
88+
true, // Declare `let` bindings normally
89+
));
90+
91+
// Lower the `then` arm into its block.
92+
this.expr_into_dest(destination, then_blk, then)
93+
});
94+
95+
// Pack `(then_block, else_block)` into `BlockAnd<BasicBlock>`.
96+
then_block.and(else_block)
97+
},
9598
);
9699

97-
else_blk = if let Some(else_opt) = else_opt {
98-
unpack!(this.expr_into_dest(destination, else_blk, else_opt))
100+
// Unpack `BlockAnd<BasicBlock>` into `(then_blk, else_blk)`.
101+
let (then_blk, mut else_blk);
102+
else_blk = unpack!(then_blk = then_and_else_blocks);
103+
104+
// If there is an `else` arm, lower it into `else_blk`.
105+
if let Some(else_expr) = else_opt {
106+
unpack!(else_blk = this.expr_into_dest(destination, else_blk, else_expr));
99107
} else {
100-
// Body of the `if` expression without an `else` clause must return `()`, thus
101-
// we implicitly generate an `else {}` if it is not specified.
108+
// There is no `else` arm, so we know both arms have type `()`.
109+
// Generate the implicit `else {}` by assigning unit.
102110
let correct_si = this.source_info(expr_span.shrink_to_hi());
103111
this.cfg.push_assign_unit(else_blk, correct_si, destination, this.tcx);
104-
else_blk
105-
};
112+
}
106113

114+
// The `then` and `else` arms have been lowered into their respective
115+
// blocks, so make both of them meet up in a new block.
107116
let join_block = this.cfg.start_new_block();
108117
this.cfg.goto(then_blk, source_info, join_block);
109118
this.cfg.goto(else_blk, source_info, join_block);

0 commit comments

Comments
 (0)