]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_ast_lowering/src/block.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / compiler / rustc_ast_lowering / src / block.rs
CommitLineData
94222f64 1use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext};
064997fb 2use rustc_ast::{Block, BlockCheckMode, Local, LocalKind, Stmt, StmtKind};
94222f64 3use rustc_hir as hir;
94222f64
XL
4
5use smallvec::SmallVec;
6
7impl<'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}