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