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 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, block);
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 this.cfg.push_drop(block, span, &temp);