]> git.proxmox.com Git - rustc.git/blob - src/librustc_mir/build/stmt.rs
Imported Upstream version 1.8.0+dfsg1
[rustc.git] / src / librustc_mir / build / stmt.rs
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.
4 //
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.
10
11 use build::{BlockAnd, BlockAndExtension, Builder};
12 use hair::*;
13 use rustc::mir::repr::*;
14
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:
19 //
20 // let x = <init> in {
21 // let y = <init> in {
22 // expr1;
23 // expr2;
24 // }
25 // }
26 //
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.
32 let this = self;
33 let mut stmt_lists = vec![(None, stmts.into_iter())];
34 while !stmt_lists.is_empty() {
35 let stmt = {
36 let &mut (_, ref mut stmts) = stmt_lists.last_mut().unwrap();
37 stmts.next()
38 };
39
40 let stmt = match stmt {
41 Some(stmt) => stmt,
42 None => {
43 let (extent, _) = stmt_lists.pop().unwrap();
44 if let Some(extent) = extent {
45 unpack!(block = this.pop_scope(extent, block));
46 }
47 continue
48 }
49 };
50
51 let Stmt { span: _, kind } = this.hir.mirror(stmt);
52 match kind {
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| {
57 // FIXME #30046 ^~~~
58 match initializer {
59 Some(initializer) => {
60 this.expr_into_pattern(block, remainder_scope, pattern, initializer)
61 }
62 None => {
63 this.declare_bindings(remainder_scope, &pattern);
64 block.unit()
65 }
66 }
67 }));
68 }
69
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));
76 block.unit()
77 }));
78 }
79 }
80 }
81 block.unit()
82 }
83 }