compiler/rustc_ast_lowering/src/item.rs RUST 2,088 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 2,088.
1use rustc_abi::ExternAbi;2use rustc_ast::visit::AssocCtxt;3use rustc_ast::*;4use rustc_data_structures::fx::FxIndexMap;5use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};6use rustc_hir::attrs::{AttributeKind, EiiImplResolution};7use rustc_hir::def::{DefKind, PerNS, Res};8use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};9use rustc_hir::{10    self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, find_attr,11};12use rustc_index::{IndexSlice, IndexVec};13use rustc_middle::span_bug;14use rustc_middle::ty::{ResolverAstLowering, TyCtxt};15use rustc_span::def_id::DefId;16use rustc_span::edit_distance::find_best_match_for_name;17use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};18use smallvec::{SmallVec, smallvec};19use thin_vec::ThinVec;20use tracing::instrument;2122use super::errors::{InvalidAbi, InvalidAbiSuggestion, TupleStructWithDefault, UnionWithDefault};23use super::stability::{enabled_names, gate_unstable_abi};24use super::{25    AstOwner, FnDeclKind, GenericArgsMode, ImplTraitContext, ImplTraitPosition, LoweringContext,26    ParamMode, RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt,27};2829/// Wraps either IndexVec (during `hir_crate`), which acts like a primary30/// storage for most of the MaybeOwners, or FxIndexMap during delayed AST -> HIR31/// lowering of delegations (`lower_delayed_owner`),32/// in this case we can not modify already created IndexVec, so we use other map.33pub(super) enum Owners<'a, 'hir> {34    IndexVec(&'a mut IndexVec<LocalDefId, hir::MaybeOwner<'hir>>),35    Map(&'a mut FxIndexMap<LocalDefId, hir::MaybeOwner<'hir>>),36}3738impl<'hir> Owners<'_, 'hir> {39    fn get_or_insert_mut(&mut self, def_id: LocalDefId) -> &mut hir::MaybeOwner<'hir> {40        match self {41            Owners::IndexVec(index_vec) => {42                index_vec.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom)43            }44            Owners::Map(map) => map.entry(def_id).or_insert(hir::MaybeOwner::Phantom),45        }46    }47}4849pub(super) struct ItemLowerer<'a, 'hir> {50    pub(super) tcx: TyCtxt<'hir>,51    pub(super) resolver: &'a ResolverAstLowering<'hir>,52    pub(super) ast_index: &'a IndexSlice<LocalDefId, AstOwner<'a>>,53    pub(super) owners: Owners<'a, 'hir>,54}5556/// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span57/// to the where clause that is preferred, if it exists. Otherwise, it sets the span to the other where58/// clause if it exists.59fn add_ty_alias_where_clause(60    generics: &mut ast::Generics,61    after_where_clause: &ast::WhereClause,62    prefer_first: bool,63) {64    generics.where_clause.predicates.extend_from_slice(&after_where_clause.predicates);6566    let mut before = (generics.where_clause.has_where_token, generics.where_clause.span);67    let mut after = (after_where_clause.has_where_token, after_where_clause.span);68    if !prefer_first {69        (before, after) = (after, before);70    }71    (generics.where_clause.has_where_token, generics.where_clause.span) =72        if before.0 || !after.0 { before } else { after };73}7475impl<'hir> ItemLowerer<'_, 'hir> {76    fn with_lctx(77        &mut self,78        owner: NodeId,79        f: impl for<'a> FnOnce(&mut LoweringContext<'a, 'hir>) -> hir::OwnerNode<'hir>,80    ) {81        let mut lctx = LoweringContext::new(self.tcx, self.resolver);82        lctx.with_hir_id_owner(owner, |lctx| f(lctx));8384        for (def_id, info) in lctx.children {85            let owner = self.owners.get_or_insert_mut(def_id);86            assert!(87                matches!(owner, hir::MaybeOwner::Phantom),88                "duplicate copy of {def_id:?} in lctx.children"89            );90            *owner = info;91        }92    }9394    pub(super) fn lower_node(&mut self, def_id: LocalDefId) {95        let owner = self.owners.get_or_insert_mut(def_id);96        if let hir::MaybeOwner::Phantom = owner {97            let node = self.ast_index[def_id];98            match node {99                AstOwner::NonOwner => {}100                AstOwner::Crate(c) => {101                    assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID);102                    self.with_lctx(CRATE_NODE_ID, |lctx| {103                        let module = lctx.lower_mod(&c.items, &c.spans);104                        // FIXME(jdonszelman): is dummy span ever a problem here?105                        lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP, Target::Crate);106                        hir::OwnerNode::Crate(module)107                    })108                }109                AstOwner::Item(item) => {110                    self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))111                }112                AstOwner::AssocItem(item, ctxt) => {113                    self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))114                }115                AstOwner::ForeignItem(item) => self.with_lctx(item.id, |lctx| {116                    hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))117                }),118            }119        }120    }121}122123impl<'hir> LoweringContext<'_, 'hir> {124    pub(super) fn lower_mod(125        &mut self,126        items: &[Box<Item>],127        spans: &ModSpans,128    ) -> &'hir hir::Mod<'hir> {129        self.arena.alloc(hir::Mod {130            spans: hir::ModSpans {131                inner_span: self.lower_span(spans.inner_span),132                inject_use_span: self.lower_span(spans.inject_use_span),133            },134            item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))),135        })136    }137138    pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {139        let mut node_ids = smallvec![hir::ItemId { owner_id: self.owner_id(i.id) }];140        if let ItemKind::Use(use_tree) = &i.kind {141            self.lower_item_id_use_tree(use_tree, &mut node_ids);142        }143        node_ids144    }145146    fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) {147        match &tree.kind {148            UseTreeKind::Nested { items, .. } => {149                for &(ref nested, id) in items {150                    vec.push(hir::ItemId { owner_id: self.owner_id(id) });151                    self.lower_item_id_use_tree(nested, vec);152                }153            }154            UseTreeKind::Simple(..) | UseTreeKind::Glob(_) => {}155        }156    }157158    fn lower_eii_decl(159        &mut self,160        id: NodeId,161        name: Ident,162        EiiDecl { foreign_item, impl_unsafe }: &EiiDecl,163    ) -> Option<hir::attrs::EiiDecl> {164        self.lower_path_simple_eii(id, foreign_item).map(|did| hir::attrs::EiiDecl {165            foreign_item: did,166            impl_unsafe: *impl_unsafe,167            name,168        })169    }170171    fn lower_eii_impl(172        &mut self,173        EiiImpl {174            node_id,175            eii_macro_path,176            impl_safety,177            span,178            inner_span,179            is_default,180            known_eii_macro_resolution,181        }: &EiiImpl,182    ) -> hir::attrs::EiiImpl {183        let resolution = if let Some(target) = known_eii_macro_resolution184            && let Some(decl) = self.lower_eii_decl(185                *node_id,186                // the expect is ok here since we always generate this path in the eii macro.187                eii_macro_path.segments.last().expect("at least one segment").ident,188                target,189            ) {190            EiiImplResolution::Known(decl)191        } else if let Some(macro_did) = self.lower_path_simple_eii(*node_id, eii_macro_path) {192            EiiImplResolution::Macro(macro_did)193        } else {194            EiiImplResolution::Error(195                self.dcx().span_delayed_bug(*span, "eii never resolved without errors given"),196            )197        };198199        hir::attrs::EiiImpl {200            span: self.lower_span(*span),201            inner_span: self.lower_span(*inner_span),202            impl_marked_unsafe: self.lower_safety(*impl_safety, hir::Safety::Safe).is_unsafe(),203            is_default: *is_default,204            resolution,205        }206    }207208    fn generate_extra_attrs_for_item_kind(209        &mut self,210        id: NodeId,211        i: &ItemKind,212    ) -> Vec<hir::Attribute> {213        match i {214            ItemKind::Fn(Fn { eii_impls, .. }) | ItemKind::Static(StaticItem { eii_impls, .. })215                if eii_impls.is_empty() =>216            {217                Vec::new()218            }219            ItemKind::Fn(Fn { eii_impls, .. }) | ItemKind::Static(StaticItem { eii_impls, .. }) => {220                vec![hir::Attribute::Parsed(AttributeKind::EiiImpls(221                    eii_impls.iter().map(|i| self.lower_eii_impl(i)).collect(),222                ))]223            }224            ItemKind::MacroDef(name, MacroDef { eii_declaration: Some(target), .. }) => self225                .lower_eii_decl(id, *name, target)226                .map(|decl| vec![hir::Attribute::Parsed(AttributeKind::EiiDeclaration(decl))])227                .unwrap_or_default(),228229            ItemKind::ExternCrate(..)230            | ItemKind::Use(..)231            | ItemKind::Const(..)232            | ItemKind::ConstBlock(..)233            | ItemKind::Mod(..)234            | ItemKind::ForeignMod(..)235            | ItemKind::GlobalAsm(..)236            | ItemKind::TyAlias(..)237            | ItemKind::Enum(..)238            | ItemKind::Struct(..)239            | ItemKind::Union(..)240            | ItemKind::Trait(..)241            | ItemKind::TraitAlias(..)242            | ItemKind::Impl(..)243            | ItemKind::MacCall(..)244            | ItemKind::MacroDef(..)245            | ItemKind::Delegation(..)246            | ItemKind::DelegationMac(..) => Vec::new(),247        }248    }249250    fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {251        let vis_span = self.lower_span(i.vis.span);252        let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);253254        let extra_hir_attributes = self.generate_extra_attrs_for_item_kind(i.id, &i.kind);255        let attrs = self.lower_attrs_with_extra(256            hir_id,257            &i.attrs,258            i.span,259            Target::from_ast_item(i),260            &extra_hir_attributes,261        );262263        let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);264        let item = hir::Item {265            owner_id: hir_id.expect_owner(),266            kind,267            vis_span,268            span: self.lower_span(i.span),269            has_delayed_lints: !self.delayed_lints.is_empty(),270            eii: find_attr!(attrs, EiiImpls(..) | EiiDeclaration(..)),271        };272        self.arena.alloc(item)273    }274275    fn lower_item_kind(276        &mut self,277        span: Span,278        id: NodeId,279        hir_id: hir::HirId,280        attrs: &'hir [hir::Attribute],281        vis_span: Span,282        i: &ItemKind,283    ) -> hir::ItemKind<'hir> {284        match i {285            ItemKind::ExternCrate(orig_name, ident) => {286                let ident = self.lower_ident(*ident);287                hir::ItemKind::ExternCrate(*orig_name, ident)288            }289            ItemKind::Use(use_tree) => {290                // Start with an empty prefix.291                let prefix = Path {292                    segments: ThinVec::new(),293                    span: use_tree.prefix.span.shrink_to_lo(),294                    tokens: None,295                };296297                self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs)298            }299            ItemKind::Static(ast::StaticItem {300                ident,301                ty,302                safety: _,303                mutability: m,304                expr: e,305                define_opaque,306                eii_impls: _,307            }) => {308                let ident = self.lower_ident(*ident);309                let ty = self310                    .lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));311                let body_id = self.lower_const_body(span, e.as_deref());312                self.lower_define_opaque(hir_id, define_opaque);313                hir::ItemKind::Static(*m, ident, ty, body_id)314            }315            ItemKind::Const(ConstItem {316                defaultness: _,317                ident,318                generics,319                ty,320                rhs_kind,321                define_opaque,322            }) => {323                let ident = self.lower_ident(*ident);324                let (generics, (ty, rhs)) = self.lower_generics(325                    generics,326                    id,327                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),328                    |this| {329                        let ty = this.lower_ty_alloc(330                            ty,331                            ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy),332                        );333                        let rhs = this.lower_const_item_rhs(rhs_kind, span);334                        (ty, rhs)335                    },336                );337                self.lower_define_opaque(hir_id, &define_opaque);338                hir::ItemKind::Const(ident, generics, ty, rhs)339            }340            ItemKind::ConstBlock(ConstBlockItem { span, id, block }) => hir::ItemKind::Const(341                self.lower_ident(ConstBlockItem::IDENT),342                hir::Generics::empty(),343                self.arena.alloc(self.ty_tup(DUMMY_SP, &[])),344                hir::ConstItemRhs::Body({345                    let body = hir::Expr {346                        hir_id: self.lower_node_id(*id),347                        kind: hir::ExprKind::Block(self.lower_block(block, false), None),348                        span: self.lower_span(*span),349                    };350                    self.record_body(&[], body)351                }),352            ),353            ItemKind::Fn(Fn {354                sig: FnSig { decl, header, span: fn_sig_span },355                ident,356                generics,357                body,358                contract,359                define_opaque,360                ..361            }) => {362                self.with_new_scopes(*fn_sig_span, |this| {363                    // Note: we don't need to change the return type from `T` to364                    // `impl Future<Output = T>` here because lower_body365                    // only cares about the input argument patterns in the function366                    // declaration (decl), not the return types.367                    let coroutine_kind = header.coroutine_kind;368                    let body_id = this.lower_maybe_coroutine_body(369                        *fn_sig_span,370                        span,371                        hir_id,372                        decl,373                        coroutine_kind,374                        body.as_deref(),375                        attrs,376                        contract.as_deref(),377                    );378379                    let itctx = ImplTraitContext::Universal;380                    let (generics, decl) = this.lower_generics(generics, id, itctx, |this| {381                        this.lower_fn_decl(decl, id, *fn_sig_span, FnDeclKind::Fn, coroutine_kind)382                    });383                    let sig = hir::FnSig {384                        decl,385                        header: this.lower_fn_header(*header, hir::Safety::Safe, attrs),386                        span: this.lower_span(*fn_sig_span),387                    };388                    this.lower_define_opaque(hir_id, define_opaque);389                    let ident = this.lower_ident(*ident);390                    hir::ItemKind::Fn {391                        ident,392                        sig,393                        generics,394                        body: body_id,395                        has_body: body.is_some(),396                    }397                })398            }399            ItemKind::Mod(_, ident, mod_kind) => {400                let ident = self.lower_ident(*ident);401                match mod_kind {402                    ModKind::Loaded(items, _, spans) => {403                        hir::ItemKind::Mod(ident, self.lower_mod(items, spans))404                    }405                    ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),406                }407            }408            ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod {409                abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),410                items: self411                    .arena412                    .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),413            },414            ItemKind::GlobalAsm(asm) => {415                let asm = self.lower_inline_asm(span, asm);416                let fake_body =417                    self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));418                hir::ItemKind::GlobalAsm { asm, fake_body }419            }420            ItemKind::TyAlias(TyAlias { ident, generics, after_where_clause, ty, .. }) => {421                // We lower422                //423                // type Foo = impl Trait424                //425                // to426                //427                // type Foo = Foo1428                // opaque type Foo1: Trait429                let ident = self.lower_ident(*ident);430                let mut generics = generics.clone();431                add_ty_alias_where_clause(&mut generics, after_where_clause, true);432                let (generics, ty) = self.lower_generics(433                    &generics,434                    id,435                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),436                    |this| match ty {437                        None => {438                            let guar = this.dcx().span_delayed_bug(439                                span,440                                "expected to lower type alias type, but it was missing",441                            );442                            this.arena.alloc(this.ty(span, hir::TyKind::Err(guar)))443                        }444                        Some(ty) => this.lower_ty_alloc(445                            ty,446                            ImplTraitContext::OpaqueTy {447                                origin: hir::OpaqueTyOrigin::TyAlias {448                                    parent: this.local_def_id(id),449                                    in_assoc_ty: false,450                                },451                            },452                        ),453                    },454                );455                hir::ItemKind::TyAlias(ident, generics, ty)456            }457            ItemKind::Enum(ident, generics, enum_definition) => {458                let ident = self.lower_ident(*ident);459                let (generics, variants) = self.lower_generics(460                    generics,461                    id,462                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),463                    |this| {464                        this.arena.alloc_from_iter(465                            enum_definition.variants.iter().map(|x| this.lower_variant(i, x)),466                        )467                    },468                );469                hir::ItemKind::Enum(ident, generics, hir::EnumDef { variants })470            }471            ItemKind::Struct(ident, generics, struct_def) => {472                let ident = self.lower_ident(*ident);473                let (generics, struct_def) = self.lower_generics(474                    generics,475                    id,476                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),477                    |this| this.lower_variant_data(hir_id, i, struct_def),478                );479                hir::ItemKind::Struct(ident, generics, struct_def)480            }481            ItemKind::Union(ident, generics, vdata) => {482                let ident = self.lower_ident(*ident);483                let (generics, vdata) = self.lower_generics(484                    generics,485                    id,486                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),487                    |this| this.lower_variant_data(hir_id, i, vdata),488                );489                hir::ItemKind::Union(ident, generics, vdata)490            }491            ItemKind::Impl(Impl {492                generics: ast_generics,493                of_trait,494                self_ty: ty,495                items: impl_items,496                constness,497            }) => {498                // Lower the "impl header" first. This ordering is important499                // for in-band lifetimes! Consider `'a` here:500                //501                //     impl Foo<'a> for u32 {502                //         fn method(&'a self) { .. }503                //     }504                //505                // Because we start by lowering the `Foo<'a> for u32`506                // part, we will add `'a` to the list of generics on507                // the impl. When we then encounter it later in the508                // method, it will not be considered an in-band509                // lifetime to be added, but rather a reference to a510                // parent lifetime.511                let itctx = ImplTraitContext::Universal;512                let (generics, (of_trait, lowered_ty)) =513                    self.lower_generics(ast_generics, id, itctx, |this| {514                        let of_trait = of_trait515                            .as_deref()516                            .map(|of_trait| this.lower_trait_impl_header(of_trait));517518                        let lowered_ty = this.lower_ty_alloc(519                            ty,520                            ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf),521                        );522523                        (of_trait, lowered_ty)524                    });525526                let new_impl_items = self527                    .arena528                    .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));529530                let constness = self.lower_constness(*constness);531532                hir::ItemKind::Impl(hir::Impl {533                    generics,534                    of_trait,535                    self_ty: lowered_ty,536                    items: new_impl_items,537                    constness,538                })539            }540            ItemKind::Trait(Trait {541                impl_restriction,542                constness,543                is_auto,544                safety,545                ident,546                generics,547                bounds,548                items,549            }) => {550                let constness = self.lower_constness(*constness);551                let impl_restriction = self.lower_impl_restriction(impl_restriction);552                let ident = self.lower_ident(*ident);553                let (generics, (safety, items, bounds)) = self.lower_generics(554                    generics,555                    id,556                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),557                    |this| {558                        let bounds = this.lower_param_bounds(559                            bounds,560                            RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::SuperTrait),561                            ImplTraitContext::Disallowed(ImplTraitPosition::Bound),562                        );563                        let items = this.arena.alloc_from_iter(564                            items.iter().map(|item| this.lower_trait_item_ref(item)),565                        );566                        let safety = this.lower_safety(*safety, hir::Safety::Safe);567                        (safety, items, bounds)568                    },569                );570                hir::ItemKind::Trait {571                    impl_restriction,572                    constness,573                    is_auto: *is_auto,574                    safety,575                    ident,576                    generics,577                    bounds,578                    items,579                }580            }581            ItemKind::TraitAlias(TraitAlias { constness, ident, generics, bounds }) => {582                let constness = self.lower_constness(*constness);583                let ident = self.lower_ident(*ident);584                let (generics, bounds) = self.lower_generics(585                    generics,586                    id,587                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),588                    |this| {589                        this.lower_param_bounds(590                            bounds,591                            RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitAlias),592                            ImplTraitContext::Disallowed(ImplTraitPosition::Bound),593                        )594                    },595                );596                hir::ItemKind::TraitAlias(constness, ident, generics, bounds)597            }598            ItemKind::MacroDef(ident, MacroDef { body, macro_rules, eii_declaration: _ }) => {599                let ident = self.lower_ident(*ident);600                let body = Box::new(self.lower_delim_args(body));601                let def_id = self.local_def_id(id);602                let def_kind = self.tcx.def_kind(def_id);603                let DefKind::Macro(macro_kinds) = def_kind else {604                    unreachable!(605                        "expected DefKind::Macro for macro item, found {}",606                        def_kind.descr(def_id.to_def_id())607                    );608                };609                let macro_def = self.arena.alloc(ast::MacroDef {610                    body,611                    macro_rules: *macro_rules,612                    eii_declaration: None,613                });614                hir::ItemKind::Macro(ident, macro_def, macro_kinds)615            }616            ItemKind::Delegation(delegation) => {617                let delegation_results = self.lower_delegation(delegation, id);618                hir::ItemKind::Fn {619                    sig: delegation_results.sig,620                    ident: delegation_results.ident,621                    generics: delegation_results.generics,622                    body: delegation_results.body_id,623                    has_body: true,624                }625            }626            ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => {627                panic!("macros should have been expanded by now")628            }629        }630    }631632    fn lower_path_simple_eii(&mut self, id: NodeId, path: &Path) -> Option<DefId> {633        let res = self.get_partial_res(id)?;634        let Some(did) = res.expect_full_res().opt_def_id() else {635            self.dcx().span_delayed_bug(path.span, "should have errored in resolve");636            return None;637        };638639        Some(did)640    }641642    #[instrument(level = "debug", skip(self))]643    fn lower_use_tree(644        &mut self,645        tree: &UseTree,646        prefix: &Path,647        id: NodeId,648        vis_span: Span,649        attrs: &'hir [hir::Attribute],650    ) -> hir::ItemKind<'hir> {651        let path = &tree.prefix;652        let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();653654        match tree.kind {655            UseTreeKind::Simple(rename) => {656                let mut ident = tree.ident();657658                // First, apply the prefix to the path.659                let mut path = Path { segments, span: path.span, tokens: None };660661                // Correctly resolve `self` imports.662                if path.segments.len() > 1663                    && path.segments.last().unwrap().ident.name == kw::SelfLower664                {665                    let _ = path.segments.pop();666                    if rename.is_none() {667                        ident = path.segments.last().unwrap().ident;668                    }669                }670671                let res = self.lower_import_res(id, path.span);672                let path = self.lower_use_path(res, &path, ParamMode::Explicit);673                let ident = self.lower_ident(ident);674                hir::ItemKind::Use(path, hir::UseKind::Single(ident))675            }676            UseTreeKind::Glob(_) => {677                let res = self.expect_full_res(id);678                let res = self.lower_res(res);679                // Put the result in the appropriate namespace.680                let res = match res {681                    Res::Def(DefKind::Mod | DefKind::Trait, _) => {682                        PerNS { type_ns: Some(res), value_ns: None, macro_ns: None }683                    }684                    Res::Def(DefKind::Enum, _) => {685                        PerNS { type_ns: None, value_ns: Some(res), macro_ns: None }686                    }687                    Res::Err => {688                        // Propagate the error to all namespaces, just to be sure.689                        let err = Some(Res::Err);690                        PerNS { type_ns: err, value_ns: err, macro_ns: err }691                    }692                    _ => span_bug!(path.span, "bad glob res {:?}", res),693                };694                let path = Path { segments, span: path.span, tokens: None };695                let path = self.lower_use_path(res, &path, ParamMode::Explicit);696                hir::ItemKind::Use(path, hir::UseKind::Glob)697            }698            UseTreeKind::Nested { items: ref trees, .. } => {699                // Nested imports are desugared into simple imports.700                // So, if we start with701                //702                // ```703                // pub(x) use foo::{a, b};704                // ```705                //706                // we will create three items:707                //708                // ```709                // pub(x) use foo::a;710                // pub(x) use foo::b;711                // pub(x) use foo::{}; // <-- this is called the `ListStem`712                // ```713                //714                // The first two are produced by recursively invoking715                // `lower_use_tree` (and indeed there may be things716                // like `use foo::{a::{b, c}}` and so forth). They717                // wind up being directly added to718                // `self.items`. However, the structure of this719                // function also requires us to return one item, and720                // for that we return the `{}` import (called the721                // `ListStem`).722723                let span = prefix.span.to(path.span);724                let prefix = Path { segments, span, tokens: None };725726                // Add all the nested `PathListItem`s to the HIR.727                for &(ref use_tree, id) in trees {728                    let owner_id = self.owner_id(id);729730                    // Each `use` import is an item and thus are owners of the731                    // names in the path. Up to this point the nested import is732                    // the current owner, since we want each desugared import to733                    // own its own names, we have to adjust the owner before734                    // lowering the rest of the import.735                    self.with_hir_id_owner(id, |this| {736                        // `prefix` is lowered multiple times, but in different HIR owners.737                        // So each segment gets renewed `HirId` with the same738                        // `ItemLocalId` and the new owner. (See `lower_node_id`)739                        let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs);740                        if !attrs.is_empty() {741                            this.attrs.insert(hir::ItemLocalId::ZERO, attrs);742                        }743744                        let item = hir::Item {745                            owner_id,746                            kind,747                            vis_span,748                            span: this.lower_span(use_tree.span()),749                            has_delayed_lints: !this.delayed_lints.is_empty(),750                            eii: find_attr!(attrs, EiiImpls(..) | EiiDeclaration(..)),751                        };752                        hir::OwnerNode::Item(this.arena.alloc(item))753                    });754                }755756                // Condition should match `build_reduced_graph_for_use_tree`.757                let path = if trees.is_empty()758                    && !(prefix.segments.is_empty()759                        || prefix.segments.len() == 1760                            && prefix.segments[0].ident.name == kw::PathRoot)761                {762                    // For empty lists we need to lower the prefix so it is checked for things763                    // like stability later.764                    let res = self.lower_import_res(id, span);765                    self.lower_use_path(res, &prefix, ParamMode::Explicit)766                } else {767                    // For non-empty lists we can just drop all the data, the prefix is already768                    // present in HIR as a part of nested imports.769                    let span = self.lower_span(span);770                    self.arena.alloc(hir::UsePath { res: PerNS::default(), segments: &[], span })771                };772                hir::ItemKind::Use(path, hir::UseKind::ListStem)773            }774        }775    }776777    fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> {778        // Evaluate with the lifetimes in `params` in-scope.779        // This is used to track which lifetimes have already been defined,780        // and which need to be replicated when lowering an async fn.781        match ctxt {782            AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),783            AssocCtxt::Impl { of_trait } => {784                hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait))785            }786        }787    }788789    fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {790        let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);791        let owner_id = hir_id.expect_owner();792        let attrs =793            self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_foreign_item_kind(&i.kind));794        let (ident, kind) = match &i.kind {795            ForeignItemKind::Fn(Fn { sig, ident, generics, define_opaque, .. }) => {796                let fdec = &sig.decl;797                let itctx = ImplTraitContext::Universal;798                let (generics, (decl, fn_args)) =799                    self.lower_generics(generics, i.id, itctx, |this| {800                        (801                            // Disallow `impl Trait` in foreign items.802                            this.lower_fn_decl(fdec, i.id, sig.span, FnDeclKind::ExternFn, None),803                            this.lower_fn_params_to_idents(fdec),804                        )805                    });806807                // Unmarked safety in unsafe block defaults to unsafe.808                let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);809810                if define_opaque.is_some() {811                    self.dcx().span_err(i.span, "foreign functions cannot define opaque types");812                }813814                (815                    ident,816                    hir::ForeignItemKind::Fn(817                        hir::FnSig { header, decl, span: self.lower_span(sig.span) },818                        fn_args,819                        generics,820                    ),821                )822            }823            ForeignItemKind::Static(StaticItem {824                ident,825                ty,826                mutability,827                expr: _,828                safety,829                define_opaque,830                eii_impls: _,831            }) => {832                let ty = self833                    .lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));834                let safety = self.lower_safety(*safety, hir::Safety::Unsafe);835                if define_opaque.is_some() {836                    self.dcx().span_err(i.span, "foreign statics cannot define opaque types");837                }838                (ident, hir::ForeignItemKind::Static(ty, *mutability, safety))839            }840            ForeignItemKind::TyAlias(TyAlias { ident, .. }) => (ident, hir::ForeignItemKind::Type),841            ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),842        };843844        let item = hir::ForeignItem {845            owner_id,846            ident: self.lower_ident(*ident),847            kind,848            vis_span: self.lower_span(i.vis.span),849            span: self.lower_span(i.span),850            has_delayed_lints: !self.delayed_lints.is_empty(),851        };852        self.arena.alloc(item)853    }854855    fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemId {856        hir::ForeignItemId { owner_id: self.owner_id(i.id) }857    }858859    fn lower_variant(&mut self, item_kind: &ItemKind, v: &Variant) -> hir::Variant<'hir> {860        let hir_id = self.lower_node_id(v.id);861        self.lower_attrs(hir_id, &v.attrs, v.span, Target::Variant);862        hir::Variant {863            hir_id,864            def_id: self.local_def_id(v.id),865            data: self.lower_variant_data(hir_id, item_kind, &v.data),866            disr_expr: v867                .disr_expr868                .as_ref()869                .map(|e| self.lower_anon_const_to_anon_const(e, e.value.span)),870            ident: self.lower_ident(v.ident),871            span: self.lower_span(v.span),872        }873    }874875    fn lower_variant_data(876        &mut self,877        parent_id: hir::HirId,878        item_kind: &ItemKind,879        vdata: &VariantData,880    ) -> hir::VariantData<'hir> {881        match vdata {882            VariantData::Struct { fields, recovered } => {883                let fields = self884                    .arena885                    .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f)));886887                if let ItemKind::Union(..) = item_kind {888                    for field in &fields[..] {889                        if let Some(default) = field.default {890                            // Unions cannot derive `Default`, and it's not clear how to use default891                            // field values of unions if that was supported. Therefore, blanket reject892                            // trying to use field values with unions.893                            if self.tcx.features().default_field_values() {894                                self.dcx().emit_err(UnionWithDefault { span: default.span });895                            } else {896                                let _ = self.dcx().span_delayed_bug(897                                default.span,898                                "expected union default field values feature gate error but none \899                                was produced",900                            );901                            }902                        }903                    }904                }905906                hir::VariantData::Struct { fields, recovered: *recovered }907            }908            VariantData::Tuple(fields, id) => {909                let ctor_id = self.lower_node_id(*id);910                self.alias_attrs(ctor_id, parent_id);911                let fields = self912                    .arena913                    .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f)));914                for field in &fields[..] {915                    if let Some(default) = field.default {916                        // Default values in tuple struct and tuple variants are not allowed by the917                        // RFC due to concerns about the syntax, both in the item definition and the918                        // expression. We could in the future allow `struct S(i32 = 0);` and force919                        // users to construct the value with `let _ = S { .. };`.920                        if self.tcx.features().default_field_values() {921                            self.dcx().emit_err(TupleStructWithDefault { span: default.span });922                        } else {923                            let _ = self.dcx().span_delayed_bug(924                                default.span,925                                "expected `default values on `struct` fields aren't supported` \926                                 feature-gate error but none was produced",927                            );928                        }929                    }930                }931                hir::VariantData::Tuple(fields, ctor_id, self.local_def_id(*id))932            }933            VariantData::Unit(id) => {934                let ctor_id = self.lower_node_id(*id);935                self.alias_attrs(ctor_id, parent_id);936                hir::VariantData::Unit(ctor_id, self.local_def_id(*id))937            }938        }939    }940941    pub(super) fn lower_field_def(942        &mut self,943        (index, f): (usize, &FieldDef),944    ) -> hir::FieldDef<'hir> {945        let ty =946            self.lower_ty_alloc(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));947        let hir_id = self.lower_node_id(f.id);948        self.lower_attrs(hir_id, &f.attrs, f.span, Target::Field);949        hir::FieldDef {950            span: self.lower_span(f.span),951            hir_id,952            def_id: self.local_def_id(f.id),953            ident: match f.ident {954                Some(ident) => self.lower_ident(ident),955                // FIXME(jseyfried): positional field hygiene.956                None => Ident::new(sym::integer(index), self.lower_span(f.span)),957            },958            vis_span: self.lower_span(f.vis.span),959            default: f960                .default961                .as_ref()962                .map(|v| self.lower_anon_const_to_anon_const(v, v.value.span)),963            ty,964            safety: self.lower_safety(f.safety, hir::Safety::Safe),965        }966    }967968    fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {969        let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);970        let attrs = self.lower_attrs(971            hir_id,972            &i.attrs,973            i.span,974            Target::from_assoc_item_kind(&i.kind, AssocCtxt::Trait),975        );976        let trait_item_def_id = hir_id.expect_owner();977978        let (ident, generics, kind, has_value) = match &i.kind {979            AssocItemKind::Const(ConstItem {980                ident,981                generics,982                ty,983                rhs_kind,984                define_opaque,985                ..986            }) => {987                let (generics, kind) = self.lower_generics(988                    generics,989                    i.id,990                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),991                    |this| {992                        let ty = this.lower_ty_alloc(993                            ty,994                            ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy),995                        );996                        // Trait associated consts don't need an expression/body.997                        let rhs = if rhs_kind.has_expr() {998                            Some(this.lower_const_item_rhs(rhs_kind, i.span))999                        } else {1000                            None1001                        };1002                        hir::TraitItemKind::Const(ty, rhs, rhs_kind.is_type_const().into())1003                    },1004                );10051006                if define_opaque.is_some() {1007                    if rhs_kind.has_expr() {1008                        self.lower_define_opaque(hir_id, &define_opaque);1009                    } else {1010                        self.dcx().span_err(1011                            i.span,1012                            "only trait consts with default bodies can define opaque types",1013                        );1014                    }1015                }10161017                (*ident, generics, kind, rhs_kind.has_expr())1018            }1019            AssocItemKind::Fn(Fn { sig, ident, generics, body: None, define_opaque, .. }) => {1020                // FIXME(contracts): Deny contract here since it won't apply to1021                // any impl method or callees.1022                let idents = self.lower_fn_params_to_idents(&sig.decl);1023                let (generics, sig) = self.lower_method_sig(1024                    generics,1025                    sig,1026                    i.id,1027                    FnDeclKind::Trait,1028                    sig.header.coroutine_kind,1029                    attrs,1030                );1031                if define_opaque.is_some() {1032                    self.dcx().span_err(1033                        i.span,1034                        "only trait methods with default bodies can define opaque types",1035                    );1036                }1037                (1038                    *ident,1039                    generics,1040                    hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(idents)),1041                    false,1042                )1043            }1044            AssocItemKind::Fn(Fn {1045                sig,1046                ident,1047                generics,1048                body: Some(body),1049                contract,1050                define_opaque,1051                ..1052            }) => {1053                let body_id = self.lower_maybe_coroutine_body(1054                    sig.span,1055                    i.span,1056                    hir_id,1057                    &sig.decl,1058                    sig.header.coroutine_kind,1059                    Some(body),1060                    attrs,1061                    contract.as_deref(),1062                );1063                let (generics, sig) = self.lower_method_sig(1064                    generics,1065                    sig,1066                    i.id,1067                    FnDeclKind::Trait,1068                    sig.header.coroutine_kind,1069                    attrs,1070                );1071                self.lower_define_opaque(hir_id, &define_opaque);1072                (1073                    *ident,1074                    generics,1075                    hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),1076                    true,1077                )1078            }1079            AssocItemKind::Type(TyAlias {1080                ident,1081                generics,1082                after_where_clause,1083                bounds,1084                ty,1085                ..1086            }) => {1087                let mut generics = generics.clone();1088                add_ty_alias_where_clause(&mut generics, after_where_clause, false);1089                let (generics, kind) = self.lower_generics(1090                    &generics,1091                    i.id,1092                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),1093                    |this| {1094                        let ty = ty.as_ref().map(|x| {1095                            this.lower_ty_alloc(1096                                x,1097                                ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy),1098                            )1099                        });1100                        hir::TraitItemKind::Type(1101                            this.lower_param_bounds(1102                                bounds,1103                                RelaxedBoundPolicy::Allowed,1104                                ImplTraitContext::Disallowed(ImplTraitPosition::Generic),1105                            ),1106                            ty,1107                        )1108                    },1109                );1110                (*ident, generics, kind, ty.is_some())1111            }1112            AssocItemKind::Delegation(delegation) => {1113                let delegation_results = self.lower_delegation(delegation, i.id);1114                let item_kind = hir::TraitItemKind::Fn(1115                    delegation_results.sig,1116                    hir::TraitFn::Provided(delegation_results.body_id),1117                );1118                (delegation.ident, delegation_results.generics, item_kind, true)1119            }1120            AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {1121                panic!("macros should have been expanded by now")1122            }1123        };11241125        let defaultness = match i.kind.defaultness() {1126            // We do not yet support `final` on trait associated items other than functions.1127            // Even though we reject `final` on non-functions during AST validation, we still1128            // need to stop propagating it here because later compiler passes do not expect1129            // and cannot handle such items.1130            Defaultness::Final(..) if !matches!(i.kind, AssocItemKind::Fn(..)) => {1131                Defaultness::Implicit1132            }1133            defaultness => defaultness,1134        };1135        let (defaultness, _) = self1136            .lower_defaultness(defaultness, has_value, || hir::Defaultness::Default { has_value });11371138        let item = hir::TraitItem {1139            owner_id: trait_item_def_id,1140            ident: self.lower_ident(ident),1141            generics,1142            kind,1143            span: self.lower_span(i.span),1144            defaultness,1145            has_delayed_lints: !self.delayed_lints.is_empty(),1146        };1147        self.arena.alloc(item)1148    }11491150    fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemId {1151        hir::TraitItemId { owner_id: self.owner_id(i.id) }1152    }11531154    /// Construct `ExprKind::Err` for the given `span`.1155    pub(crate) fn expr_err(&mut self, span: Span, guar: ErrorGuaranteed) -> hir::Expr<'hir> {1156        self.expr(span, hir::ExprKind::Err(guar))1157    }11581159    fn lower_trait_impl_header(1160        &mut self,1161        trait_impl_header: &TraitImplHeader,1162    ) -> &'hir hir::TraitImplHeader<'hir> {1163        let TraitImplHeader { safety, polarity, defaultness, ref trait_ref } = *trait_impl_header;1164        let safety = self.lower_safety(safety, hir::Safety::Safe);1165        let polarity = match polarity {1166            ImplPolarity::Positive => ImplPolarity::Positive,1167            ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)),1168        };1169        // `defaultness.has_value()` is never called for an `impl`, always `true` in order1170        // to not cause an assertion failure inside the `lower_defaultness` function.1171        let has_val = true;1172        let (defaultness, defaultness_span) =1173            self.lower_defaultness(defaultness, has_val, || hir::Defaultness::Final);1174        let modifiers = TraitBoundModifiers {1175            constness: BoundConstness::Never,1176            asyncness: BoundAsyncness::Normal,1177            // we don't use this in bound lowering1178            polarity: BoundPolarity::Positive,1179        };1180        let trait_ref = self.lower_trait_ref(1181            modifiers,1182            trait_ref,1183            ImplTraitContext::Disallowed(ImplTraitPosition::Trait),1184        );11851186        self.arena.alloc(hir::TraitImplHeader {1187            safety,1188            polarity,1189            defaultness,1190            defaultness_span,1191            trait_ref,1192        })1193    }11941195    fn lower_impl_item(1196        &mut self,1197        i: &AssocItem,1198        is_in_trait_impl: bool,1199    ) -> &'hir hir::ImplItem<'hir> {1200        // Since `default impl` is not yet implemented, this is always true in impls.1201        let has_value = true;1202        let (defaultness, _) =1203            self.lower_defaultness(i.kind.defaultness(), has_value, || hir::Defaultness::Final);1204        let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);1205        let attrs = self.lower_attrs(1206            hir_id,1207            &i.attrs,1208            i.span,1209            Target::from_assoc_item_kind(&i.kind, AssocCtxt::Impl { of_trait: is_in_trait_impl }),1210        );12111212        let (ident, (generics, kind)) = match &i.kind {1213            AssocItemKind::Const(ConstItem {1214                ident,1215                generics,1216                ty,1217                rhs_kind,1218                define_opaque,1219                ..1220            }) => (1221                *ident,1222                self.lower_generics(1223                    generics,1224                    i.id,1225                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),1226                    |this| {1227                        let ty = this.lower_ty_alloc(1228                            ty,1229                            ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy),1230                        );1231                        this.lower_define_opaque(hir_id, &define_opaque);1232                        let rhs = this.lower_const_item_rhs(rhs_kind, i.span);1233                        hir::ImplItemKind::Const(ty, rhs)1234                    },1235                ),1236            ),1237            AssocItemKind::Fn(Fn {1238                sig, ident, generics, body, contract, define_opaque, ..1239            }) => {1240                let body_id = self.lower_maybe_coroutine_body(1241                    sig.span,1242                    i.span,1243                    hir_id,1244                    &sig.decl,1245                    sig.header.coroutine_kind,1246                    body.as_deref(),1247                    attrs,1248                    contract.as_deref(),1249                );1250                let (generics, sig) = self.lower_method_sig(1251                    generics,1252                    sig,1253                    i.id,1254                    if is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },1255                    sig.header.coroutine_kind,1256                    attrs,1257                );1258                self.lower_define_opaque(hir_id, &define_opaque);12591260                (*ident, (generics, hir::ImplItemKind::Fn(sig, body_id)))1261            }1262            AssocItemKind::Type(TyAlias { ident, generics, after_where_clause, ty, .. }) => {1263                let mut generics = generics.clone();1264                add_ty_alias_where_clause(&mut generics, after_where_clause, false);1265                (1266                    *ident,1267                    self.lower_generics(1268                        &generics,1269                        i.id,1270                        ImplTraitContext::Disallowed(ImplTraitPosition::Generic),1271                        |this| match ty {1272                            None => {1273                                let guar = this.dcx().span_delayed_bug(1274                                    i.span,1275                                    "expected to lower associated type, but it was missing",1276                                );1277                                let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err(guar)));1278                                hir::ImplItemKind::Type(ty)1279                            }1280                            Some(ty) => {1281                                let ty = this.lower_ty_alloc(1282                                    ty,1283                                    ImplTraitContext::OpaqueTy {1284                                        origin: hir::OpaqueTyOrigin::TyAlias {1285                                            parent: this.local_def_id(i.id),1286                                            in_assoc_ty: true,1287                                        },1288                                    },1289                                );1290                                hir::ImplItemKind::Type(ty)1291                            }1292                        },1293                    ),1294                )1295            }1296            AssocItemKind::Delegation(delegation) => {1297                let delegation_results = self.lower_delegation(delegation, i.id);1298                (1299                    delegation.ident,1300                    (1301                        delegation_results.generics,1302                        hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),1303                    ),1304                )1305            }1306            AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {1307                panic!("macros should have been expanded by now")1308            }1309        };13101311        let span = self.lower_span(i.span);1312        let item = hir::ImplItem {1313            owner_id: hir_id.expect_owner(),1314            ident: self.lower_ident(ident),1315            generics,1316            impl_kind: if is_in_trait_impl {1317                ImplItemImplKind::Trait {1318                    defaultness,1319                    trait_item_def_id: self1320                        .get_partial_res(i.id)1321                        .and_then(|r| r.expect_full_res().opt_def_id())1322                        .ok_or_else(|| {1323                            self.dcx().span_delayed_bug(1324                                span,1325                                "could not resolve trait item being implemented",1326                            )1327                        }),1328                }1329            } else {1330                ImplItemImplKind::Inherent { vis_span: self.lower_span(i.vis.span) }1331            },1332            kind,1333            span,1334            has_delayed_lints: !self.delayed_lints.is_empty(),1335        };1336        self.arena.alloc(item)1337    }13381339    fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemId {1340        hir::ImplItemId { owner_id: self.owner_id(i.id) }1341    }13421343    fn lower_defaultness(1344        &self,1345        d: Defaultness,1346        has_value: bool,1347        implicit: impl FnOnce() -> hir::Defaultness,1348    ) -> (hir::Defaultness, Option<Span>) {1349        match d {1350            Defaultness::Implicit => (implicit(), None),1351            Defaultness::Default(sp) => {1352                (hir::Defaultness::Default { has_value }, Some(self.lower_span(sp)))1353            }1354            Defaultness::Final(sp) => (hir::Defaultness::Final, Some(self.lower_span(sp))),1355        }1356    }13571358    fn record_body(1359        &mut self,1360        params: &'hir [hir::Param<'hir>],1361        value: hir::Expr<'hir>,1362    ) -> hir::BodyId {1363        let body = hir::Body { params, value: self.arena.alloc(value) };1364        let id = body.id();1365        assert_eq!(id.hir_id.owner, self.current_hir_id_owner);1366        self.bodies.push((id.hir_id.local_id, self.arena.alloc(body)));1367        id1368    }13691370    pub(super) fn lower_body(1371        &mut self,1372        f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),1373    ) -> hir::BodyId {1374        let prev_coroutine_kind = self.coroutine_kind.take();1375        let task_context = self.task_context.take();1376        let (parameters, result) = f(self);1377        let body_id = self.record_body(parameters, result);1378        self.task_context = task_context;1379        self.coroutine_kind = prev_coroutine_kind;1380        body_id1381    }13821383    fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {1384        let hir_id = self.lower_node_id(param.id);1385        self.lower_attrs(hir_id, &param.attrs, param.span, Target::Param);1386        hir::Param {1387            hir_id,1388            pat: self.lower_pat(&param.pat),1389            ty_span: self.lower_span(param.ty.span),1390            span: self.lower_span(param.span),1391        }1392    }13931394    pub(super) fn lower_fn_body(1395        &mut self,1396        decl: &FnDecl,1397        contract: Option<&FnContract>,1398        body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,1399    ) -> hir::BodyId {1400        self.lower_body(|this| {1401            let params =1402                this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x)));14031404            // Optionally lower the fn contract1405            if let Some(contract) = contract {1406                (params, this.lower_contract(body, contract))1407            } else {1408                (params, body(this))1409            }1410        })1411    }14121413    fn lower_fn_body_block(1414        &mut self,1415        decl: &FnDecl,1416        body: &Block,1417        contract: Option<&FnContract>,1418    ) -> hir::BodyId {1419        self.lower_fn_body(decl, contract, |this| this.lower_block_expr(body))1420    }14211422    pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {1423        self.lower_body(|this| {1424            (1425                &[],1426                match expr {1427                    Some(expr) => this.lower_expr_mut(expr),1428                    None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")),1429                },1430            )1431        })1432    }14331434    /// Takes what may be the body of an `async fn` or a `gen fn` and wraps it in an `async {}` or1435    /// `gen {}` block as appropriate.1436    fn lower_maybe_coroutine_body(1437        &mut self,1438        fn_decl_span: Span,1439        span: Span,1440        fn_id: hir::HirId,1441        decl: &FnDecl,1442        coroutine_kind: Option<CoroutineKind>,1443        body: Option<&Block>,1444        attrs: &'hir [hir::Attribute],1445        contract: Option<&FnContract>,1446    ) -> hir::BodyId {1447        let Some(body) = body else {1448            // Functions without a body are an error, except if this is an intrinsic. For those we1449            // create a fake body so that the entire rest of the compiler doesn't have to deal with1450            // this as a special case.1451            return self.lower_fn_body(decl, contract, |this| {1452                if find_attr!(attrs, RustcIntrinsic) || this.tcx.is_sdylib_interface_build() {1453                    let span = this.lower_span(span);1454                    let empty_block = hir::Block {1455                        hir_id: this.next_id(),1456                        stmts: &[],1457                        expr: None,1458                        rules: hir::BlockCheckMode::DefaultBlock,1459                        span,1460                        targeted_by_break: false,1461                    };1462                    let loop_ = hir::ExprKind::Loop(1463                        this.arena.alloc(empty_block),1464                        None,1465                        hir::LoopSource::Loop,1466                        span,1467                    );1468                    hir::Expr { hir_id: this.next_id(), kind: loop_, span }1469                } else {1470                    this.expr_err(span, this.dcx().has_errors().unwrap())1471                }1472            });1473        };1474        let Some(coroutine_kind) = coroutine_kind else {1475            // Typical case: not a coroutine.1476            return self.lower_fn_body_block(decl, body, contract);1477        };1478        // FIXME(contracts): Support contracts on async fn.1479        self.lower_body(|this| {1480            let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(1481                decl,1482                |this| this.lower_block_expr(body),1483                fn_decl_span,1484                body.span,1485                coroutine_kind,1486                hir::CoroutineSource::Fn,1487            );14881489            // FIXME(async_fn_track_caller): Can this be moved above?1490            let hir_id = expr.hir_id;1491            this.maybe_forward_track_caller(body.span, fn_id, hir_id);14921493            (parameters, expr)1494        })1495    }14961497    /// Lowers a desugared coroutine body after moving all of the arguments1498    /// into the body. This is to make sure that the future actually owns the1499    /// arguments that are passed to the function, and to ensure things like1500    /// drop order are stable.1501    pub(crate) fn lower_coroutine_body_with_moved_arguments(1502        &mut self,1503        decl: &FnDecl,1504        lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>,1505        fn_decl_span: Span,1506        body_span: Span,1507        coroutine_kind: CoroutineKind,1508        coroutine_source: hir::CoroutineSource,1509    ) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>) {1510        let mut parameters: Vec<hir::Param<'_>> = Vec::new();1511        let mut statements: Vec<hir::Stmt<'_>> = Vec::new();15121513        // Async function parameters are lowered into the closure body so that they are1514        // captured and so that the drop order matches the equivalent non-async functions.1515        //1516        // from:1517        //1518        //     async fn foo(<pattern>: <ty>, <pattern>: <ty>, <pattern>: <ty>) {1519        //         <body>1520        //     }1521        //1522        // into:1523        //1524        //     fn foo(__arg0: <ty>, __arg1: <ty>, __arg2: <ty>) {1525        //       async move {1526        //         let __arg2 = __arg2;1527        //         let <pattern> = __arg2;1528        //         let __arg1 = __arg1;1529        //         let <pattern> = __arg1;1530        //         let __arg0 = __arg0;1531        //         let <pattern> = __arg0;1532        //         drop-temps { <body> } // see comments later in fn for details1533        //       }1534        //     }1535        //1536        // If `<pattern>` is a simple ident, then it is lowered to a single1537        // `let <pattern> = <pattern>;` statement as an optimization.1538        //1539        // Note that the body is embedded in `drop-temps`; an1540        // equivalent desugaring would be `return { <body>1541        // };`. The key point is that we wish to drop all the1542        // let-bound variables and temporaries created in the body1543        // (and its tail expression!) before we drop the1544        // parameters (c.f. rust-lang/rust#64512).1545        for (index, parameter) in decl.inputs.iter().enumerate() {1546            let parameter = self.lower_param(parameter);1547            let span = parameter.pat.span;15481549            // Check if this is a binding pattern, if so, we can optimize and avoid adding a1550            // `let <pat> = __argN;` statement. In this case, we do not rename the parameter.1551            let (ident, is_simple_parameter) = match parameter.pat.kind {1552                hir::PatKind::Binding(hir::BindingMode(ByRef::No, _), _, ident, _) => (ident, true),1553                // For `ref mut` or wildcard arguments, we can't reuse the binding, but1554                // we can keep the same name for the parameter.1555                // This lets rustdoc render it correctly in documentation.1556                hir::PatKind::Binding(_, _, ident, _) => (ident, false),1557                hir::PatKind::Wild => (Ident::with_dummy_span(rustc_span::kw::Underscore), false),1558                _ => {1559                    // Replace the ident for bindings that aren't simple.1560                    let name = format!("__arg{index}");1561                    let ident = Ident::from_str(&name);15621563                    (ident, false)1564                }1565            };15661567            let desugared_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);15681569            // Construct a parameter representing `__argN: <ty>` to replace the parameter of the1570            // async function.1571            //1572            // If this is the simple case, this parameter will end up being the same as the1573            // original parameter, but with a different pattern id.1574            let stmt_attrs = self.attrs.get(&parameter.hir_id.local_id).copied();1575            let (new_parameter_pat, new_parameter_id) = self.pat_ident(desugared_span, ident);1576            let new_parameter = hir::Param {1577                hir_id: parameter.hir_id,1578                pat: new_parameter_pat,1579                ty_span: self.lower_span(parameter.ty_span),1580                span: self.lower_span(parameter.span),1581            };15821583            if is_simple_parameter {1584                // If this is the simple case, then we only insert one statement that is1585                // `let <pat> = <pat>;`. We re-use the original argument's pattern so that1586                // `HirId`s are densely assigned.1587                let expr = self.expr_ident(desugared_span, ident, new_parameter_id);1588                let stmt = self.stmt_let_pat(1589                    stmt_attrs,1590                    desugared_span,1591                    Some(expr),1592                    parameter.pat,1593                    hir::LocalSource::AsyncFn,1594                );1595                statements.push(stmt);1596            } else {1597                // If this is not the simple case, then we construct two statements:1598                //1599                // ```1600                // let __argN = __argN;1601                // let <pat> = __argN;1602                // ```1603                //1604                // The first statement moves the parameter into the closure and thus ensures1605                // that the drop order is correct.1606                //1607                // The second statement creates the bindings that the user wrote.16081609                // Construct the `let mut __argN = __argN;` statement. It must be a mut binding1610                // because the user may have specified a `ref mut` binding in the next1611                // statement.1612                let (move_pat, move_id) =1613                    self.pat_ident_binding_mode(desugared_span, ident, hir::BindingMode::MUT);1614                let move_expr = self.expr_ident(desugared_span, ident, new_parameter_id);1615                let move_stmt = self.stmt_let_pat(1616                    None,1617                    desugared_span,1618                    Some(move_expr),1619                    move_pat,1620                    hir::LocalSource::AsyncFn,1621                );16221623                // Construct the `let <pat> = __argN;` statement. We re-use the original1624                // parameter's pattern so that `HirId`s are densely assigned.1625                let pattern_expr = self.expr_ident(desugared_span, ident, move_id);1626                let pattern_stmt = self.stmt_let_pat(1627                    stmt_attrs,1628                    desugared_span,1629                    Some(pattern_expr),1630                    parameter.pat,1631                    hir::LocalSource::AsyncFn,1632                );16331634                statements.push(move_stmt);1635                statements.push(pattern_stmt);1636            };16371638            parameters.push(new_parameter);1639        }16401641        let mkbody = |this: &mut LoweringContext<'_, 'hir>| {1642            // Create a block from the user's function body:1643            let user_body = lower_body(this);16441645            // Transform into `drop-temps { <user-body> }`, an expression:1646            let desugared_span =1647                this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);1648            let user_body = this.expr_drop_temps(desugared_span, this.arena.alloc(user_body));16491650            // As noted above, create the final block like1651            //1652            // ```1653            // {1654            //   let $param_pattern = $raw_param;1655            //   ...1656            //   drop-temps { <user-body> }1657            // }1658            // ```1659            let body = this.block_all(1660                desugared_span,1661                this.arena.alloc_from_iter(statements),1662                Some(user_body),1663            );16641665            this.expr_block(body)1666        };1667        let desugaring_kind = match coroutine_kind {1668            CoroutineKind::Async { .. } => hir::CoroutineDesugaring::Async,1669            CoroutineKind::Gen { .. } => hir::CoroutineDesugaring::Gen,1670            CoroutineKind::AsyncGen { .. } => hir::CoroutineDesugaring::AsyncGen,1671        };1672        let closure_id = coroutine_kind.closure_id();16731674        let coroutine_expr = self.make_desugared_coroutine_expr(1675            // The default capture mode here is by-ref. Later on during upvar analysis,1676            // we will force the captured arguments to by-move, but for async closures,1677            // we want to make sure that we avoid unnecessarily moving captures, or else1678            // all async closures would default to `FnOnce` as their calling mode.1679            CaptureBy::Ref,1680            closure_id,1681            None,1682            fn_decl_span,1683            body_span,1684            desugaring_kind,1685            coroutine_source,1686            mkbody,1687        );16881689        let expr = hir::Expr {1690            hir_id: self.lower_node_id(closure_id),1691            kind: coroutine_expr,1692            span: self.lower_span(body_span),1693        };16941695        (self.arena.alloc_from_iter(parameters), expr)1696    }16971698    fn lower_method_sig(1699        &mut self,1700        generics: &Generics,1701        sig: &FnSig,1702        id: NodeId,1703        kind: FnDeclKind,1704        coroutine_kind: Option<CoroutineKind>,1705        attrs: &[hir::Attribute],1706    ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {1707        let header = self.lower_fn_header(sig.header, hir::Safety::Safe, attrs);1708        let itctx = ImplTraitContext::Universal;1709        let (generics, decl) = self.lower_generics(generics, id, itctx, |this| {1710            this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)1711        });1712        (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })1713    }17141715    pub(super) fn lower_fn_header(1716        &mut self,1717        h: FnHeader,1718        default_safety: hir::Safety,1719        attrs: &[hir::Attribute],1720    ) -> hir::FnHeader {1721        let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {1722            hir::IsAsync::Async(self.lower_span(span))1723        } else {1724            hir::IsAsync::NotAsync1725        };17261727        let safety = self.lower_safety(h.safety, default_safety);17281729        // Treat safe `#[target_feature]` functions as unsafe, but also remember that we did so.1730        let safety = if find_attr!(attrs, TargetFeature { was_forced: false, .. })1731            && safety.is_safe()1732            && !self.tcx.sess.target.is_like_wasm1733        {1734            hir::HeaderSafety::SafeTargetFeatures1735        } else {1736            safety.into()1737        };17381739        hir::FnHeader {1740            safety,1741            asyncness,1742            constness: self.lower_constness(h.constness),1743            abi: self.lower_extern(h.ext),1744        }1745    }17461747    pub(super) fn lower_abi(&mut self, abi_str: StrLit) -> ExternAbi {1748        let ast::StrLit { symbol_unescaped, span, .. } = abi_str;1749        let extern_abi = symbol_unescaped.as_str().parse().unwrap_or_else(|_| {1750            self.error_on_invalid_abi(abi_str);1751            ExternAbi::Rust1752        });1753        let tcx = self.tcx;17541755        // we can't do codegen for unsupported ABIs, so error now so we won't get farther1756        if !tcx.sess.target.is_abi_supported(extern_abi) {1757            let mut err = struct_span_code_err!(1758                tcx.dcx(),1759                span,1760                E0570,1761                "{extern_abi} is not a supported ABI for the current target",1762            );17631764            if let ExternAbi::Stdcall { unwind } = extern_abi {1765                let c_abi = ExternAbi::C { unwind };1766                let system_abi = ExternAbi::System { unwind };1767                err.help(format!("if you need `extern {extern_abi}` on win32 and `extern {c_abi}` everywhere else, \1768                    use `extern {system_abi}`"1769                ));1770            }1771            err.emit();1772        }1773        // Show required feature gate even if we already errored, as the user is likely to build the code1774        // for the actually intended target next and then they will need the feature gate.1775        gate_unstable_abi(tcx.sess, tcx.features(), span, extern_abi);1776        extern_abi1777    }17781779    pub(super) fn lower_extern(&mut self, ext: Extern) -> ExternAbi {1780        match ext {1781            Extern::None => ExternAbi::Rust,1782            Extern::Implicit(_) => ExternAbi::FALLBACK,1783            Extern::Explicit(abi, _) => self.lower_abi(abi),1784        }1785    }17861787    fn error_on_invalid_abi(&self, abi: StrLit) {1788        let abi_names = enabled_names(self.tcx.features(), abi.span)1789            .iter()1790            .map(|s| Symbol::intern(s))1791            .collect::<Vec<_>>();1792        let suggested_name = find_best_match_for_name(&abi_names, abi.symbol_unescaped, None);1793        self.dcx().emit_err(InvalidAbi {1794            abi: abi.symbol_unescaped,1795            span: abi.span,1796            suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {1797                span: abi.span,1798                suggestion: suggested_name.to_string(),1799            }),1800            command: "rustc --print=calling-conventions".to_string(),1801        });1802    }18031804    pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness {1805        match c {1806            Const::Yes(_) => hir::Constness::Const,1807            Const::No => hir::Constness::NotConst,1808        }1809    }18101811    pub(super) fn lower_safety(&self, s: Safety, default: hir::Safety) -> hir::Safety {1812        match s {1813            Safety::Unsafe(_) => hir::Safety::Unsafe,1814            Safety::Default => default,1815            Safety::Safe(_) => hir::Safety::Safe,1816        }1817    }18181819    pub(super) fn lower_impl_restriction(1820        &mut self,1821        r: &ImplRestriction,1822    ) -> &'hir hir::ImplRestriction<'hir> {1823        let kind = match &r.kind {1824            RestrictionKind::Unrestricted => hir::RestrictionKind::Unrestricted,1825            RestrictionKind::Restricted { path, id, shorthand: _ } => {1826                let res = self.get_partial_res(*id);1827                if let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) {1828                    hir::RestrictionKind::Restricted(self.arena.alloc(hir::Path {1829                        res: did,1830                        segments: self.arena.alloc_from_iter(path.segments.iter().map(|segment| {1831                            self.lower_path_segment(1832                                path.span,1833                                segment,1834                                ParamMode::Explicit,1835                                GenericArgsMode::Err,1836                                ImplTraitContext::Disallowed(ImplTraitPosition::Path),1837                                None,1838                            )1839                        })),1840                        span: self.lower_span(path.span),1841                    }))1842                } else {1843                    self.dcx().span_delayed_bug(path.span, "should have errored in resolve");1844                    hir::RestrictionKind::Unrestricted1845                }1846            }1847        };1848        self.arena.alloc(hir::ImplRestriction { kind, span: self.lower_span(r.span) })1849    }18501851    /// Return the pair of the lowered `generics` as `hir::Generics` and the evaluation of `f` with1852    /// the carried impl trait definitions and bounds.1853    #[instrument(level = "debug", skip(self, f))]1854    fn lower_generics<T>(1855        &mut self,1856        generics: &Generics,1857        parent_node_id: NodeId,1858        itctx: ImplTraitContext,1859        f: impl FnOnce(&mut Self) -> T,1860    ) -> (&'hir hir::Generics<'hir>, T) {1861        assert!(self.impl_trait_defs.is_empty());1862        assert!(self.impl_trait_bounds.is_empty());18631864        let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new();1865        predicates.extend(generics.params.iter().filter_map(|param| {1866            self.lower_generic_bound_predicate(1867                param.ident,1868                param.id,1869                &param.kind,1870                &param.bounds,1871                param.colon_span,1872                generics.span,1873                RelaxedBoundPolicy::Allowed,1874                itctx,1875                PredicateOrigin::GenericParam,1876            )1877        }));1878        predicates.extend(1879            generics1880                .where_clause1881                .predicates1882                .iter()1883                .map(|predicate| self.lower_where_predicate(predicate, &generics.params)),1884        );18851886        let mut params: SmallVec<[hir::GenericParam<'hir>; 4]> = self1887            .lower_generic_params_mut(&generics.params, hir::GenericParamSource::Generics)1888            .collect();18891890        // Introduce extra lifetimes if late resolution tells us to.1891        let extra_lifetimes = self.resolver.extra_lifetime_params(parent_node_id);1892        params.extend(extra_lifetimes.into_iter().filter_map(|&(ident, node_id, res)| {1893            self.lifetime_res_to_generic_param(1894                ident,1895                node_id,1896                res,1897                hir::GenericParamSource::Generics,1898            )1899        }));19001901        let has_where_clause_predicates = !generics.where_clause.predicates.is_empty();1902        let where_clause_span = self.lower_span(generics.where_clause.span);1903        let span = self.lower_span(generics.span);1904        let res = f(self);19051906        let impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);1907        params.extend(impl_trait_defs.into_iter());19081909        let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);1910        predicates.extend(impl_trait_bounds.into_iter());19111912        let lowered_generics = self.arena.alloc(hir::Generics {1913            params: self.arena.alloc_from_iter(params),1914            predicates: self.arena.alloc_from_iter(predicates),1915            has_where_clause_predicates,1916            where_clause_span,1917            span,1918        });19191920        (lowered_generics, res)1921    }19221923    pub(super) fn lower_define_opaque(1924        &mut self,1925        hir_id: HirId,1926        define_opaque: &Option<ThinVec<(NodeId, Path)>>,1927    ) {1928        assert_eq!(self.define_opaque, None);1929        assert!(hir_id.is_owner());1930        let Some(define_opaque) = define_opaque.as_ref() else {1931            return;1932        };1933        let define_opaque = define_opaque.iter().filter_map(|(id, path)| {1934            let res = self.get_partial_res(*id);1935            let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) else {1936                self.dcx().span_delayed_bug(path.span, "should have errored in resolve");1937                return None;1938            };1939            let Some(did) = did.as_local() else {1940                self.dcx().span_err(1941                    path.span,1942                    "only opaque types defined in the local crate can be defined",1943                );1944                return None;1945            };1946            Some((self.lower_span(path.span), did))1947        });1948        let define_opaque = self.arena.alloc_from_iter(define_opaque);1949        self.define_opaque = Some(define_opaque);1950    }19511952    pub(super) fn lower_generic_bound_predicate(1953        &mut self,1954        ident: Ident,1955        id: NodeId,1956        kind: &GenericParamKind,1957        bounds: &[GenericBound],1958        colon_span: Option<Span>,1959        parent_span: Span,1960        rbp: RelaxedBoundPolicy<'_>,1961        itctx: ImplTraitContext,1962        origin: PredicateOrigin,1963    ) -> Option<hir::WherePredicate<'hir>> {1964        // Do not create a clause if we do not have anything inside it.1965        if bounds.is_empty() {1966            return None;1967        }19681969        let bounds = self.lower_param_bounds(bounds, rbp, itctx);19701971        let param_span = ident.span;19721973        // Reconstruct the span of the entire predicate from the individual generic bounds.1974        let span_start = colon_span.unwrap_or_else(|| param_span.shrink_to_hi());1975        let span = bounds.iter().fold(span_start, |span_accum, bound| {1976            match bound.span().find_ancestor_inside(parent_span) {1977                Some(bound_span) => span_accum.to(bound_span),1978                None => span_accum,1979            }1980        });1981        let span = self.lower_span(span);1982        let hir_id = self.next_id();1983        let kind = self.arena.alloc(match kind {1984            GenericParamKind::Const { .. } => return None,1985            GenericParamKind::Type { .. } => {1986                let def_id = self.local_def_id(id).to_def_id();1987                let hir_id = self.next_id();1988                let res = Res::Def(DefKind::TyParam, def_id);1989                let ident = self.lower_ident(ident);1990                let ty_path = self.arena.alloc(hir::Path {1991                    span: self.lower_span(param_span),1992                    res,1993                    segments: self1994                        .arena1995                        .alloc_from_iter([hir::PathSegment::new(ident, hir_id, res)]),1996                });1997                let ty_id = self.next_id();1998                let bounded_ty =1999                    self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path));2000                hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {

