]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/hair/cx/block.rs
1be07fba2b0cdf55a83a5cf3b5791cc26e1c8147
[rust.git] / src / librustc_mir / hair / cx / block.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 hair::*;
12 use hair::cx::Cx;
13 use hair::cx::to_ref::ToRef;
14 use rustc::middle::region::{BlockRemainder, CodeExtentData};
15 use rustc::hir;
16 use syntax::ast;
17
18 impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
19     type Output = Block<'tcx>;
20
21     fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Block<'tcx> {
22         // We have to eagerly translate the "spine" of the statements
23         // in order to get the lexical scoping correctly.
24         let stmts = mirror_stmts(cx, self.id, &*self.stmts);
25         Block {
26             targeted_by_break: self.targeted_by_break,
27             extent: cx.tcx.region_maps().node_extent(self.id),
28             span: self.span,
29             stmts: stmts,
30             expr: self.expr.to_ref(),
31         }
32     }
33 }
34
35 fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
36                                 block_id: ast::NodeId,
37                                 stmts: &'tcx [hir::Stmt])
38                                 -> Vec<StmtRef<'tcx>> {
39     let mut result = vec![];
40     for (index, stmt) in stmts.iter().enumerate() {
41         match stmt.node {
42             hir::StmtExpr(ref expr, id) |
43             hir::StmtSemi(ref expr, id) => {
44                 result.push(StmtRef::Mirror(Box::new(Stmt {
45                     span: stmt.span,
46                     kind: StmtKind::Expr {
47                         scope: cx.tcx.region_maps().node_extent(id),
48                         expr: expr.to_ref(),
49                     },
50                 })))
51             }
52             hir::StmtDecl(ref decl, id) => {
53                 match decl.node {
54                     hir::DeclItem(..) => {
55                         // ignore for purposes of the MIR
56                     }
57                     hir::DeclLocal(ref local) => {
58                         let remainder_extent = CodeExtentData::Remainder(BlockRemainder {
59                             block: block_id,
60                             first_statement_index: index as u32,
61                         });
62                         let remainder_extent =
63                             cx.tcx.region_maps().lookup_code_extent(remainder_extent);
64
65                         let pattern = Pattern::from_hir(cx.tcx, cx.tables(), &local.pat);
66                         result.push(StmtRef::Mirror(Box::new(Stmt {
67                             span: stmt.span,
68                             kind: StmtKind::Let {
69                                 remainder_scope: remainder_extent,
70                                 init_scope: cx.tcx.region_maps().node_extent(id),
71                                 pattern: pattern,
72                                 initializer: local.init.to_ref(),
73                             },
74                         })));
75                     }
76                 }
77             }
78         }
79     }
80     return result;
81 }
82
83 pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
84                                    block: &'tcx hir::Block)
85                                    -> ExprRef<'tcx> {
86     let block_ty = cx.tables().node_id_to_type(block.id);
87     let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(block.id);
88     let expr = Expr {
89         ty: block_ty,
90         temp_lifetime: temp_lifetime,
91         temp_lifetime_was_shrunk: was_shrunk,
92         span: block.span,
93         kind: ExprKind::Block { body: block },
94     };
95     expr.to_ref()
96 }