]>
Commit | Line | Data |
---|---|---|
e9174d1e SL |
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 | ||
92a42be0 | 11 | use build::{BlockAnd, BlockAndExtension, Builder}; |
e9174d1e | 12 | use hair::*; |
92a42be0 | 13 | use rustc::mir::repr::*; |
e9174d1e | 14 | |
b039eaaf SL |
15 | impl<'a,'tcx> Builder<'a,'tcx> { |
16 | pub fn stmts(&mut self, mut block: BasicBlock, stmts: Vec<StmtRef<'tcx>>) -> BlockAnd<()> { | |
92a42be0 SL |
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. | |
e9174d1e | 32 | let this = self; |
92a42be0 SL |
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 { | |
7453a54e | 45 | unpack!(block = this.pop_scope(extent, block)); |
92a42be0 SL |
46 | } |
47 | continue | |
48 | } | |
49 | }; | |
50 | ||
7453a54e | 51 | let Stmt { span: _, kind } = this.hir.mirror(stmt); |
92a42be0 SL |
52 | match kind { |
53 | StmtKind::Let { remainder_scope, init_scope, pattern, initializer, stmts } => { | |
7453a54e | 54 | this.push_scope(remainder_scope); |
92a42be0 SL |
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 | } | |
e9174d1e | 67 | })); |
92a42be0 | 68 | } |
e9174d1e | 69 | |
92a42be0 SL |
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)); | |
7453a54e | 75 | unpack!(block = this.build_drop(block, temp)); |
e9174d1e SL |
76 | block.unit() |
77 | })); | |
92a42be0 | 78 | } |
e9174d1e SL |
79 | } |
80 | } | |
92a42be0 | 81 | block.unit() |
e9174d1e SL |
82 | } |
83 | } |