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);
60 let stmt_span = StatementSpan(cx.tcx.hir.span(stmt.node.id()));
62 hir::StmtKind::Expr(ref expr, _) |
63 hir::StmtKind::Semi(ref expr, _) => {
64 result.push(StmtRef::Mirror(Box::new(Stmt {
65 kind: StmtKind::Expr {
66 scope: region::Scope {
68 data: region::ScopeData::Node
72 opt_destruction_scope: opt_dxn_ext,
76 hir::StmtKind::Decl(ref decl, _) => {
78 hir::DeclKind::Item(..) => {
79 // ignore for purposes of the MIR
81 hir::DeclKind::Local(ref local) => {
82 let remainder_scope = region::Scope {
84 data: region::ScopeData::Remainder(
85 region::FirstStatementIndex::new(index)),
88 let mut pattern = cx.pattern_from_hir(&local.pat);
90 if let Some(ty) = &local.ty {
91 if let Some(&user_ty) = cx.tables.user_provided_tys().get(ty.hir_id) {
95 kind: Box::new(PatternKind::AscribeUserType {
96 user_ty: PatternTypeProjection::from_canonical_ty(user_ty),
97 user_ty_span: ty.span,
104 result.push(StmtRef::Mirror(Box::new(Stmt {
105 kind: StmtKind::Let {
106 remainder_scope: remainder_scope,
107 init_scope: region::Scope {
109 data: region::ScopeData::Node
112 initializer: local.init.to_ref(),
113 lint_level: cx.lint_level_of(local.id),
115 opt_destruction_scope: opt_dxn_ext,
126 pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
127 block: &'tcx hir::Block)
129 let block_ty = cx.tables().node_id_to_type(block.hir_id);
130 let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id);
135 kind: ExprKind::Block { body: block },