ExprKind::Match { scrutinee, ref arms } => {
this.match_expr(destination, expr_span, block, &this.thir[scrutinee], arms)
}
- ExprKind::If { cond, then, else_opt } => {
- let place = unpack!(
- block = this.as_temp(
- block,
- Some(this.local_scope()),
- &this.thir[cond],
- Mutability::Mut
+ ExprKind::If { cond, then, else_opt, if_then_scope } => {
+ let then_blk;
+ let then_expr = &this.thir[then];
+ let then_source_info = this.source_info(then_expr.span);
+ let condition_scope = this.local_scope();
+
+ let mut else_blk = unpack!(
+ then_blk = this.in_scope(
+ (if_then_scope, then_source_info),
+ LintLevel::Inherited,
+ |this| {
+ let (then_block, else_block) =
+ this.in_if_then_scope(condition_scope, |this| {
+ let then_blk = unpack!(this.then_else_break(
+ block,
+ &this.thir[cond],
+ Some(condition_scope),
+ condition_scope,
+ then_expr.span,
+ ));
+ this.expr_into_dest(destination, then_blk, then_expr)
+ });
+ then_block.and(else_block)
+ },
)
);
- let operand = Operand::Move(Place::from(place));
-
- let mut then_block = this.cfg.start_new_block();
- let mut else_block = this.cfg.start_new_block();
- let term = TerminatorKind::if_(this.tcx, operand, then_block, else_block);
- this.cfg.terminate(block, source_info, term);
- unpack!(
- then_block = this.expr_into_dest(destination, then_block, &this.thir[then])
- );
- else_block = if let Some(else_opt) = else_opt {
- unpack!(this.expr_into_dest(destination, else_block, &this.thir[else_opt]))
+ else_blk = if let Some(else_opt) = else_opt {
+ unpack!(this.expr_into_dest(destination, else_blk, &this.thir[else_opt]))
} else {
// Body of the `if` expression without an `else` clause must return `()`, thus
- // we implicitly generate a `else {}` if it is not specified.
+ // we implicitly generate an `else {}` if it is not specified.
let correct_si = this.source_info(expr_span.shrink_to_hi());
- this.cfg.push_assign_unit(else_block, correct_si, destination, this.tcx);
- else_block
+ this.cfg.push_assign_unit(else_blk, correct_si, destination, this.tcx);
+ else_blk
};
let join_block = this.cfg.start_new_block();
this.cfg.terminate(
- then_block,
+ then_blk,
source_info,
TerminatorKind::Goto { target: join_block },
);
this.cfg.terminate(
- else_block,
+ else_blk,
source_info,
TerminatorKind::Goto { target: join_block },
);
join_block.unit()
}
+ ExprKind::Let { expr, ref pat } => {
+ let scope = this.local_scope();
+ let (true_block, false_block) = this.in_if_then_scope(scope, |this| {
+ this.lower_let_expr(block, &this.thir[expr], pat, scope, expr_span)
+ });
+
+ let join_block = this.cfg.start_new_block();
+
+ this.cfg.push_assign_constant(
+ true_block,
+ source_info,
+ destination,
+ Constant {
+ span: expr_span,
+ user_ty: None,
+ literal: ty::Const::from_bool(this.tcx, true).into(),
+ },
+ );
+
+ this.cfg.push_assign_constant(
+ false_block,
+ source_info,
+ destination,
+ Constant {
+ span: expr_span,
+ user_ty: None,
+ literal: ty::Const::from_bool(this.tcx, false).into(),
+ },
+ );
+
+ this.cfg.goto(true_block, source_info, join_block);
+ this.cfg.goto(false_block, source_info, join_block);
+ join_block.unit()
+ }
ExprKind::NeverToAny { source } => {
let source = &this.thir[source];
let is_call =
);
this.diverge_from(loop_block);
- // The “return” value of the loop body must always be an unit. We therefore
+ // The “return” value of the loop body must always be a unit. We therefore
// introduce a unit temporary as the destination for the loop body.
let tmp = this.get_unit_temp();
// Execute the body, branching back to the test.
inferred_ty,
})
});
- let adt = box AggregateKind::Adt(
+ let adt = Box::new(AggregateKind::Adt(
adt_def,
variant_index,
substs,
user_ty,
active_field_index,
- );
+ ));
this.cfg.push_assign(
block,
source_info,
}
thir::InlineAsmOperand::Const { value, span } => {
mir::InlineAsmOperand::Const {
- value: box Constant { span, user_ty: None, literal: value.into() },
+ value: Box::new(Constant {
+ span,
+ user_ty: None,
+ literal: value.into(),
+ }),
}
}
thir::InlineAsmOperand::SymFn { expr } => mir::InlineAsmOperand::SymFn {
- value: box this.as_constant(&this.thir[expr]),
+ value: Box::new(this.as_constant(&this.thir[expr])),
},
thir::InlineAsmOperand::SymStatic { def_id } => {
mir::InlineAsmOperand::SymStatic { def_id }