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(constant
))
72 Category
::Rvalue(..) => {
74 unpack
!(block
= this
.as_temp(block
, scope
, expr
));
75 block
.and(Operand
::Consume(operand
))