]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/hair/cx/block.rs
Rollup merge of #50610 - estebank:fmt-str, r=Kimundi
[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::{self, BlockRemainder};
15 use rustc::hir;
16
17 use rustc_data_structures::indexed_vec::Idx;
18
19 impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
20     type Output = Block<'tcx>;
21
22     fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Block<'tcx> {
23         // We have to eagerly lower the "spine" of the statements
24         // in order to get the lexical scoping correctly.
25         let stmts = mirror_stmts(cx, self.hir_id.local_id, &*self.stmts);
26         let opt_destruction_scope =
27             cx.region_scope_tree.opt_destruction_scope(self.hir_id.local_id);
28         Block {
29             targeted_by_break: self.targeted_by_break,
30             region_scope: region::Scope::Node(self.hir_id.local_id),
31             opt_destruction_scope,
32             span: self.span,
33             stmts,
34             expr: self.expr.to_ref(),
35             safety_mode: match self.rules {
36                 hir::BlockCheckMode::DefaultBlock =>
37                     BlockSafety::Safe,
38                 hir::BlockCheckMode::UnsafeBlock(..) =>
39                     BlockSafety::ExplicitUnsafe(self.id),
40                 hir::BlockCheckMode::PushUnsafeBlock(..) =>
41                     BlockSafety::PushUnsafe,
42                 hir::BlockCheckMode::PopUnsafeBlock(..) =>
43                     BlockSafety::PopUnsafe
44             },
45         }
46     }
47 }
48
49 fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
50                                 block_id: hir::ItemLocalId,
51                                 stmts: &'tcx [hir::Stmt])
52                                 -> Vec<StmtRef<'tcx>> {
53     let mut result = vec![];
54     for (index, stmt) in stmts.iter().enumerate() {
55         let hir_id = cx.tcx.hir.node_to_hir_id(stmt.node.id());
56         let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
57         match stmt.node {
58             hir::StmtExpr(ref expr, _) |
59             hir::StmtSemi(ref expr, _) => {
60                 result.push(StmtRef::Mirror(Box::new(Stmt {
61                     kind: StmtKind::Expr {
62                         scope: region::Scope::Node(hir_id.local_id),
63                         expr: expr.to_ref(),
64                     },
65                     opt_destruction_scope: opt_dxn_ext,
66                 })))
67             }
68             hir::StmtDecl(ref decl, _) => {
69                 match decl.node {
70                     hir::DeclItem(..) => {
71                         // ignore for purposes of the MIR
72                     }
73                     hir::DeclLocal(ref local) => {
74                         let remainder_scope = region::Scope::Remainder(BlockRemainder {
75                             block: block_id,
76                             first_statement_index: region::FirstStatementIndex::new(index),
77                         });
78
79                         let ty = local.ty.clone().map(|ty| ty.hir_id);
80                         let pattern = cx.pattern_from_hir(&local.pat);
81                         result.push(StmtRef::Mirror(Box::new(Stmt {
82                             kind: StmtKind::Let {
83                                 remainder_scope: remainder_scope,
84                                 init_scope: region::Scope::Node(hir_id.local_id),
85                                 pattern,
86                                 ty,
87                                 initializer: local.init.to_ref(),
88                                 lint_level: cx.lint_level_of(local.id),
89                             },
90                             opt_destruction_scope: opt_dxn_ext,
91                         })));
92                     }
93                 }
94             }
95         }
96     }
97     return result;
98 }
99
100 pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
101                                    block: &'tcx hir::Block)
102                                    -> ExprRef<'tcx> {
103     let block_ty = cx.tables().node_id_to_type(block.hir_id);
104     let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id);
105     let expr = Expr {
106         ty: block_ty,
107         temp_lifetime,
108         span: block.span,
109         kind: ExprKind::Block { body: block },
110     };
111     expr.to_ref()
112 }