]> git.proxmox.com Git - rustc.git/blob - src/librustc_mir/tcx/block.rs
Move away from hash to the same rust naming schema
[rustc.git] / src / librustc_mir / tcx / 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
13 use tcx::Cx;
14 use tcx::pattern::PatNode;
15 use tcx::rustc::middle::region::{BlockRemainder, CodeExtentData};
16 use tcx::rustc_front::hir;
17 use tcx::syntax::ast;
18 use tcx::syntax::ptr::P;
19 use tcx::to_ref::ToRef;
20
21 impl<'a,'tcx:'a> Mirror<Cx<'a,'tcx>> for &'tcx hir::Block {
22 type Output = Block<Cx<'a,'tcx>>;
23
24 fn make_mirror(self, cx: &mut Cx<'a,'tcx>) -> Block<Cx<'a,'tcx>> {
25 // We have to eagerly translate the "spine" of the statements
26 // in order to get the lexical scoping correctly.
27 let stmts = mirror_stmts(cx, self.id, self.stmts.iter().enumerate());
28 Block {
29 extent: cx.tcx.region_maps.node_extent(self.id),
30 span: self.span,
31 stmts: stmts,
32 expr: self.expr.to_ref()
33 }
34 }
35 }
36
37 impl<'a,'tcx:'a> Mirror<Cx<'a,'tcx>> for &'tcx hir::Stmt {
38 type Output = Stmt<Cx<'a,'tcx>>;
39
40 fn make_mirror(self, _cx: &mut Cx<'a,'tcx>) -> Stmt<Cx<'a,'tcx>> {
41 // In order to get the scoping correct, we eagerly mirror
42 // statements when we translate the enclosing block, so we
43 // should in fact never get to this point.
44 panic!("statements are eagerly mirrored");
45 }
46 }
47
48 fn mirror_stmts<'a,'tcx:'a,STMTS>(cx: &mut Cx<'a,'tcx>,
49 block_id: ast::NodeId,
50 mut stmts: STMTS)
51 -> Vec<StmtRef<Cx<'a,'tcx>>>
52 where STMTS: Iterator<Item=(usize, &'tcx P<hir::Stmt>)>
53 {
54 let mut result = vec![];
55 while let Some((index, stmt)) = stmts.next() {
56 match stmt.node {
57 hir::StmtExpr(ref expr, id) | hir::StmtSemi(ref expr, id) =>
58 result.push(
59 StmtRef::Mirror(
60 Box::new(Stmt { span: stmt.span,
61 kind: StmtKind::Expr {
62 scope: cx.tcx.region_maps.node_extent(id),
63 expr: expr.to_ref() } }))),
64
65 hir::StmtDecl(ref decl, id) => {
66 match decl.node {
67 hir::DeclItem(..) => { /* ignore for purposes of the MIR */ }
68 hir::DeclLocal(ref local) => {
69 let remainder_extent = CodeExtentData::Remainder(BlockRemainder {
70 block: block_id,
71 first_statement_index: index as u32
72 });
73 let remainder_extent =
74 cx.tcx.region_maps.lookup_code_extent(remainder_extent);
75
76 // pull in all following statements, since
77 // they are within the scope of this let:
78 let following_stmts = mirror_stmts(cx, block_id, stmts);
79
80 result.push(
81 StmtRef::Mirror(
82 Box::new(Stmt {
83 span: stmt.span,
84 kind: StmtKind::Let {
85 remainder_scope: remainder_extent,
86 init_scope: cx.tcx.region_maps.node_extent(id),
87 pattern: PatNode::irrefutable(&local.pat).to_ref(),
88 initializer: local.init.to_ref(),
89 stmts: following_stmts
90 }
91 })));
92
93 return result;
94 }
95 }
96 }
97 }
98 }
99 return result;
100 }
101
102 pub fn to_expr_ref<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
103 block: &'tcx hir::Block)
104 -> ExprRef<Cx<'a, 'tcx>> {
105 let block_ty = cx.tcx.node_id_to_type(block.id);
106 let temp_lifetime = cx.tcx.region_maps.temporary_scope(block.id);
107 let expr = Expr {
108 ty: block_ty,
109 temp_lifetime: temp_lifetime,
110 span: block.span,
111 kind: ExprKind::Block { body: block }
112 };
113 expr.to_ref()
114 }