1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! See docs in build/expr/mod.rs
13 use build::{BlockAnd, BlockAndExtension, Builder};
14 use build::expr::category::Category;
16 use rustc::middle::region::CodeExtent;
19 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
20 /// Returns an operand suitable for use until the end of the current
23 /// The operand returned from this function will *not be valid* after
24 /// an ExprKind::Scope is passed, so please do *not* return it from
25 /// functions to avoid bad miscompiles.
26 pub fn as_local_operand<M>(&mut self, block: BasicBlock, expr: M)
27 -> BlockAnd<Operand<'tcx>>
28 where M: Mirror<'tcx, Output = Expr<'tcx>>
30 let topmost_scope = self.topmost_scope(); // FIXME(#6393)
31 self.as_operand(block, Some(topmost_scope), expr)
34 /// Compile `expr` into a value that can be used as an operand.
35 /// If `expr` is an lvalue like `x`, this will introduce a
36 /// temporary `tmp = x`, so that we capture the value of `x` at
39 /// The operand is known to be live until the end of `scope`.
40 pub fn as_operand<M>(&mut self,
42 scope: Option<CodeExtent>,
43 expr: M) -> BlockAnd<Operand<'tcx>>
44 where M: Mirror<'tcx, Output = Expr<'tcx>>
46 let expr = self.hir.mirror(expr);
47 self.expr_as_operand(block, scope, expr)
50 fn expr_as_operand(&mut self,
51 mut block: BasicBlock,
52 scope: Option<CodeExtent>,
54 -> BlockAnd<Operand<'tcx>> {
55 debug!("expr_as_operand(block={:?}, expr={:?})", block, expr);
58 if let ExprKind::Scope { extent, value } = expr.kind {
59 return this.in_scope(extent, block, |this| {
60 this.as_operand(block, scope, value)
64 let category = Category::of(&expr.kind).unwrap();
65 debug!("expr_as_operand: category={:?} for={:?}", category, expr.kind);
67 Category::Constant => {
68 let constant = this.as_constant(expr);
69 block.and(Operand::Constant(box constant))
72 Category::Rvalue(..) => {
74 unpack!(block = this.as_temp(block, scope, expr));
75 block.and(Operand::Consume(operand))