]>
Commit | Line | Data |
---|---|---|
94222f64 | 1 | use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext}; |
064997fb | 2 | use rustc_ast::{Block, BlockCheckMode, Local, LocalKind, Stmt, StmtKind}; |
94222f64 | 3 | use rustc_hir as hir; |
94222f64 XL |
4 | |
5 | use smallvec::SmallVec; | |
6 | ||
7 | impl<'a, 'hir> LoweringContext<'a, 'hir> { | |
8 | pub(super) fn lower_block( | |
9 | &mut self, | |
10 | b: &Block, | |
11 | targeted_by_break: bool, | |
12 | ) -> &'hir hir::Block<'hir> { | |
13 | self.arena.alloc(self.lower_block_noalloc(b, targeted_by_break)) | |
14 | } | |
15 | ||
16 | pub(super) fn lower_block_noalloc( | |
17 | &mut self, | |
18 | b: &Block, | |
19 | targeted_by_break: bool, | |
20 | ) -> hir::Block<'hir> { | |
21 | let (stmts, expr) = self.lower_stmts(&b.stmts); | |
22 | let rules = self.lower_block_check_mode(&b.rules); | |
23 | let hir_id = self.lower_node_id(b.id); | |
24 | hir::Block { hir_id, stmts, expr, rules, span: self.lower_span(b.span), targeted_by_break } | |
25 | } | |
26 | ||
27 | fn lower_stmts( | |
28 | &mut self, | |
29 | mut ast_stmts: &[Stmt], | |
30 | ) -> (&'hir [hir::Stmt<'hir>], Option<&'hir hir::Expr<'hir>>) { | |
31 | let mut stmts = SmallVec::<[hir::Stmt<'hir>; 8]>::new(); | |
32 | let mut expr = None; | |
33 | while let [s, tail @ ..] = ast_stmts { | |
487cf647 FG |
34 | match &s.kind { |
35 | StmtKind::Local(local) => { | |
94222f64 | 36 | let hir_id = self.lower_node_id(s.id); |
064997fb FG |
37 | let local = self.lower_local(local); |
38 | self.alias_attrs(hir_id, local.hir_id); | |
39 | let kind = hir::StmtKind::Local(local); | |
40 | let span = self.lower_span(s.span); | |
41 | stmts.push(hir::Stmt { hir_id, kind, span }); | |
94222f64 | 42 | } |
487cf647 | 43 | StmtKind::Item(it) => { |
c295e0f8 | 44 | stmts.extend(self.lower_item_ref(it).into_iter().enumerate().map( |
94222f64 XL |
45 | |(i, item_id)| { |
46 | let hir_id = match i { | |
47 | 0 => self.lower_node_id(s.id), | |
48 | _ => self.next_id(), | |
49 | }; | |
50 | let kind = hir::StmtKind::Item(item_id); | |
51 | let span = self.lower_span(s.span); | |
52 | hir::Stmt { hir_id, kind, span } | |
53 | }, | |
54 | )); | |
55 | } | |
487cf647 | 56 | StmtKind::Expr(e) => { |
94222f64 XL |
57 | let e = self.lower_expr(e); |
58 | if tail.is_empty() { | |
59 | expr = Some(e); | |
60 | } else { | |
61 | let hir_id = self.lower_node_id(s.id); | |
62 | self.alias_attrs(hir_id, e.hir_id); | |
63 | let kind = hir::StmtKind::Expr(e); | |
64 | let span = self.lower_span(s.span); | |
65 | stmts.push(hir::Stmt { hir_id, kind, span }); | |
66 | } | |
67 | } | |
487cf647 | 68 | StmtKind::Semi(e) => { |
94222f64 XL |
69 | let e = self.lower_expr(e); |
70 | let hir_id = self.lower_node_id(s.id); | |
71 | self.alias_attrs(hir_id, e.hir_id); | |
72 | let kind = hir::StmtKind::Semi(e); | |
73 | let span = self.lower_span(s.span); | |
74 | stmts.push(hir::Stmt { hir_id, kind, span }); | |
75 | } | |
76 | StmtKind::Empty => {} | |
77 | StmtKind::MacCall(..) => panic!("shouldn't exist here"), | |
78 | } | |
79 | ast_stmts = &ast_stmts[1..]; | |
80 | } | |
81 | (self.arena.alloc_from_iter(stmts), expr) | |
82 | } | |
83 | ||
84 | fn lower_local(&mut self, l: &Local) -> &'hir hir::Local<'hir> { | |
85 | let ty = l | |
86 | .ty | |
87 | .as_ref() | |
f2b60f7d | 88 | .map(|t| self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Variable))); |
94222f64 XL |
89 | let init = l.kind.init().map(|init| self.lower_expr(init)); |
90 | let hir_id = self.lower_node_id(l.id); | |
91 | let pat = self.lower_pat(&l.pat); | |
064997fb | 92 | let els = if let LocalKind::InitElse(_, els) = &l.kind { |
064997fb FG |
93 | Some(self.lower_block(els, false)) |
94 | } else { | |
95 | None | |
96 | }; | |
94222f64 XL |
97 | let span = self.lower_span(l.span); |
98 | let source = hir::LocalSource::Normal; | |
99 | self.lower_attrs(hir_id, &l.attrs); | |
064997fb | 100 | self.arena.alloc(hir::Local { hir_id, ty, pat, init, els, span, source }) |
94222f64 XL |
101 | } |
102 | ||
103 | fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode { | |
104 | match *b { | |
105 | BlockCheckMode::Default => hir::BlockCheckMode::DefaultBlock, | |
106 | BlockCheckMode::Unsafe(u) => { | |
107 | hir::BlockCheckMode::UnsafeBlock(self.lower_unsafe_source(u)) | |
108 | } | |
109 | } | |
110 | } | |
94222f64 | 111 | } |