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 use build
::{BlockAnd, BlockAndExtension, Builder}
;
13 use rustc
::mir
::repr
::*;
15 impl<'a
,'tcx
> Builder
<'a
,'tcx
> {
16 pub fn stmts(&mut self, mut block
: BasicBlock
, stmts
: Vec
<StmtRef
<'tcx
>>) -> BlockAnd
<()> {
17 // This convoluted structure is to avoid using recursion as we walk down a list
18 // of statements. Basically, the structure we get back is something like:
20 // let x = <init> in {
21 // let y = <init> in {
27 // To process this, we keep a stack of (Option<CodeExtent>,
28 // vec::IntoIter<Stmt>) pairs. At each point we pull off the
29 // top most pair and extract one statement from the
30 // iterator. Once it's complete, we pop the scope from the
31 // first half the pair.
33 let mut stmt_lists
= vec
![(None
, stmts
.into_iter())];
34 while !stmt_lists
.is_empty() {
36 let &mut (_
, ref mut stmts
) = stmt_lists
.last_mut().unwrap();
40 let stmt
= match stmt
{
43 let (extent
, _
) = stmt_lists
.pop().unwrap();
44 if let Some(extent
) = extent
{
45 unpack
!(block
= this
.pop_scope(extent
, block
));
51 let Stmt { span: _, kind }
= this
.hir
.mirror(stmt
);
53 StmtKind
::Let { remainder_scope, init_scope, pattern, initializer, stmts }
=> {
54 this
.push_scope(remainder_scope
);
55 stmt_lists
.push((Some(remainder_scope
), stmts
.into_iter()));
56 unpack
!(block
= this
.in_scope(init_scope
, block
, move |this
| {
59 Some(initializer
) => {
60 this
.expr_into_pattern(block
, remainder_scope
, pattern
, initializer
)
63 this
.declare_bindings(remainder_scope
, &pattern
);
70 StmtKind
::Expr { scope, expr }
=> {
71 unpack
!(block
= this
.in_scope(scope
, block
, |this
| {
72 let expr
= this
.hir
.mirror(expr
);
73 let temp
= this
.temp(expr
.ty
.clone());
74 unpack
!(block
= this
.into(&temp
, block
, expr
));
75 unpack
!(block
= this
.build_drop(block
, temp
));