]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_mir_build/src/thir/cx/block.rs
Rollup merge of #82037 - calavera:strip_debuginfo_osx, r=petrochenkov
[rust.git] / compiler / rustc_mir_build / src / thir / cx / block.rs
1 use crate::thir::cx::Cx;
2
3 use rustc_hir as hir;
4 use rustc_middle::middle::region;
5 use rustc_middle::thir::*;
6 use rustc_middle::ty;
7
8 use rustc_index::vec::Idx;
9
10 impl<'tcx> Cx<'tcx> {
11     crate fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> Block {
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.map(|expr| self.mirror_expr(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     ) -> Box<[StmtId]> {
41         stmts
42             .iter()
43             .enumerate()
44             .filter_map(|(index, stmt)| {
45                 let hir_id = stmt.hir_id;
46                 let opt_dxn_ext = self.region_scope_tree.opt_destruction_scope(hir_id.local_id);
47                 match stmt.kind {
48                     hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => {
49                         let stmt = Stmt {
50                             kind: StmtKind::Expr {
51                                 scope: region::Scope {
52                                     id: hir_id.local_id,
53                                     data: region::ScopeData::Node,
54                                 },
55                                 expr: self.mirror_expr(expr),
56                             },
57                             opt_destruction_scope: opt_dxn_ext,
58                         };
59                         Some(self.thir.stmts.push(stmt))
60                     }
61                     hir::StmtKind::Item(..) => {
62                         // ignore for purposes of the MIR
63                         None
64                     }
65                     hir::StmtKind::Local(ref local) => {
66                         let remainder_scope = region::Scope {
67                             id: block_id,
68                             data: region::ScopeData::Remainder(region::FirstStatementIndex::new(
69                                 index,
70                             )),
71                         };
72
73                         let mut pattern = self.pattern_from_hir(local.pat);
74
75                         if let Some(ty) = &local.ty {
76                             if let Some(&user_ty) =
77                                 self.typeck_results.user_provided_types().get(ty.hir_id)
78                             {
79                                 debug!("mirror_stmts: user_ty={:?}", user_ty);
80                                 pattern = Pat {
81                                     ty: pattern.ty,
82                                     span: pattern.span,
83                                     kind: Box::new(PatKind::AscribeUserType {
84                                         ascription: Ascription {
85                                             user_ty: PatTyProj::from_user_type(user_ty),
86                                             user_ty_span: ty.span,
87                                             variance: ty::Variance::Covariant,
88                                         },
89                                         subpattern: pattern,
90                                     }),
91                                 };
92                             }
93                         }
94
95                         let stmt = Stmt {
96                             kind: StmtKind::Let {
97                                 remainder_scope,
98                                 init_scope: region::Scope {
99                                     id: hir_id.local_id,
100                                     data: region::ScopeData::Node,
101                                 },
102                                 pattern,
103                                 initializer: local.init.map(|init| self.mirror_expr(init)),
104                                 lint_level: LintLevel::Explicit(local.hir_id),
105                             },
106                             opt_destruction_scope: opt_dxn_ext,
107                         };
108                         Some(self.thir.stmts.push(stmt))
109                     }
110                 }
111             })
112             .collect()
113     }
114 }