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