1 use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext};
2 use rustc_ast::{Block, BlockCheckMode, Local, Stmt, StmtKind};
5 use smallvec::{smallvec, SmallVec};
7 impl<'a, 'hir> LoweringContext<'a, 'hir> {
8 pub(super) fn lower_block(
11 targeted_by_break: bool,
12 ) -> &'hir hir::Block<'hir> {
13 self.arena.alloc(self.lower_block_noalloc(b, targeted_by_break))
16 pub(super) fn lower_block_noalloc(
19 targeted_by_break: bool,
20 ) -> hir::Block<'hir> {
21 let (stmts, expr) = match &*b.stmts {
22 [stmts @ .., Stmt { kind: StmtKind::Expr(e), .. }] => (stmts, Some(&*e)),
23 stmts => (stmts, None),
25 let stmts = self.arena.alloc_from_iter(stmts.iter().flat_map(|stmt| self.lower_stmt(stmt)));
26 let expr = expr.map(|e| self.lower_expr(e));
27 let rules = self.lower_block_check_mode(&b.rules);
28 let hir_id = self.lower_node_id(b.id);
30 hir::Block { hir_id, stmts, expr, rules, span: self.lower_span(b.span), targeted_by_break }
33 fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt<'hir>; 1]> {
34 let (hir_id, kind) = match s.kind {
35 StmtKind::Local(ref l) => {
36 let l = self.lower_local(l);
37 let hir_id = self.lower_node_id(s.id);
38 self.alias_attrs(hir_id, l.hir_id);
39 return smallvec![hir::Stmt {
41 kind: hir::StmtKind::Local(self.arena.alloc(l)),
42 span: self.lower_span(s.span),
45 StmtKind::Item(ref it) => {
46 // Can only use the ID once.
47 let mut id = Some(s.id);
54 .map(|id| self.lower_node_id(id))
55 .unwrap_or_else(|| self.next_id());
59 kind: hir::StmtKind::Item(item_id),
60 span: self.lower_span(s.span),
65 StmtKind::Expr(ref e) => {
66 let e = self.lower_expr(e);
67 let hir_id = self.lower_node_id(s.id);
68 self.alias_attrs(hir_id, e.hir_id);
69 (hir_id, hir::StmtKind::Expr(e))
71 StmtKind::Semi(ref e) => {
72 let e = self.lower_expr(e);
73 let hir_id = self.lower_node_id(s.id);
74 self.alias_attrs(hir_id, e.hir_id);
75 (hir_id, hir::StmtKind::Semi(e))
77 StmtKind::Empty => return smallvec![],
78 StmtKind::MacCall(..) => panic!("shouldn't exist here"),
80 smallvec![hir::Stmt { hir_id, kind, span: self.lower_span(s.span) }]
83 fn lower_local(&mut self, l: &Local) -> hir::Local<'hir> {
87 .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Binding)));
88 let init = l.kind.init().map(|init| self.lower_expr(init));
89 let hir_id = self.lower_node_id(l.id);
90 self.lower_attrs(hir_id, &l.attrs);
94 pat: self.lower_pat(&l.pat),
96 span: self.lower_span(l.span),
97 source: hir::LocalSource::Normal,
101 fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
103 BlockCheckMode::Default => hir::BlockCheckMode::DefaultBlock,
104 BlockCheckMode::Unsafe(u) => {
105 hir::BlockCheckMode::UnsafeBlock(self.lower_unsafe_source(u))