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.
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.
13 use hair::cx::to_ref::ToRef;
14 use rustc::middle::region;
17 use rustc_data_structures::indexed_vec::Idx;
19 impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
20 type Output = Block<'tcx>;
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);
29 targeted_by_break: self.targeted_by_break,
30 region_scope: region::Scope {
31 id: self.hir_id.local_id,
32 data: region::ScopeData::Node
34 opt_destruction_scope,
37 expr: self.expr.to_ref(),
38 safety_mode: match self.rules {
39 hir::BlockCheckMode::DefaultBlock =>
41 hir::BlockCheckMode::UnsafeBlock(..) =>
42 BlockSafety::ExplicitUnsafe(self.id),
43 hir::BlockCheckMode::PushUnsafeBlock(..) =>
44 BlockSafety::PushUnsafe,
45 hir::BlockCheckMode::PopUnsafeBlock(..) =>
46 BlockSafety::PopUnsafe
52 fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
53 block_id: hir::ItemLocalId,
54 stmts: &'tcx [hir::Stmt])
55 -> Vec<StmtRef<'tcx>> {
56 let mut result = vec![];
57 for (index, stmt) in stmts.iter().enumerate() {
58 let hir_id = cx.tcx.hir.node_to_hir_id(stmt.node.id());
59 let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
61 hir::StmtKind::Expr(ref expr, _) |
62 hir::StmtKind::Semi(ref expr, _) => {
63 result.push(StmtRef::Mirror(Box::new(Stmt {
64 kind: StmtKind::Expr {
65 scope: region::Scope {
67 data: region::ScopeData::Node
71 opt_destruction_scope: opt_dxn_ext,
74 hir::StmtKind::Decl(ref decl, _) => {
76 hir::DeclKind::Item(..) => {
77 // ignore for purposes of the MIR
79 hir::DeclKind::Local(ref local) => {
80 let remainder_scope = region::Scope {
82 data: region::ScopeData::Remainder(
83 region::FirstStatementIndex::new(index)),
86 let mut pattern = cx.pattern_from_hir(&local.pat);
88 if let Some(ty) = &local.ty {
89 if let Some(&user_ty) = cx.tables.user_provided_tys().get(ty.hir_id) {
93 kind: Box::new(PatternKind::AscribeUserType {
94 user_ty: PatternTypeAnnotation::from_c_ty(user_ty),
95 user_ty_span: ty.span,
102 result.push(StmtRef::Mirror(Box::new(Stmt {
103 kind: StmtKind::Let {
104 remainder_scope: remainder_scope,
105 init_scope: region::Scope {
107 data: region::ScopeData::Node
110 initializer: local.init.to_ref(),
111 lint_level: cx.lint_level_of(local.id),
113 opt_destruction_scope: opt_dxn_ext,
123 pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
124 block: &'tcx hir::Block)
126 let block_ty = cx.tables().node_id_to_type(block.hir_id);
127 let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id);
132 kind: ExprKind::Block { body: block },