1 use crate::hair::{self, *};
2 use crate::hair::cx::Cx;
3 use crate::hair::cx::to_ref::ToRef;
4 use rustc::middle::region;
8 use rustc_data_structures::indexed_vec::Idx;
10 impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
11 type Output = Block<'tcx>;
13 fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Block<'tcx> {
14 // We have to eagerly lower the "spine" of the statements
15 // in order to get the lexical scoping correctly.
16 let stmts = mirror_stmts(cx, self.hir_id.local_id, &*self.stmts);
17 let opt_destruction_scope =
18 cx.region_scope_tree.opt_destruction_scope(self.hir_id.local_id);
20 targeted_by_break: self.targeted_by_break,
21 region_scope: region::Scope {
22 id: self.hir_id.local_id,
23 data: region::ScopeData::Node
25 opt_destruction_scope,
28 expr: self.expr.to_ref(),
29 safety_mode: match self.rules {
30 hir::BlockCheckMode::DefaultBlock =>
32 hir::BlockCheckMode::UnsafeBlock(..) =>
33 BlockSafety::ExplicitUnsafe(self.hir_id),
34 hir::BlockCheckMode::PushUnsafeBlock(..) =>
35 BlockSafety::PushUnsafe,
36 hir::BlockCheckMode::PopUnsafeBlock(..) =>
37 BlockSafety::PopUnsafe
43 fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
44 block_id: hir::ItemLocalId,
45 stmts: &'tcx [hir::Stmt])
46 -> Vec<StmtRef<'tcx>> {
47 let mut result = vec![];
48 for (index, stmt) in stmts.iter().enumerate() {
49 let hir_id = stmt.hir_id;
50 let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
51 let stmt_span = StatementSpan(cx.tcx.hir().span_by_hir_id(hir_id));
53 hir::StmtKind::Expr(ref expr) |
54 hir::StmtKind::Semi(ref expr) => {
55 result.push(StmtRef::Mirror(Box::new(Stmt {
56 kind: StmtKind::Expr {
57 scope: region::Scope {
59 data: region::ScopeData::Node
63 opt_destruction_scope: opt_dxn_ext,
67 hir::StmtKind::Item(..) => {
68 // ignore for purposes of the MIR
70 hir::StmtKind::Local(ref local) => {
71 let remainder_scope = region::Scope {
73 data: region::ScopeData::Remainder(
74 region::FirstStatementIndex::new(index)),
77 let mut pattern = cx.pattern_from_hir(&local.pat);
79 if let Some(ty) = &local.ty {
80 if let Some(&user_ty) = cx.tables.user_provided_types().get(ty.hir_id) {
81 debug!("mirror_stmts: user_ty={:?}", user_ty);
85 kind: Box::new(PatternKind::AscribeUserType {
86 ascription: hair::pattern::Ascription {
87 user_ty: PatternTypeProjection::from_user_type(user_ty),
88 user_ty_span: ty.span,
89 variance: ty::Variance::Covariant,
97 result.push(StmtRef::Mirror(Box::new(Stmt {
99 remainder_scope: remainder_scope,
100 init_scope: region::Scope {
102 data: region::ScopeData::Node
105 initializer: local.init.to_ref(),
106 lint_level: cx.lint_level_of(local.hir_id),
108 opt_destruction_scope: opt_dxn_ext,
117 pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
118 block: &'tcx hir::Block)
120 let block_ty = cx.tables().node_type(block.hir_id);
121 let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id);
126 kind: ExprKind::Block { body: block },