Code quality findings 20

Critical: Use of 'unsafe' keyword bypasses Rust's safety guarantees. Requires careful auditing, clear justification (FFI, specific optimizations), and minimal scope.
error safety unsafe-block
EiiDecl { foreign_item, impl_unsafe }: &EiiDecl,
Critical: Use of 'unsafe' keyword bypasses Rust's safety guarantees. Requires careful auditing, clear justification (FFI, specific optimizations), and minimal scope.
error safety unsafe-block
// Unmarked safety in unsafe block defaults to unsafe.
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
let node = self.ast_index[def_id];
Warning: '.expect()' will panic with a custom message on None/Err. While better than unwrap() for debugging, prefer non-panicking error handling in production code (match, if let, ?).
warning correctness expect-usage
eii_macro_path.segments.last().expect("at least one segment").ident,
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
attrs: &'hir [hir::Attribute],
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
attrs: &'hir [hir::Attribute],
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
&& path.segments.last().unwrap().ident.name == kw::SelfLower
Warning: Ignoring a Result or Option using 'let _ =' can hide errors or unexpected None values. Ensure the value is handled appropriately (match, if let, ?, expect) unless intentionally discarded with justification.
warning correctness discarded-result
let _ = path.segments.pop();
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
ident = path.segments.last().unwrap().ident;
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
&& prefix.segments[0].ident.name == kw::PathRoot)
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
for field in &fields[..] {
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
for field in &fields[..] {
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
params: &'hir [hir::Param<'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
f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'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
attrs: &'hir [hir::Attribute],
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
warning correctness unwrap-usage
this.expr_err(span, this.dcx().has_errors().unwrap())
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::Param<'hir>], hir::Expr<'hir>) {
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info maintainability wildcard-import
use rustc_ast::*;
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
vec.push(hir::ItemId { owner_id: self.owner_id(id) });
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 (ident, is_simple_parameter) = match parameter.pat.kind {

Get this view in your editor

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