1 //! See docs in build/expr/mod.rs
3 use crate::build::expr::category::Category;
4 use crate::build::{BlockAnd, BlockAndExtension, Builder};
6 use rustc::middle::region;
9 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
10 /// Returns an operand suitable for use until the end of the current
13 /// The operand returned from this function will *not be valid* after
14 /// an ExprKind::Scope is passed, so please do *not* return it from
15 /// functions to avoid bad miscompiles.
16 pub fn as_local_operand<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Operand<'tcx>>
18 M: Mirror<'tcx, Output = Expr<'tcx>>,
20 let local_scope = self.local_scope();
21 self.as_operand(block, local_scope, expr)
24 /// Compile `expr` into a value that can be used as an operand.
25 /// If `expr` is a place like `x`, this will introduce a
26 /// temporary `tmp = x`, so that we capture the value of `x` at
29 /// The operand is known to be live until the end of `scope`.
33 scope: Option<region::Scope>,
35 ) -> BlockAnd<Operand<'tcx>>
37 M: Mirror<'tcx, Output = Expr<'tcx>>,
39 let expr = self.hir.mirror(expr);
40 self.expr_as_operand(block, scope, expr)
45 mut block: BasicBlock,
46 scope: Option<region::Scope>,
48 ) -> BlockAnd<Operand<'tcx>> {
49 debug!("expr_as_operand(block={:?}, expr={:?})", block, expr);
52 if let ExprKind::Scope {
58 let source_info = this.source_info(expr.span);
59 let region_scope = (region_scope, source_info);
60 return this.in_scope(region_scope, lint_level, block, |this| {
61 this.as_operand(block, scope, value)
65 let category = Category::of(&expr.kind).unwrap();
67 "expr_as_operand: category={:?} for={:?}",
71 Category::Constant => {
72 let constant = this.as_constant(expr);
73 block.and(Operand::Constant(box constant))
75 Category::Place | Category::Rvalue(..) => {
76 let operand = unpack!(block = this.as_temp(block, scope, expr, Mutability::Mut));
77 block.and(Operand::Move(Place::Base(PlaceBase::Local(operand))))