]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir_build/hair/cx/block.rs
Update const_forget.rs
[rust.git] / src / librustc_mir_build / hair / cx / block.rs
1 use crate::hair::cx::to_ref::ToRef;
2 use crate::hair::cx::Cx;
3 use crate::hair::{self, *};
4
5 use rustc::middle::region;
6 use rustc::ty;
7 use rustc_hir as hir;
8
9 use rustc_index::vec::Idx;
10
11 impl<'tcx> Mirror<'tcx> for &'tcx hir::Block<'tcx> {
12     type Output = Block<'tcx>;
13
14     fn make_mirror(self, cx: &mut Cx<'_, 'tcx>) -> Block<'tcx> {
15         // We have to eagerly lower the "spine" of the statements
16         // in order to get the lexical scoping correctly.
17         let stmts = mirror_stmts(cx, self.hir_id.local_id, &*self.stmts);
18         let opt_destruction_scope =
19             cx.region_scope_tree.opt_destruction_scope(self.hir_id.local_id);
20         Block {
21             targeted_by_break: self.targeted_by_break,
22             region_scope: region::Scope { id: self.hir_id.local_id, data: region::ScopeData::Node },
23             opt_destruction_scope,
24             span: self.span,
25             stmts,
26             expr: self.expr.to_ref(),
27             safety_mode: match self.rules {
28                 hir::BlockCheckMode::DefaultBlock => BlockSafety::Safe,
29                 hir::BlockCheckMode::UnsafeBlock(..) => BlockSafety::ExplicitUnsafe(self.hir_id),
30                 hir::BlockCheckMode::PushUnsafeBlock(..) => BlockSafety::PushUnsafe,
31                 hir::BlockCheckMode::PopUnsafeBlock(..) => BlockSafety::PopUnsafe,
32             },
33         }
34     }
35 }
36
37 fn mirror_stmts<'a, 'tcx>(
38     cx: &mut Cx<'a, 'tcx>,
39     block_id: hir::ItemLocalId,
40     stmts: &'tcx [hir::Stmt<'tcx>],
41 ) -> Vec<StmtRef<'tcx>> {
42     let mut result = vec![];
43     for (index, stmt) in stmts.iter().enumerate() {
44         let hir_id = stmt.hir_id;
45         let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
46         match stmt.kind {
47             hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => {
48                 result.push(StmtRef::Mirror(Box::new(Stmt {
49                     kind: StmtKind::Expr {
50                         scope: region::Scope { id: hir_id.local_id, data: region::ScopeData::Node },
51                         expr: expr.to_ref(),
52                     },
53                     opt_destruction_scope: opt_dxn_ext,
54                 })))
55             }
56             hir::StmtKind::Item(..) => {
57                 // ignore for purposes of the MIR
58             }
59             hir::StmtKind::Local(ref local) => {
60                 let remainder_scope = region::Scope {
61                     id: block_id,
62                     data: region::ScopeData::Remainder(region::FirstStatementIndex::new(index)),
63                 };
64
65                 let mut pattern = cx.pattern_from_hir(&local.pat);
66
67                 if let Some(ty) = &local.ty {
68                     if let Some(&user_ty) = cx.tables.user_provided_types().get(ty.hir_id) {
69                         debug!("mirror_stmts: user_ty={:?}", user_ty);
70                         pattern = Pat {
71                             ty: pattern.ty,
72                             span: pattern.span,
73                             kind: Box::new(PatKind::AscribeUserType {
74                                 ascription: hair::pattern::Ascription {
75                                     user_ty: PatTyProj::from_user_type(user_ty),
76                                     user_ty_span: ty.span,
77                                     variance: ty::Variance::Covariant,
78                                 },
79                                 subpattern: pattern,
80                             }),
81                         };
82                     }
83                 }
84
85                 result.push(StmtRef::Mirror(Box::new(Stmt {
86                     kind: StmtKind::Let {
87                         remainder_scope: remainder_scope,
88                         init_scope: region::Scope {
89                             id: hir_id.local_id,
90                             data: region::ScopeData::Node,
91                         },
92                         pattern,
93                         initializer: local.init.to_ref(),
94                         lint_level: LintLevel::Explicit(local.hir_id),
95                     },
96                     opt_destruction_scope: opt_dxn_ext,
97                 })));
98             }
99         }
100     }
101     return result;
102 }
103
104 crate fn to_expr_ref<'a, 'tcx>(
105     cx: &mut Cx<'a, 'tcx>,
106     block: &'tcx hir::Block<'tcx>,
107 ) -> ExprRef<'tcx> {
108     let block_ty = cx.tables().node_type(block.hir_id);
109     let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id);
110     let expr = Expr {
111         ty: block_ty,
112         temp_lifetime,
113         span: block.span,
114         kind: ExprKind::Block { body: block },
115     };
116     expr.to_ref()
117 }