]> git.proxmox.com Git - rustc.git/blob - src/librustc_mir/hair/cx/block.rs
New upstream version 1.15.0+dfsg1
[rustc.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 extent: cx.tcx.region_maps.node_extent(self.id),
27 span: self.span,
28 stmts: stmts,
29 expr: self.expr.to_ref(),
30 }
31 }
32 }
33
34 fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
35 block_id: ast::NodeId,
36 stmts: &'tcx [hir::Stmt])
37 -> Vec<StmtRef<'tcx>> {
38 let mut result = vec![];
39 for (index, stmt) in stmts.iter().enumerate() {
40 match stmt.node {
41 hir::StmtExpr(ref expr, id) |
42 hir::StmtSemi(ref expr, id) => {
43 result.push(StmtRef::Mirror(Box::new(Stmt {
44 span: stmt.span,
45 kind: StmtKind::Expr {
46 scope: cx.tcx.region_maps.node_extent(id),
47 expr: expr.to_ref(),
48 },
49 })))
50 }
51 hir::StmtDecl(ref decl, id) => {
52 match decl.node {
53 hir::DeclItem(..) => {
54 // ignore for purposes of the MIR
55 }
56 hir::DeclLocal(ref local) => {
57 let remainder_extent = CodeExtentData::Remainder(BlockRemainder {
58 block: block_id,
59 first_statement_index: index as u32,
60 });
61 let remainder_extent =
62 cx.tcx.region_maps.lookup_code_extent(remainder_extent);
63
64 let pattern = Pattern::from_hir(cx.tcx, &local.pat);
65 result.push(StmtRef::Mirror(Box::new(Stmt {
66 span: stmt.span,
67 kind: StmtKind::Let {
68 remainder_scope: remainder_extent,
69 init_scope: cx.tcx.region_maps.node_extent(id),
70 pattern: pattern,
71 initializer: local.init.to_ref(),
72 },
73 })));
74 }
75 }
76 }
77 }
78 }
79 return result;
80 }
81
82 pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
83 block: &'tcx hir::Block)
84 -> ExprRef<'tcx> {
85 let block_ty = cx.tcx.tables().node_id_to_type(block.id);
86 let temp_lifetime = cx.tcx.region_maps.temporary_scope(block.id);
87 let expr = Expr {
88 ty: block_ty,
89 temp_lifetime: temp_lifetime,
90 span: block.span,
91 kind: ExprKind::Block { body: block },
92 };
93 expr.to_ref()
94 }