]> git.proxmox.com Git - rustc.git/blame - src/librustc_mir/build/expr/as_operand.rs
New upstream version 1.33.0+dfsg1
[rustc.git] / src / librustc_mir / build / expr / as_operand.rs
CommitLineData
e9174d1e
SL
1//! See docs in build/expr/mod.rs
2
e9174d1e 3use build::expr::category::Category;
b7449926 4use build::{BlockAnd, BlockAndExtension, Builder};
e9174d1e 5use hair::*;
ea8adc8c 6use rustc::middle::region;
c30ab7b3 7use rustc::mir::*;
e9174d1e 8
a7813a04 9impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
8bb4bdeb
XL
10 /// Returns an operand suitable for use until the end of the current
11 /// scope expression.
12 ///
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.
b7449926
XL
16 pub fn as_local_operand<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Operand<'tcx>>
17 where
18 M: Mirror<'tcx, Output = Expr<'tcx>>,
8bb4bdeb 19 {
7cac9316
XL
20 let local_scope = self.local_scope();
21 self.as_operand(block, local_scope, expr)
8bb4bdeb
XL
22 }
23
e9174d1e 24 /// Compile `expr` into a value that can be used as an operand.
ff7c6d11 25 /// If `expr` is a place like `x`, this will introduce a
e9174d1e
SL
26 /// temporary `tmp = x`, so that we capture the value of `x` at
27 /// this time.
8bb4bdeb
XL
28 ///
29 /// The operand is known to be live until the end of `scope`.
b7449926
XL
30 pub fn as_operand<M>(
31 &mut self,
32 block: BasicBlock,
33 scope: Option<region::Scope>,
34 expr: M,
35 ) -> BlockAnd<Operand<'tcx>>
36 where
37 M: Mirror<'tcx, Output = Expr<'tcx>>,
e9174d1e
SL
38 {
39 let expr = self.hir.mirror(expr);
8bb4bdeb 40 self.expr_as_operand(block, scope, expr)
e9174d1e
SL
41 }
42
b7449926
XL
43 fn expr_as_operand(
44 &mut self,
45 mut block: BasicBlock,
46 scope: Option<region::Scope>,
47 expr: Expr<'tcx>,
48 ) -> BlockAnd<Operand<'tcx>> {
b039eaaf 49 debug!("expr_as_operand(block={:?}, expr={:?})", block, expr);
e9174d1e
SL
50 let this = self;
51
b7449926
XL
52 if let ExprKind::Scope {
53 region_scope,
54 lint_level,
55 value,
56 } = expr.kind
57 {
041b39d2 58 let source_info = this.source_info(expr.span);
ea8adc8c
XL
59 let region_scope = (region_scope, source_info);
60 return this.in_scope(region_scope, lint_level, block, |this| {
8bb4bdeb
XL
61 this.as_operand(block, scope, value)
62 });
e9174d1e
SL
63 }
64
65 let category = Category::of(&expr.kind).unwrap();
b7449926
XL
66 debug!(
67 "expr_as_operand: category={:?} for={:?}",
68 category, expr.kind
69 );
e9174d1e
SL
70 match category {
71 Category::Constant => {
72 let constant = this.as_constant(expr);
cc61c64b 73 block.and(Operand::Constant(box constant))
e9174d1e 74 }
b7449926
XL
75 Category::Place | Category::Rvalue(..) => {
76 let operand = unpack!(block = this.as_temp(block, scope, expr, Mutability::Mut));
ff7c6d11 77 block.and(Operand::Move(Place::Local(operand)))
e9174d1e
SL
78 }
79 }
80 }
81}