compiler/rustc_ast_lowering/src/block.rs RUST 126 lines View on github.com → Search inside
1use rustc_ast::{Block, BlockCheckMode, Local, LocalKind, Stmt, StmtKind};2use rustc_hir as hir;3use rustc_hir::Target;4use rustc_span::sym;5use smallvec::SmallVec;67use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext};89impl<'hir> LoweringContext<'_, 'hir> {10    pub(super) fn lower_block(11        &mut self,12        b: &Block,13        targeted_by_break: bool,14    ) -> &'hir hir::Block<'hir> {15        let hir_id = self.lower_node_id(b.id);16        self.arena.alloc(self.lower_block_noalloc(hir_id, b, targeted_by_break))17    }1819    pub(super) fn lower_block_noalloc(20        &mut self,21        hir_id: hir::HirId,22        b: &Block,23        targeted_by_break: bool,24    ) -> hir::Block<'hir> {25        let (stmts, expr) = self.lower_stmts(&b.stmts);26        let rules = self.lower_block_check_mode(&b.rules);27        hir::Block { hir_id, stmts, expr, rules, span: self.lower_span(b.span), targeted_by_break }28    }2930    pub(super) fn lower_stmts(31        &mut self,32        mut ast_stmts: &[Stmt],33    ) -> (&'hir [hir::Stmt<'hir>], Option<&'hir hir::Expr<'hir>>) {34        let mut stmts = SmallVec::<[hir::Stmt<'hir>; 8]>::new();35        let mut expr = None;36        while let [s, tail @ ..] = ast_stmts {37            match &s.kind {38                StmtKind::Let(local) => {39                    let hir_id = self.lower_node_id(s.id);40                    let local = self.lower_local(local);41                    self.alias_attrs(hir_id, local.hir_id);42                    let kind = hir::StmtKind::Let(local);43                    let span = self.lower_span(s.span);44                    stmts.push(hir::Stmt { hir_id, kind, span });45                }46                StmtKind::Item(it) => {47                    stmts.extend(self.lower_item_ref(it).into_iter().enumerate().map(48                        |(i, item_id)| {49                            let hir_id = match i {50                                0 => self.lower_node_id(s.id),51                                _ => self.next_id(),52                            };53                            let kind = hir::StmtKind::Item(item_id);54                            let span = self.lower_span(s.span);55                            hir::Stmt { hir_id, kind, span }56                        },57                    ));58                }59                StmtKind::Expr(e) => {60                    let e = self.lower_expr(e);61                    if tail.is_empty() {62                        expr = Some(e);63                    } else {64                        let hir_id = self.lower_node_id(s.id);65                        self.alias_attrs(hir_id, e.hir_id);66                        let kind = hir::StmtKind::Expr(e);67                        let span = self.lower_span(s.span);68                        stmts.push(hir::Stmt { hir_id, kind, span });69                    }70                }71                StmtKind::Semi(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                    let kind = hir::StmtKind::Semi(e);76                    let span = self.lower_span(s.span);77                    stmts.push(hir::Stmt { hir_id, kind, span });78                }79                StmtKind::Empty => {}80                StmtKind::MacCall(..) => panic!("shouldn't exist here"),81            }82            ast_stmts = tail;83        }84        (self.arena.alloc_from_iter(stmts), expr)85    }8687    /// Return an `ImplTraitContext` that allows impl trait in bindings if88    /// the feature gate is enabled, or issues a feature error if it is not.89    fn impl_trait_in_bindings_ctxt(&self, position: ImplTraitPosition) -> ImplTraitContext {90        if self.tcx.features().impl_trait_in_bindings() {91            ImplTraitContext::InBinding92        } else {93            ImplTraitContext::FeatureGated(position, sym::impl_trait_in_bindings)94        }95    }9697    fn lower_local(&mut self, l: &Local) -> &'hir hir::LetStmt<'hir> {98        // Let statements are allowed to have impl trait in bindings.99        let super_ = l.super_.map(|span| self.lower_span(span));100        let ty = l.ty.as_ref().map(|t| {101            self.lower_ty_alloc(t, self.impl_trait_in_bindings_ctxt(ImplTraitPosition::Variable))102        });103        let init = l.kind.init().map(|init| self.lower_expr(init));104        let hir_id = self.lower_node_id(l.id);105        let pat = self.lower_pat(&l.pat);106        let els = if let LocalKind::InitElse(_, els) = &l.kind {107            Some(self.lower_block(els, false))108        } else {109            None110        };111        let span = self.lower_span(l.span);112        let source = hir::LocalSource::Normal;113        self.lower_attrs(hir_id, &l.attrs, l.span, Target::Statement);114        self.arena.alloc(hir::LetStmt { hir_id, super_, ty, pat, init, els, span, source })115    }116117    fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {118        match *b {119            BlockCheckMode::Default => hir::BlockCheckMode::DefaultBlock,120            BlockCheckMode::Unsafe(u) => {121                hir::BlockCheckMode::UnsafeBlock(self.lower_unsafe_source(u))122            }123        }124    }125}

Code quality findings 4

Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
) -> (&'hir [hir::Stmt<'hir>], Option<&'hir hir::Expr<'hir>>) {
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning correctness unchecked-indexing
while let [s, tail @ ..] = ast_stmts {
Performance Info: Calling .push() repeatedly inside a loop without prior capacity reservation can lead to multiple reallocations. Consider using `Vec::with_capacity(n)` or `vec.reserve(n)` if the approximate number of elements is known.
info performance push-without-reserve
stmts.push(hir::Stmt { hir_id, kind, span });
Info: Ensure 'match' statements are exhaustive. If matching on enums, consider adding a wildcard arm `_ => {}` only if necessary and intentional, as it suppresses warnings about unhandled variants.
info correctness match-wildcard
let hir_id = match i {

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.