]>
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 | ||
11 | use hair::*; | |
92a42be0 SL |
12 | use hair::cx::Cx; |
13 | use hair::cx::to_ref::ToRef; | |
b039eaaf | 14 | use rustc::middle::region::{BlockRemainder, CodeExtentData}; |
54a0048b | 15 | use rustc::hir; |
b039eaaf | 16 | use syntax::ast; |
e9174d1e | 17 | |
b039eaaf SL |
18 | impl<'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 |
34 | fn 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 | 77 | pub 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 | } |