compiler/rustc_ast_lowering/src/lib.rs RUST 3,169 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 3,169.
1//! Lowers the AST to the HIR.2//!3//! Since the AST and HIR are fairly similar, this is mostly a simple procedure,4//! much like a fold. Where lowering involves a bit more work things get more5//! interesting and there are some invariants you should know about. These mostly6//! concern spans and IDs.7//!8//! Spans are assigned to AST nodes during parsing and then are modified during9//! expansion to indicate the origin of a node and the process it went through10//! being expanded. IDs are assigned to AST nodes just before lowering.11//!12//! For the simpler lowering steps, IDs and spans should be preserved. Unlike13//! expansion we do not preserve the process of lowering in the spans, so spans14//! should not be modified here. When creating a new node (as opposed to15//! "folding" an existing one), create a new ID using `next_id()`.16//!17//! You must ensure that IDs are unique. That means that you should only use the18//! ID from an AST node in a single HIR node (you can assume that AST node-IDs19//! are unique). Every new node must have a unique ID. Avoid cloning HIR nodes.20//! If you do, you must then set the new node's ID to a fresh one.21//!22//! Spans are used for error messages and for tools to map semantics back to23//! source code. It is therefore not as important with spans as IDs to be strict24//! about use (you can't break the compiler by screwing up a span). Obviously, a25//! HIR node can only have a single span. But multiple nodes can have the same26//! span and spans don't need to be kept in order, etc. Where code is preserved27//! by lowering, it should have the same span as in the AST. Where HIR nodes are28//! new it is probably best to give a span for the whole AST node being lowered.29//! All nodes should have real spans; don't use dummy spans. Tools are likely to30//! get confused if the spans from leaf AST nodes occur in multiple places31//! in the HIR, especially for multiple identifiers.3233// tidy-alphabetical-start34#![feature(deref_patterns)]35#![recursion_limit = "256"]36// tidy-alphabetical-end3738use std::mem;39use std::sync::Arc;4041use rustc_ast::mut_visit::{self, MutVisitor};42use rustc_ast::node_id::NodeMap;43use rustc_ast::visit::{self, Visitor};44use rustc_ast::{self as ast, *};45use rustc_attr_parsing::{AttributeParser, OmitDoc, Recovery, ShouldEmit};46use rustc_data_structures::fx::FxIndexMap;47use rustc_data_structures::sorted_map::SortedMap;48use rustc_data_structures::stable_hash::{StableHash, StableHasher};49use rustc_data_structures::steal::Steal;50use rustc_data_structures::tagged_ptr::TaggedRef;51use rustc_data_structures::unord::ExtendUnord;52use rustc_errors::codes::*;53use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle};54use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};55use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap};56use rustc_hir::definitions::PerParentDisambiguatorState;57use rustc_hir::lints::DelayedLint;58use rustc_hir::{59    self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource,60    LifetimeSyntax, MissingLifetimeKind, ParamName, Target, TraitCandidate, find_attr,61};62use rustc_index::{Idx, IndexVec};63use rustc_macros::extension;64use rustc_middle::queries::Providers;65use rustc_middle::span_bug;66use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt};67use rustc_session::errors::add_feature_diagnostics;68use rustc_span::symbol::{Ident, Symbol, kw, sym};69use rustc_span::{DUMMY_SP, DesugaringKind, Span};70use smallvec::{SmallVec, smallvec};71use thin_vec::ThinVec;72use tracing::{debug, instrument, trace};7374use crate::diagnostics::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait};7576macro_rules! arena_vec {77    ($this:expr; $($x:expr),*) => (78        $this.arena.alloc_from_iter([$($x),*])79    );80}8182mod asm;83mod block;84mod contract;85mod delegation;86mod diagnostics;87mod expr;88mod format;89mod index;90mod item;91mod pat;92mod path;93pub mod stability;9495pub fn provide(providers: &mut Providers) {96    providers.index_ast = index_ast;97    providers.lower_to_hir = lower_to_hir;98}99100struct LoweringContext<'a, 'hir> {101    tcx: TyCtxt<'hir>,102    resolver: &'a ResolverAstLowering<'hir>,103    current_disambiguator: PerParentDisambiguatorState,104105    /// Used to allocate HIR nodes.106    arena: &'hir hir::Arena<'hir>,107108    /// Bodies inside the owner being lowered.109    bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,110    /// `#[define_opaque]` attributes111    define_opaque: Option<&'hir [(Span, LocalDefId)]>,112    /// Attributes inside the owner being lowered.113    attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,114    /// Collect items that were created by lowering the current owner.115    children: LocalDefIdMap<hir::MaybeOwner<'hir>>,116117    contract_ensures: Option<(Span, Ident, HirId)>,118119    coroutine_kind: Option<hir::CoroutineKind>,120121    /// When inside an `async` context, this is the `HirId` of the122    /// `task_context` local bound to the resume argument of the coroutine.123    task_context: Option<HirId>,124125    /// Used to get the current `fn`'s def span to point to when using `await`126    /// outside of an `async fn`.127    current_item: Option<Span>,128129    try_block_scope: TryBlockScope,130    loop_scope: Option<HirId>,131    is_in_loop_condition: bool,132    is_in_dyn_type: bool,133134    current_hir_id_owner: hir::OwnerId,135    owner: &'a PerOwnerResolverData<'hir>,136    item_local_id_counter: hir::ItemLocalId,137    trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>,138139    impl_trait_defs: Vec<hir::GenericParam<'hir>>,140    impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,141142    /// NodeIds of pattern identifiers and labelled nodes that are lowered inside the current HIR owner.143    ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,144    /// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering check.145    #[cfg(debug_assertions)]146    node_id_to_local_id: NodeMap<hir::ItemLocalId>,147    /// The `NodeId` space is split in two.148    /// `0..resolver.next_node_id` are created by the resolver on the AST.149    /// The higher part `resolver.next_node_id..next_node_id` are created during lowering.150    next_node_id: NodeId,151    /// Maps the `NodeId`s created during lowering to `LocalDefId`s.152    node_id_to_def_id: NodeMap<LocalDefId>,153    /// Overlay over resolver's `partial_res_map` used by delegation.154    /// This only contains `PartialRes::new(Res::Local(self_param_id))`,155    /// so we only store `self_param_id`.156    partial_res_overrides: NodeMap<NodeId>,157158    allow_contracts: Arc<[Symbol]>,159    allow_try_trait: Arc<[Symbol]>,160    allow_gen_future: Arc<[Symbol]>,161    allow_pattern_type: Arc<[Symbol]>,162    allow_async_gen: Arc<[Symbol]>,163    allow_async_iterator: Arc<[Symbol]>,164    allow_for_await: Arc<[Symbol]>,165    allow_async_fn_traits: Arc<[Symbol]>,166167    delayed_lints: Vec<DelayedLint>,168169    /// Stack of `move(...)` collection states. A plain closure body pushes170    /// `Some`, so `move(...)` expressions can record the generated locals they171    /// should lower to. Nested bodies that cannot use `move(...)` push `None`.172    move_expr_bindings: Vec<Option<expr::MoveExprState<'hir>>>,173174    attribute_parser: AttributeParser<'hir>,175}176177impl<'a, 'hir> LoweringContext<'a, 'hir> {178    fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>, owner: NodeId) -> Self {179        let current_ast_owner = &resolver.owners[&owner];180        let current_hir_id_owner = hir::OwnerId { def_id: current_ast_owner.def_id };181        let current_disambiguator = resolver182            .disambiguators183            .get(&current_hir_id_owner.def_id)184            .map(|s| s.steal())185            .unwrap_or_else(|| PerParentDisambiguatorState::new(current_hir_id_owner.def_id));186187        Self {188            tcx,189            resolver,190            current_disambiguator,191            owner: current_ast_owner,192            arena: tcx.hir_arena,193194            // HirId handling.195            bodies: Vec::new(),196            define_opaque: None,197            attrs: SortedMap::default(),198            children: LocalDefIdMap::default(),199            contract_ensures: None,200            current_hir_id_owner,201            // 0 corresponds to `owner` lowered as `current_hir_id_owner`,202            // and we never call `lower_node_id(owner)`.203            item_local_id_counter: hir::ItemLocalId::new(1),204            ident_and_label_to_local_id: Default::default(),205            #[cfg(debug_assertions)]206            node_id_to_local_id: Default::default(),207            trait_map: Default::default(),208            next_node_id: resolver.next_node_id,209            node_id_to_def_id: NodeMap::default(),210            partial_res_overrides: NodeMap::default(),211212            // Lowering state.213            try_block_scope: TryBlockScope::Function,214            loop_scope: None,215            is_in_loop_condition: false,216            is_in_dyn_type: false,217            coroutine_kind: None,218            task_context: None,219            current_item: None,220            impl_trait_defs: Vec::new(),221            impl_trait_bounds: Vec::new(),222            allow_contracts: [sym::contracts_internals].into(),223            allow_try_trait: [224                sym::try_trait_v2,225                sym::try_trait_v2_residual,226                sym::yeet_desugar_details,227            ]228            .into(),229            allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),230            allow_gen_future: if tcx.features().async_fn_track_caller() {231                [sym::gen_future, sym::closure_track_caller].into()232            } else {233                [sym::gen_future].into()234            },235            allow_for_await: [sym::async_gen_internals, sym::async_iterator].into(),236            allow_async_fn_traits: [sym::async_fn_traits].into(),237            allow_async_gen: [sym::async_gen_internals].into(),238            // FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller`239            // interact with `gen`/`async gen` blocks240            allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),241242            move_expr_bindings: Vec::new(),243            attribute_parser: AttributeParser::new(244                tcx.sess,245                tcx.features(),246                tcx.registered_tools(()),247                ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },248            ),249            delayed_lints: Vec::new(),250        }251    }252253    pub(crate) fn dcx(&self) -> DiagCtxtHandle<'hir> {254        self.tcx.dcx()255    }256}257258struct SpanLowerer {259    is_incremental: bool,260    def_id: LocalDefId,261}262263impl SpanLowerer {264    fn lower(&self, span: Span) -> Span {265        if self.is_incremental {266            span.with_parent(Some(self.def_id))267        } else {268            // Do not make spans relative when not using incremental compilation.269            span270        }271    }272}273274#[extension(trait ResolverAstLoweringExt<'tcx>)]275impl<'tcx> ResolverAstLowering<'tcx> {276    fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'tcx>) -> Option<Vec<usize>> {277        let ExprKind::Path(None, path) = &expr.kind else {278            return None;279        };280281        // Don't perform legacy const generics rewriting if the path already282        // has generic arguments.283        if path.segments.last().unwrap().args.is_some() {284            return None;285        }286287        // We do not need to look at `partial_res_overrides`. That map only contains overrides for288        // `self_param` locals. And here we are looking for the function definition that `expr`289        // resolves to.290        let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?;291292        // We only support cross-crate argument rewriting. Uses293        // within the same crate should be updated to use the new294        // const generics style.295        if def_id.is_local() {296            return None;297        }298299        // we can use parsed attrs here since for other crates they're already available300        find_attr!(301            tcx, def_id,302            RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes303        )304        .map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect())305    }306307    /// Obtain the list of lifetimes parameters to add to an item.308    ///309    /// Extra lifetime parameters should only be added in places that can appear310    /// as a `binder` in `LifetimeRes`.311    ///312    /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring313    /// should appear at the enclosing `PolyTraitRef`.314    fn extra_lifetime_params(&self, id: NodeId) -> &[(Ident, NodeId, MissingLifetimeKind)] {315        self.extra_lifetime_params_map.get(&id).map_or(&[], |v| &v[..])316    }317}318319/// How relaxed bounds `?Trait` should be treated.320///321/// Relaxed bounds should only be allowed in places where we later322/// (namely during HIR ty lowering) perform *sized elaboration*.323#[derive(Debug)]324enum RelaxedBoundPolicy<'a> {325    /// The `DefId` refers to the trait that is being relaxed.326    Allowed(&'a mut FxIndexMap<DefId, Span>),327    Forbidden(RelaxedBoundForbiddenReason),328}329impl RelaxedBoundPolicy<'_> {330    fn reborrow(&mut self) -> RelaxedBoundPolicy<'_> {331        match self {332            RelaxedBoundPolicy::Allowed(m) => RelaxedBoundPolicy::Allowed(m),333            RelaxedBoundPolicy::Forbidden(reason) => RelaxedBoundPolicy::Forbidden(*reason),334        }335    }336}337338#[derive(Clone, Copy, Debug)]339enum RelaxedBoundForbiddenReason {340    TraitObjectTy,341    SuperTrait,342    TraitAlias,343    AssocTyBounds,344    /// We do not allow where bounds doing relaxed bounds,345    /// except if it's for generic parameters of the current item.346    WhereBound,347}348349/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,350/// and if so, what meaning it has.351#[derive(Debug, Copy, Clone, PartialEq, Eq)]352enum ImplTraitContext {353    /// Treat `impl Trait` as shorthand for a new universal generic parameter.354    /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually355    /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.356    ///357    /// Newly generated parameters should be inserted into the given `Vec`.358    Universal,359360    /// Treat `impl Trait` as shorthand for a new opaque type.361    /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually362    /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.363    ///364    OpaqueTy { origin: hir::OpaqueTyOrigin<LocalDefId> },365366    /// Treat `impl Trait` as a "trait ascription", which is like a type367    /// variable but that also enforces that a set of trait goals hold.368    ///369    /// This is useful to guide inference for unnameable types.370    InBinding,371372    /// `impl Trait` is unstably accepted in this position.373    FeatureGated(ImplTraitPosition, Symbol),374    /// `impl Trait` is not accepted in this position.375    Disallowed(ImplTraitPosition),376}377378/// Position in which `impl Trait` is disallowed.379#[derive(Debug, Copy, Clone, PartialEq, Eq)]380enum ImplTraitPosition {381    Path,382    Variable,383    Trait,384    Bound,385    Generic,386    ExternFnParam,387    ClosureParam,388    PointerParam,389    FnTraitParam,390    ExternFnReturn,391    ClosureReturn,392    PointerReturn,393    FnTraitReturn,394    GenericDefault,395    ConstTy,396    StaticTy,397    AssocTy,398    FieldTy,399    Cast,400    ImplSelf,401    OffsetOf,402}403404impl std::fmt::Display for ImplTraitPosition {405    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {406        let name = match self {407            ImplTraitPosition::Path => "paths",408            ImplTraitPosition::Variable => "the type of variable bindings",409            ImplTraitPosition::Trait => "traits",410            ImplTraitPosition::Bound => "bounds",411            ImplTraitPosition::Generic => "generics",412            ImplTraitPosition::ExternFnParam => "`extern fn` parameters",413            ImplTraitPosition::ClosureParam => "closure parameters",414            ImplTraitPosition::PointerParam => "`fn` pointer parameters",415            ImplTraitPosition::FnTraitParam => "the parameters of `Fn` trait bounds",416            ImplTraitPosition::ExternFnReturn => "`extern fn` return types",417            ImplTraitPosition::ClosureReturn => "closure return types",418            ImplTraitPosition::PointerReturn => "`fn` pointer return types",419            ImplTraitPosition::FnTraitReturn => "the return type of `Fn` trait bounds",420            ImplTraitPosition::GenericDefault => "generic parameter defaults",421            ImplTraitPosition::ConstTy => "const types",422            ImplTraitPosition::StaticTy => "static types",423            ImplTraitPosition::AssocTy => "associated types",424            ImplTraitPosition::FieldTy => "field types",425            ImplTraitPosition::Cast => "cast expression types",426            ImplTraitPosition::ImplSelf => "impl headers",427            ImplTraitPosition::OffsetOf => "`offset_of!` parameters",428        };429430        write!(f, "{name}")431    }432}433434#[derive(Copy, Clone, Debug, PartialEq, Eq)]435enum FnDeclKind {436    Fn,437    Inherent,438    ExternFn,439    Closure,440    Pointer,441    Trait,442    Impl,443}444445#[derive(Copy, Clone, Debug)]446enum TryBlockScope {447    /// There isn't a `try` block, so a `?` will use `return`.448    Function,449    /// We're inside a `try { … }` block, so a `?` will block-break450    /// from that block using a type depending only on the argument.451    Homogeneous(HirId),452    /// We're inside a `try as _ { … }` block, so a `?` will block-break453    /// from that block using the type specified.454    Heterogeneous(HirId),455}456457fn index_ast<'tcx>(458    tcx: TyCtxt<'tcx>,459    (): (),460) -> IndexVec<LocalDefId, Steal<(Arc<ResolverAstLowering<'tcx>>, AstOwner)>> {461    // Queries that borrow `resolver_for_lowering`.462    tcx.ensure_done().output_filenames(());463    tcx.ensure_done().early_lint_checks(());464    tcx.ensure_done().get_lang_items(());465    tcx.ensure_done().debugger_visualizers(LOCAL_CRATE);466467    let (resolver, krate) = tcx.resolver_for_lowering();468    let mut resolver = resolver.steal();469    let mut krate = krate.steal();470471    let mut indexer = Indexer {472        owners: &resolver.owners,473        index: IndexVec::new(),474        next_node_id: resolver.next_node_id,475    };476    indexer.visit_crate(&mut krate);477    indexer.insert(CRATE_NODE_ID, AstOwner::Crate(Box::new(krate)));478    resolver.next_node_id = indexer.next_node_id;479480    let index = indexer.index;481    let resolver = Arc::new(resolver);482    let index = index.into_iter().map(|owner| Steal::new((Arc::clone(&resolver), owner))).collect();483    return index;484485    struct Indexer<'s, 'hir> {486        owners: &'s NodeMap<PerOwnerResolverData<'hir>>,487        index: IndexVec<LocalDefId, AstOwner>,488        next_node_id: NodeId,489    }490491    impl Indexer<'_, '_> {492        fn insert(&mut self, id: NodeId, node: AstOwner) {493            let def_id = self.owners[&id].def_id;494            self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner);495            self.index[def_id] = node;496        }497498        fn make_dummy<K>(499            &mut self,500            id: NodeId,501            span: Span,502            dummy: impl FnOnce(Box<MacCall>) -> K,503        ) -> Box<Item<K>> {504            use rustc_ast::token::Delimiter;505            use rustc_ast::tokenstream::{DelimSpan, TokenStream};506            use thin_vec::thin_vec;507508            Box::new(Item {509                attrs: AttrVec::default(),510                id,511                span,512                vis: Visibility { kind: VisibilityKind::Public, span, tokens: None },513                // Lacking a better choice, we replace the contents with a macro call.514                // Unexpanded macros should never reach lowering, so this is not confusing.515                kind: dummy(Box::new(MacCall {516                    path: Path { span, segments: thin_vec![], tokens: None },517                    args: Box::new(DelimArgs {518                        dspan: DelimSpan::from_single(span),519                        delim: Delimiter::Parenthesis,520                        tokens: TokenStream::new(Vec::new()),521                    }),522                })),523                tokens: None,524            })525        }526527        fn replace_with_dummy<K>(528            &mut self,529            item: &mut ast::Item<K>,530            dummy: impl FnOnce(Box<MacCall>) -> K,531            node: impl FnOnce(Box<Item<K>>) -> AstOwner,532        ) {533            let dummy = self.make_dummy(item.id, item.span, dummy);534            let item = mem::replace(item, *dummy);535            self.insert(item.id, node(Box::new(item)));536        }537538        #[tracing::instrument(level = "trace", skip(self))]539        fn visit_item_id_use_tree(540            &mut self,541            tree: &UseTree,542            parent: LocalDefId,543            items: &mut SmallVec<[Box<Item>; 1]>,544        ) {545            match tree.kind {546                UseTreeKind::Glob(_) | UseTreeKind::Simple(_) => {}547                UseTreeKind::Nested { items: ref nested_vec, span } => {548                    for &(ref nested, id) in nested_vec {549                        self.insert(id, AstOwner::NestedUseTree(parent));550                        items.push(self.make_dummy(id, span, ItemKind::MacCall));551552                        let def_id = self.owners[&id].def_id;553                        self.visit_item_id_use_tree(nested, def_id, items);554                    }555                }556            }557        }558    }559560    impl MutVisitor for Indexer<'_, '_> {561        fn visit_attribute(&mut self, _: &mut Attribute) {562            // We do not want to lower expressions that appear in attributes,563            // as they are not accessible to the rest of the HIR.564        }565566        fn flat_map_item(&mut self, mut item: Box<Item>) -> SmallVec<[Box<Item>; 1]> {567            let def_id = self.owners[&item.id].def_id;568            mut_visit::walk_item(self, &mut *item);569            let dummy = self.make_dummy(item.id, item.span, ItemKind::MacCall);570            let mut items = smallvec![dummy];571            if let ItemKind::Use(ref use_tree) = item.kind {572                self.visit_item_id_use_tree(use_tree, def_id, &mut items);573            }574            self.insert(item.id, AstOwner::Item(item));575            items576        }577578        fn flat_map_stmt(&mut self, stmt: Stmt) -> SmallVec<[Stmt; 1]> {579            let Stmt { id, span, kind } = stmt;580            let mut id = Some(id);581            mut_visit::walk_flat_map_stmt_kind(self, kind)582                .into_iter()583                .map(|kind| {584                    // Expanding the current statement is a nested `use` item,585                    // it is expanded into several flat `use` items.586                    // Create new NodeIds for the corresponding statements587                    // as two statements cannot have the same.588                    let id = id.take().unwrap_or_else(|| {589                        let next = self.next_node_id;590                        self.next_node_id.increment_by(1);591                        next592                    });593                    Stmt { id, kind, span }594                })595                .collect()596        }597598        fn visit_assoc_item(&mut self, item: &mut AssocItem, ctxt: visit::AssocCtxt) {599            mut_visit::walk_assoc_item(self, item, ctxt);600            match ctxt {601                visit::AssocCtxt::Trait => {602                    self.replace_with_dummy(item, AssocItemKind::MacCall, AstOwner::TraitItem)603                }604                visit::AssocCtxt::Impl { .. } => {605                    self.replace_with_dummy(item, AssocItemKind::MacCall, AstOwner::ImplItem)606                }607            }608        }609610        fn visit_foreign_item(&mut self, item: &mut ForeignItem) {611            mut_visit::walk_item(self, item);612            self.replace_with_dummy(item, ForeignItemKind::MacCall, AstOwner::ForeignItem);613        }614    }615}616617#[instrument(level = "trace", skip(tcx))]618fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> {619    // Queries that borrow `resolver_for_lowering`.620    tcx.ensure_done().output_filenames(());621    tcx.ensure_done().early_lint_checks(());622    tcx.ensure_done().debugger_visualizers(LOCAL_CRATE);623    tcx.ensure_done().get_lang_items(());624    let ast_index = tcx.index_ast(());625    let resolver_and_node = ast_index.get(def_id).map(Steal::steal);626627    let fallback_to_ancestor = |parent_id| {628        // The item did not exist in the AST, it was created while lowering another item.629        // `parent_id` may be different from the direct parent of `def_id`,630        // for instance use-trees are lowered by the first sibling.631        let mut parent_info = tcx.lower_to_hir(parent_id);632        if let hir::MaybeOwner::NonOwner(hir_id) = parent_info {633            // `parent_id` could also not be a owner either.634            // For instance if `def_id` is an enum variant field,635            // the direct parent is the enum variant.636            // In that case `hir_id.owner` point to the actual HIR owner637            // and skips all non-owner parents, so fetch the HIR associated to it.638            parent_info = tcx.lower_to_hir(hir_id.owner);639        }640641        let parent_info = parent_info.unwrap();642        *parent_info.children.get(&def_id).unwrap_or_else(|| {643            panic!(644                "{:?} does not appear in children of {:?}",645                def_id,646                parent_info.nodes.node().def_id()647            )648        })649    };650651    let Some((resolver, node)) = resolver_and_node else {652        // `ast_index` does not contain all definitions, only up-to the highest653        // `LocalDefId` which has a non-trivial `AstOwner`. Gracefully handle654        // other definitions, in particular those nested inside this highest definition.655        return fallback_to_ancestor(tcx.local_parent(def_id));656    };657658    let mut item_lowerer = item::ItemLowerer { tcx, resolver: &*resolver };659660    let item = match &node {661        // The item existed in the AST.662        AstOwner::Crate(c) => item_lowerer.lower_crate(&c),663        AstOwner::Item(item) => item_lowerer.lower_item(&item),664        AstOwner::TraitItem(item) => item_lowerer.lower_trait_item(&item),665        AstOwner::ImplItem(item) => item_lowerer.lower_impl_item(&item),666        AstOwner::ForeignItem(item) => item_lowerer.lower_foreign_item(&item),667        AstOwner::NestedUseTree(owner_id) => fallback_to_ancestor(*owner_id),668        // The item existed in the AST, but is not a HIR owner.669        // Fetch the correct information from its parent.670        AstOwner::NonOwner => fallback_to_ancestor(tcx.local_parent(def_id)),671    };672673    tcx.sess.time("drop_ast", || mem::drop(node));674675    item676}677678#[derive(Copy, Clone, PartialEq, Debug)]679enum ParamMode {680    /// Any path in a type context.681    Explicit,682    /// The `module::Type` in `module::Type::method` in an expression.683    Optional,684}685686#[derive(Copy, Clone, Debug)]687enum AllowReturnTypeNotation {688    /// Only in types, since RTN is denied later during HIR lowering.689    Yes,690    /// All other positions (path expr, method, use tree).691    No,692}693694enum GenericArgsMode {695    /// Allow paren sugar, don't allow RTN.696    ParenSugar,697    /// Allow RTN, don't allow paren sugar.698    ReturnTypeNotation,699    // Error if parenthesized generics or RTN are encountered.700    Err,701    /// Silence errors when lowering generics. Only used with `Res::Err`.702    Silence,703}704705impl<'hir> LoweringContext<'_, 'hir> {706    fn create_def(707        &mut self,708        node_id: NodeId,709        name: Option<Symbol>,710        def_kind: DefKind,711        span: Span,712    ) -> LocalDefId {713        let parent = self.current_hir_id_owner.def_id;714        assert_ne!(node_id, ast::DUMMY_NODE_ID);715        assert!(716            self.opt_local_def_id(node_id).is_none(),717            "adding a def'n for node-id {:?} and def kind {:?} but a previous def'n exists: {:?}",718            node_id,719            def_kind,720            self.tcx.hir_def_key(self.local_def_id(node_id)),721        );722723        let def_id = self724            .tcx725            .at(span)726            .create_def(parent, name, def_kind, None, &mut self.current_disambiguator)727            .def_id();728729        debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);730        self.node_id_to_def_id.insert(node_id, def_id);731732        def_id733    }734735    fn next_node_id(&mut self) -> NodeId {736        let start = self.next_node_id;737        let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");738        self.next_node_id = NodeId::from_u32(next);739        start740    }741742    /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name743    /// resolver (if any).744    #[instrument(level = "trace", skip(self), ret)]745    fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {746        self.node_id_to_def_id747            .get(&node)748            .or_else(|| self.owner.node_id_to_def_id.get(&node))749            .copied()750    }751752    fn local_def_id(&self, node: NodeId) -> LocalDefId {753        self.opt_local_def_id(node).unwrap_or_else(|| {754            self.resolver.owners.items().any(|(id, items)| {755                items.node_id_to_def_id.items().any(|(node_id, def_id)| {756                    if *node_id == node {757                        let actual_owner = items.node_id_to_def_id.get(id);758                        panic!("{def_id:?} ({node_id}) was found in {actual_owner:?} ({id})",)759                    }760                    false761                })762            });763            panic!("no entry for node id: `{node:?}`");764        })765    }766767    fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {768        match self.partial_res_overrides.get(&id) {769            Some(self_param_id) => Some(PartialRes::new(Res::Local(*self_param_id))),770            None => self.resolver.partial_res_map.get(&id).copied(),771        }772    }773774    /// Given the id of an owner node in the AST, returns the corresponding `OwnerId`.775    fn owner_id(&self, node: NodeId) -> hir::OwnerId {776        hir::OwnerId { def_id: self.resolver.owners[&node].def_id }777    }778779    /// Freshen the `LoweringContext` and ready it to lower a nested item.780    /// The lowered item is registered into `self.children`.781    ///782    /// This function sets up `HirId` lowering infrastructure,783    /// and stashes the shared mutable state to avoid pollution by the closure.784    #[instrument(level = "debug", skip(self, f))]785    fn with_hir_id_owner(786        &mut self,787        owner: NodeId,788        f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,789    ) {790        let owner_id = self.owner_id(owner);791        let def_id = owner_id.def_id;792793        let new_disambig = self794            .resolver795            .disambiguators796            .get(&def_id)797            .map(|s| s.steal())798            .unwrap_or_else(|| PerParentDisambiguatorState::new(def_id));799800        let disambiguator = mem::replace(&mut self.current_disambiguator, new_disambig);801        let current_ast_owner = mem::replace(&mut self.owner, &self.resolver.owners[&owner]);802        let current_attrs = mem::take(&mut self.attrs);803        let current_bodies = mem::take(&mut self.bodies);804        let current_define_opaque = mem::take(&mut self.define_opaque);805        let current_ident_and_label_to_local_id = mem::take(&mut self.ident_and_label_to_local_id);806807        #[cfg(debug_assertions)]808        let current_node_id_to_local_id = mem::take(&mut self.node_id_to_local_id);809        let current_trait_map = mem::take(&mut self.trait_map);810        let current_owner = mem::replace(&mut self.current_hir_id_owner, owner_id);811        let current_local_counter =812            mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));813        let current_impl_trait_defs = mem::take(&mut self.impl_trait_defs);814        let current_impl_trait_bounds = mem::take(&mut self.impl_trait_bounds);815        let current_delayed_lints = mem::take(&mut self.delayed_lints);816        let current_children = mem::take(&mut self.children);817818        // Do not reset `next_node_id` and `node_id_to_def_id`:819        // we want `f` to be able to refer to the `LocalDefId`s that the caller created.820        // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.821822        // Always allocate the first `HirId` for the owner itself.823        #[cfg(debug_assertions)]824        {825            let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO);826            debug_assert_eq!(_old, None);827        }828829        let item = f(self);830        assert_eq!(owner_id, item.def_id());831        // `f` should have consumed all the elements in these vectors when constructing `item`.832        assert!(self.impl_trait_defs.is_empty());833        assert!(self.impl_trait_bounds.is_empty());834        let info = self.make_owner_info(item);835836        self.current_disambiguator = disambiguator;837        self.owner = current_ast_owner;838        self.attrs = current_attrs;839        self.bodies = current_bodies;840        self.define_opaque = current_define_opaque;841        self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;842843        #[cfg(debug_assertions)]844        {845            self.node_id_to_local_id = current_node_id_to_local_id;846        }847        self.trait_map = current_trait_map;848        self.current_hir_id_owner = current_owner;849        self.item_local_id_counter = current_local_counter;850        self.impl_trait_defs = current_impl_trait_defs;851        self.impl_trait_bounds = current_impl_trait_bounds;852        self.delayed_lints = current_delayed_lints;853        self.children = current_children;854        self.children.extend_unord(info.children.items().map(|(&def_id, &info)| (def_id, info)));855856        debug_assert!(!self.children.contains_key(&owner_id.def_id));857        self.children.insert(owner_id.def_id, hir::MaybeOwner::Owner(info));858    }859860    fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {861        let attrs = mem::take(&mut self.attrs);862        let mut bodies = mem::take(&mut self.bodies);863        let define_opaque = mem::take(&mut self.define_opaque);864        let trait_map = mem::take(&mut self.trait_map);865        let delayed_lints = Steal::new(mem::take(&mut self.delayed_lints).into_boxed_slice());866        let children = mem::take(&mut self.children);867868        #[cfg(debug_assertions)]869        for (id, attrs) in attrs.iter() {870            // Verify that we do not store empty slices in the map.871            if attrs.is_empty() {872                panic!("Stored empty attributes for {:?}", id);873            }874        }875876        bodies.sort_by_key(|(k, _)| *k);877        let bodies = SortedMap::from_presorted_elements(bodies);878879        // Don't hash unless necessary, because it's expensive.880        let rustc_middle::hir::Hashes { bodies_hash, attrs_hash } =881            self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque);882        let num_nodes = self.item_local_id_counter.as_usize();883        let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);884        let nodes = hir::OwnerNodes { opt_hash: bodies_hash, nodes, bodies };885        let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };886887        let opt_hash = self.tcx.needs_hir_hash().then(|| {888            self.tcx.with_stable_hashing_context(|mut hcx| {889                let mut stable_hasher = StableHasher::new();890                bodies_hash.unwrap().stable_hash(&mut hcx, &mut stable_hasher);891                attrs_hash.unwrap().stable_hash(&mut hcx, &mut stable_hasher);892                // Do not hash delayed_lints.893                parenting.stable_hash(&mut hcx, &mut stable_hasher);894                trait_map.stable_hash(&mut hcx, &mut stable_hasher);895                children.stable_hash(&mut hcx, &mut stable_hasher);896                stable_hasher.finish()897            })898        });899900        self.arena.alloc(hir::OwnerInfo {901            opt_hash,902            nodes,903            parenting,904            attrs,905            trait_map,906            delayed_lints,907            children,908        })909    }910911    /// This method allocates a new `HirId` for the given `NodeId`.912    /// Take care not to call this method if the resulting `HirId` is then not913    /// actually used in the HIR, as that would trigger an assertion in the914    /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped915    /// properly. Calling the method twice with the same `NodeId` is also forbidden.916    #[instrument(level = "debug", skip(self), ret)]917    fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId {918        assert_ne!(ast_node_id, DUMMY_NODE_ID);919920        let owner = self.current_hir_id_owner;921        let local_id = self.item_local_id_counter;922        assert_ne!(local_id, hir::ItemLocalId::ZERO);923        self.item_local_id_counter.increment_by(1);924        let hir_id = HirId { owner, local_id };925926        if let Some(def_id) = self.opt_local_def_id(ast_node_id) {927            self.children.insert(def_id, hir::MaybeOwner::NonOwner(hir_id));928        }929930        if let Some(traits) = self.owner.trait_map.get(&ast_node_id) {931            self.trait_map.insert(hir_id.local_id, *traits);932        }933934        // Check whether the same `NodeId` is lowered more than once.935        #[cfg(debug_assertions)]936        {937            let old = self.node_id_to_local_id.insert(ast_node_id, local_id);938            assert_eq!(old, None);939        }940941        hir_id942    }943944    /// Generate a new `HirId` without a backing `NodeId`.945    #[instrument(level = "debug", skip(self), ret)]946    fn next_id(&mut self) -> HirId {947        let owner = self.current_hir_id_owner;948        let local_id = self.item_local_id_counter;949        assert_ne!(local_id, hir::ItemLocalId::ZERO);950        self.item_local_id_counter.increment_by(1);951        HirId { owner, local_id }952    }953954    #[instrument(level = "trace", skip(self))]955    fn lower_res(&mut self, res: Res<NodeId>) -> Res {956        let res: Result<Res, ()> = res.apply_id(|id| {957            let owner = self.current_hir_id_owner;958            let local_id = self.ident_and_label_to_local_id.get(&id).copied().ok_or(())?;959            Ok(HirId { owner, local_id })960        });961        trace!(?res);962963        // We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.964        // This can happen when trying to lower the return type `x` in erroneous code like965        //   async fn foo(x: u8) -> x {}966        // In that case, `x` is lowered as a function parameter, and the return type is lowered as967        // an opaque type as a synthesized HIR owner.968        res.unwrap_or(Res::Err)969    }970971    fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {972        self.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())973    }974975    fn lower_import_res(&mut self, id: NodeId, span: Span) -> PerNS<Option<Res>> {976        debug_assert_eq!(id, self.owner.id);977        let per_ns = self.owner.import_res.map(|res| res.map(|res| self.lower_res(res)));978        if per_ns.is_empty() {979            // Propagate the error to all namespaces, just to be sure.980            self.dcx().span_delayed_bug(span, "no resolution for an import");981            let err = Some(Res::Err);982            return PerNS { type_ns: err, value_ns: err, macro_ns: err };983        }984        per_ns985    }986987    fn make_lang_item_qpath(988        &mut self,989        lang_item: hir::LangItem,990        span: Span,991        args: Option<&'hir hir::GenericArgs<'hir>>,992    ) -> hir::QPath<'hir> {993        hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))994    }995996    fn make_lang_item_path(997        &mut self,998        lang_item: hir::LangItem,999        span: Span,1000        args: Option<&'hir hir::GenericArgs<'hir>>,1001    ) -> &'hir hir::Path<'hir> {1002        let def_id = self.tcx.require_lang_item(lang_item, span);1003        let def_kind = self.tcx.def_kind(def_id);1004        let res = Res::Def(def_kind, def_id);1005        self.arena.alloc(hir::Path {1006            span,1007            res,1008            segments: self.arena.alloc_from_iter([hir::PathSegment {1009                ident: Ident::new(lang_item.name(), span),1010                hir_id: self.next_id(),1011                res,1012                args,1013                infer_args: args.is_none(),1014            }]),1015        })1016    }10171018    /// Reuses the span but adds information like the kind of the desugaring and features that are1019    /// allowed inside this span.1020    fn mark_span_with_reason(1021        &self,1022        reason: DesugaringKind,1023        span: Span,1024        allow_internal_unstable: Option<Arc<[Symbol]>>,1025    ) -> Span {1026        self.tcx.with_stable_hashing_context(|hcx| {1027            span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx)1028        })1029    }10301031    fn span_lowerer(&self) -> SpanLowerer {1032        SpanLowerer {1033            is_incremental: self.tcx.sess.opts.incremental.is_some(),1034            def_id: self.current_hir_id_owner.def_id,1035        }1036    }10371038    /// Intercept all spans entering HIR.1039    /// Mark a span as relative to the current owning item.1040    fn lower_span(&self, span: Span) -> Span {1041        self.span_lowerer().lower(span)1042    }10431044    fn lower_ident(&self, ident: Ident) -> Ident {1045        Ident::new(ident.name, self.lower_span(ident.span))1046    }10471048    /// Converts a lifetime into a new generic parameter.1049    #[instrument(level = "debug", skip(self))]1050    fn lifetime_res_to_generic_param(1051        &mut self,1052        ident: Ident,1053        node_id: NodeId,1054        kind: MissingLifetimeKind,1055        source: hir::GenericParamSource,1056    ) -> hir::GenericParam<'hir> {1057        // Late resolution delegates to us the creation of the `LocalDefId`.1058        let _def_id = self.create_def(1059            node_id,1060            Some(kw::UnderscoreLifetime),1061            DefKind::LifetimeParam,1062            ident.span,1063        );1064        debug!(?_def_id);10651066        let hir_id = self.lower_node_id(node_id);1067        let def_id = self.local_def_id(node_id);1068        hir::GenericParam {1069            hir_id,1070            def_id,1071            name: hir::ParamName::Fresh,1072            span: self.lower_span(ident.span),1073            pure_wrt_drop: false,1074            kind: hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided(kind) },1075            colon_span: None,1076            source,1077        }1078    }10791080    /// Lowers a lifetime binder that defines `generic_params`, returning the corresponding HIR1081    /// nodes. The returned list includes any "extra" lifetime parameters that were added by the1082    /// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id1083    /// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime1084    /// parameters will be successful.1085    #[instrument(level = "debug", skip(self), ret)]1086    #[inline]1087    fn lower_lifetime_binder(1088        &mut self,1089        binder: NodeId,1090        generic_params: &[GenericParam],1091    ) -> &'hir [hir::GenericParam<'hir>] {1092        // Start by creating params for extra lifetimes params, as this creates the definitions1093        // that may be referred to by the AST inside `generic_params`.1094        let extra_lifetimes = self.resolver.extra_lifetime_params(binder);1095        debug!(?extra_lifetimes);1096        let extra_lifetimes: Vec<_> = extra_lifetimes1097            .iter()1098            .map(|&(ident, node_id, res)| {1099                self.lifetime_res_to_generic_param(1100                    ident,1101                    node_id,1102                    res,1103                    hir::GenericParamSource::Binder,1104                )1105            })1106            .collect();1107        let arena = self.arena;1108        let explicit_generic_params =1109            self.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder);1110        arena.alloc_from_iter(explicit_generic_params.chain(extra_lifetimes.into_iter()))1111    }11121113    fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {1114        let was_in_dyn_type = self.is_in_dyn_type;1115        self.is_in_dyn_type = in_scope;11161117        let result = f(self);11181119        self.is_in_dyn_type = was_in_dyn_type;11201121        result1122    }11231124    fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {1125        let current_item = self.current_item;1126        self.current_item = Some(scope_span);11271128        let was_in_loop_condition = self.is_in_loop_condition;1129        self.is_in_loop_condition = false;11301131        let old_contract = self.contract_ensures.take();11321133        let try_block_scope = mem::replace(&mut self.try_block_scope, TryBlockScope::Function);1134        let loop_scope = self.loop_scope.take();1135        let ret = f(self);1136        self.try_block_scope = try_block_scope;1137        self.loop_scope = loop_scope;11381139        self.contract_ensures = old_contract;11401141        self.is_in_loop_condition = was_in_loop_condition;11421143        self.current_item = current_item;11441145        ret1146    }11471148    fn lower_attrs(1149        &mut self,1150        id: HirId,1151        attrs: &[Attribute],1152        target_span: Span,1153        target: Target,1154    ) -> &'hir [hir::Attribute] {1155        self.lower_attrs_with_extra(id, attrs, target_span, target, &[])1156    }11571158    fn lower_attrs_with_extra(1159        &mut self,1160        id: HirId,1161        attrs: &[Attribute],1162        target_span: Span,1163        target: Target,1164        extra_hir_attributes: &[hir::Attribute],1165    ) -> &'hir [hir::Attribute] {1166        if attrs.is_empty() && extra_hir_attributes.is_empty() {1167            &[]1168        } else {1169            let mut lowered_attrs =1170                self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target);1171            lowered_attrs.extend(extra_hir_attributes.iter().cloned());11721173            assert_eq!(id.owner, self.current_hir_id_owner);1174            let ret = self.arena.alloc_from_iter(lowered_attrs);11751176            // this is possible if an item contained syntactical attribute,1177            // but none of them parse successfully or all of them were ignored1178            // for not being built-in attributes at all. They could be remaining1179            // unexpanded attributes used as markers in proc-macro derives for example.1180            // This will have emitted some diagnostics for the misparse, but will then1181            // not emit the attribute making the list empty.1182            if ret.is_empty() {1183                &[]1184            } else {1185                self.attrs.insert(id.local_id, ret);1186                ret1187            }1188        }1189    }11901191    fn lower_attrs_vec(1192        &mut self,1193        attrs: &[Attribute],1194        target_span: Span,1195        target_hir_id: HirId,1196        target: Target,1197    ) -> Vec<hir::Attribute> {1198        let l = self.span_lowerer();1199        self.attribute_parser.parse_attribute_list(1200            attrs,1201            target_span,1202            target,1203            OmitDoc::Lower,1204            |s| l.lower(s),1205            |lint_id, span, kind| {1206                self.delayed_lints.push(DelayedLint {1207                    lint_id,1208                    id: target_hir_id,1209                    span,1210                    callback: Box::new(move |dcx, level, sess: &dyn std::any::Any| {1211                        let sess = sess1212                            .downcast_ref::<rustc_session::Session>()1213                            .expect("expected `Session`");1214                        (kind.0)(dcx, level, sess)1215                    }),1216                });1217            },1218        )1219    }12201221    fn alias_attrs(&mut self, id: HirId, target_id: HirId) {1222        assert_eq!(id.owner, self.current_hir_id_owner);1223        assert_eq!(target_id.owner, self.current_hir_id_owner);1224        if let Some(&a) = self.attrs.get(&target_id.local_id) {1225            assert!(!a.is_empty());1226            self.attrs.insert(id.local_id, a);1227        }1228    }12291230    fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {1231        args.clone()1232    }12331234    /// Lower an associated item constraint.1235    #[instrument(level = "debug", skip_all)]1236    fn lower_assoc_item_constraint(1237        &mut self,1238        constraint: &AssocItemConstraint,1239        itctx: ImplTraitContext,1240    ) -> hir::AssocItemConstraint<'hir> {1241        debug!(?constraint, ?itctx);1242        // Lower the generic arguments for the associated item.1243        let gen_args = if let Some(gen_args) = &constraint.gen_args {1244            let gen_args_ctor = match gen_args {1245                GenericArgs::AngleBracketed(data) => {1246                    self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).01247                }1248                GenericArgs::Parenthesized(data) => {1249                    if let Some(first_char) = constraint.ident.as_str().chars().next()1250                        && first_char.is_ascii_lowercase()1251                    {1252                        let err = match (&data.inputs[..], &data.output) {1253                            ([_, ..], FnRetTy::Default(_)) => {1254                                diagnostics::BadReturnTypeNotation::Inputs {1255                                    span: data.inputs_span,1256                                }1257                            }1258                            ([], FnRetTy::Default(_)) => {1259                                diagnostics::BadReturnTypeNotation::NeedsDots {1260                                    span: data.inputs_span,1261                                }1262                            }1263                            // The case `T: Trait<method(..) -> Ret>` is handled in the parser.1264                            (_, FnRetTy::Ty(ty)) => {1265                                let span = data.inputs_span.shrink_to_hi().to(ty.span);1266                                diagnostics::BadReturnTypeNotation::Output {1267                                    span,1268                                    suggestion: diagnostics::RTNSuggestion {1269                                        output: span,1270                                        input: data.inputs_span,1271                                    },1272                                }1273                            }1274                        };1275                        let mut err = self.dcx().create_err(err);1276                        if !self.tcx.features().return_type_notation()1277                            && self.tcx.sess.is_nightly_build()1278                        {1279                            add_feature_diagnostics(1280                                &mut err,1281                                &self.tcx.sess,1282                                sym::return_type_notation,1283                            );1284                        }1285                        err.emit();1286                        GenericArgsCtor {1287                            args: Default::default(),1288                            constraints: &[],1289                            parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,1290                            span: data.span,1291                        }1292                    } else {1293                        self.emit_bad_parenthesized_trait_in_assoc_ty(data);1294                        self.lower_angle_bracketed_parameter_data(1295                            &data.as_angle_bracketed_args(),1296                            ParamMode::Explicit,1297                            itctx,1298                        )1299                        .01300                    }1301                }1302                GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {1303                    args: Default::default(),1304                    constraints: &[],1305                    parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,1306                    span: *span,1307                },1308            };1309            gen_args_ctor.into_generic_args(self)1310        } else {1311            hir::GenericArgs::NONE1312        };1313        let kind = match &constraint.kind {1314            AssocItemConstraintKind::Equality { term } => {1315                let term = match term {1316                    Term::Ty(ty) => self.lower_ty_alloc(ty, itctx).into(),1317                    Term::Const(c) => self.lower_anon_const_to_const_arg_and_alloc(c).into(),1318                };1319                hir::AssocItemConstraintKind::Equality { term }1320            }1321            AssocItemConstraintKind::Bound { bounds } => {1322                // Disallow ATB in dyn types1323                if self.is_in_dyn_type {1324                    let suggestion = match itctx {1325                        ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {1326                            let bound_end_span = constraint1327                                .gen_args1328                                .as_ref()1329                                .map_or(constraint.ident.span, |args| args.span());1330                            if bound_end_span.eq_ctxt(constraint.span) {1331                                Some(self.tcx.sess.source_map().next_point(bound_end_span))1332                            } else {1333                                None1334                            }1335                        }1336                        _ => None,1337                    };13381339                    let guar = self.dcx().emit_err(diagnostics::MisplacedAssocTyBinding {1340                        span: constraint.span,1341                        suggestion,1342                    });1343                    let err_ty =1344                        &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));1345                    hir::AssocItemConstraintKind::Equality { term: err_ty.into() }1346                } else {1347                    let bounds = self.lower_param_bounds(1348                        bounds,1349                        RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::AssocTyBounds),1350                        itctx,1351                    );1352                    hir::AssocItemConstraintKind::Bound { bounds }1353                }1354            }1355        };13561357        hir::AssocItemConstraint {1358            hir_id: self.lower_node_id(constraint.id),1359            ident: self.lower_ident(constraint.ident),1360            gen_args,1361            kind,1362            span: self.lower_span(constraint.span),1363        }1364    }13651366    fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {1367        // Suggest removing empty parentheses: "Trait()" -> "Trait"1368        let sub = if data.inputs.is_empty() {1369            let parentheses_span =1370                data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());1371            AssocTyParenthesesSub::Empty { parentheses_span }1372        }1373        // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`1374        else {1375            // Start of parameters to the 1st argument1376            let open_param = data.inputs_span.shrink_to_lo().to(data1377                .inputs1378                .first()1379                .unwrap()1380                .span1381                .shrink_to_lo());1382            // End of last argument to end of parameters1383            let close_param =1384                data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());1385            AssocTyParenthesesSub::NotEmpty { open_param, close_param }1386        };1387        self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });1388    }13891390    #[instrument(level = "debug", skip(self))]1391    fn lower_generic_arg(1392        &mut self,1393        arg: &ast::GenericArg,1394        itctx: ImplTraitContext,1395    ) -> hir::GenericArg<'hir> {1396        match arg {1397            ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(1398                lt,1399                LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },1400                lt.ident.into(),1401            )),1402            ast::GenericArg::Type(ty) => {1403                // We cannot just match on `TyKind::Infer` as `(_)` is represented as1404                // `TyKind::Paren(TyKind::Infer)` and should also be lowered to `GenericArg::Infer`1405                if ty.is_maybe_parenthesised_infer() {1406                    return GenericArg::Infer(hir::InferArg {1407                        hir_id: self.lower_node_id(ty.id),1408                        span: self.lower_span(ty.span),1409                    });1410                }14111412                match &ty.kind {1413                    // We parse const arguments as path types as we cannot distinguish them during1414                    // parsing. We try to resolve that ambiguity by attempting resolution in both the1415                    // type and value namespaces. If we resolved the path in the value namespace, we1416                    // transform it into a generic const argument.1417                    //1418                    // FIXME: Should we be handling `(PATH_TO_CONST)`?1419                    TyKind::Path(None, path) => {1420                        if let Some(res) = self1421                            .get_partial_res(ty.id)1422                            .and_then(|partial_res| partial_res.full_res())1423                        {1424                            if !res.matches_ns(Namespace::TypeNS)1425                                && path.is_potential_trivial_const_arg()1426                            {1427                                debug!(1428                                    "lower_generic_arg: Lowering type argument as const argument: {:?}",1429                                    ty,1430                                );14311432                                let ct =1433                                    self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);1434                                return GenericArg::Const(ct.try_as_ambig_ct().unwrap());1435                            }1436                        }1437                    }1438                    _ => {}1439                }1440                GenericArg::Type(self.lower_ty_alloc(ty, itctx).try_as_ambig_ty().unwrap())1441            }1442            ast::GenericArg::Const(ct) => {1443                let ct = self.lower_anon_const_to_const_arg_and_alloc(ct);1444                match ct.try_as_ambig_ct() {1445                    Some(ct) => GenericArg::Const(ct),1446                    None => GenericArg::Infer(hir::InferArg { hir_id: ct.hir_id, span: ct.span }),1447                }1448            }1449        }1450    }14511452    #[instrument(level = "debug", skip(self))]1453    fn lower_ty_alloc(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {1454        self.arena.alloc(self.lower_ty(t, itctx))1455    }14561457    fn lower_path_ty(1458        &mut self,1459        t: &Ty,1460        qself: &Option<Box<QSelf>>,1461        path: &Path,1462        param_mode: ParamMode,1463        itctx: ImplTraitContext,1464    ) -> hir::Ty<'hir> {1465        // Check whether we should interpret this as a bare trait object.1466        // This check mirrors the one in late resolution. We only introduce this special case in1467        // the rare occurrence we need to lower `Fresh` anonymous lifetimes.1468        // The other cases when a qpath should be opportunistically made a trait object are handled1469        // by `ty_path`.1470        if qself.is_none()1471            && let Some(partial_res) = self.get_partial_res(t.id)1472            && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()1473        {1474            let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {1475                let bound = this.lower_poly_trait_ref(1476                    &PolyTraitRef {1477                        bound_generic_params: ThinVec::new(),1478                        modifiers: TraitBoundModifiers::NONE,1479                        trait_ref: TraitRef { path: path.clone(), ref_id: t.id },1480                        span: t.span,1481                        parens: ast::Parens::No,1482                    },1483                    RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitObjectTy),1484                    itctx,1485                );1486                let bounds = this.arena.alloc_from_iter([bound]);1487                let lifetime_bound = this.elided_dyn_bound(t.span);1488                (bounds, lifetime_bound)1489            });1490            let kind = hir::TyKind::TraitObject(1491                bounds,1492                TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),1493            );1494            return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };1495        }14961497        let id = self.lower_node_id(t.id);1498        let qpath = self.lower_qpath(1499            t.id,1500            qself,1501            path,1502            param_mode,1503            AllowReturnTypeNotation::Yes,1504            itctx,1505            None,1506        );1507        self.ty_path(id, t.span, qpath)1508    }15091510    fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {1511        hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }1512    }15131514    fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {1515        self.ty(span, hir::TyKind::Tup(tys))1516    }15171518    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {1519        let kind = match &t.kind {1520            TyKind::Infer => hir::TyKind::Infer(()),1521            TyKind::Err(guar) => hir::TyKind::Err(*guar),1522            TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty_alloc(ty, itctx)),1523            TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),1524            TyKind::Ref(region, mt) => {1525                let lifetime = self.lower_ty_direct_lifetime(t, *region);1526                hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))1527            }1528            TyKind::PinnedRef(region, mt) => {1529                let lifetime = self.lower_ty_direct_lifetime(t, *region);1530                let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));1531                let span = self.lower_span(t.span);1532                let arg = hir::Ty { kind, span, hir_id: self.next_id() };1533                let args = self.arena.alloc(hir::GenericArgs {1534                    args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),1535                    constraints: &[],1536                    parenthesized: hir::GenericArgsParentheses::No,1537                    span_ext: span,1538                });1539                let path = self.make_lang_item_qpath(hir::LangItem::Pin, span, Some(args));1540                hir::TyKind::Path(path)1541            }1542            TyKind::FnPtr(f) => {1543                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);1544                hir::TyKind::FnPtr(self.arena.alloc(hir::FnPtrTy {1545                    generic_params,1546                    safety: self.lower_safety(f.safety, hir::Safety::Safe),1547                    abi: self.lower_extern(f.ext),1548                    decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),1549                    param_idents: self.lower_fn_params_to_idents(&f.decl),1550                }))1551            }1552            TyKind::UnsafeBinder(f) => {1553                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);1554                hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {1555                    generic_params,1556                    inner_ty: self.lower_ty_alloc(&f.inner_ty, itctx),1557                }))1558            }1559            TyKind::Never => hir::TyKind::Never,1560            TyKind::Tup(tys) => hir::TyKind::Tup(1561                self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty(ty, itctx))),1562            ),1563            TyKind::Paren(ty) => {1564                return self.lower_ty(ty, itctx);1565            }1566            TyKind::Path(qself, path) => {1567                return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);1568            }1569            TyKind::ImplicitSelf => {1570                let hir_id = self.next_id();1571                let res = self.expect_full_res(t.id);1572                let res = self.lower_res(res);1573                hir::TyKind::Path(hir::QPath::Resolved(1574                    None,1575                    self.arena.alloc(hir::Path {1576                        res,1577                        segments: arena_vec![self; hir::PathSegment::new(1578                            Ident::with_dummy_span(kw::SelfUpper),1579                            hir_id,1580                            res1581                        )],1582                        span: self.lower_span(t.span),1583                    }),1584                ))1585            }1586            TyKind::Array(ty, length) => hir::TyKind::Array(1587                self.lower_ty_alloc(ty, itctx),1588                self.lower_array_length_to_const_arg(length),1589            ),1590            TyKind::TraitObject(bounds, kind) => {1591                let mut lifetime_bound = None;1592                let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {1593                    let bounds =1594                        this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {1595                            // We can safely ignore constness here since AST validation1596                            // takes care of rejecting invalid modifier combinations and1597                            // const trait bounds in trait object types.1598                            GenericBound::Trait(ty) => {1599                                let trait_ref = this.lower_poly_trait_ref(1600                                    ty,1601                                    RelaxedBoundPolicy::Forbidden(1602                                        RelaxedBoundForbiddenReason::TraitObjectTy,1603                                    ),1604                                    itctx,1605                                );1606                                Some(trait_ref)1607                            }1608                            GenericBound::Outlives(lifetime) => {1609                                if lifetime_bound.is_none() {1610                                    lifetime_bound = Some(this.lower_lifetime(1611                                        lifetime,1612                                        LifetimeSource::Other,1613                                        lifetime.ident.into(),1614                                    ));1615                                }1616                                None1617                            }1618                            // Ignore `use` syntax since that is not valid in objects.1619                            GenericBound::Use(_, span) => {1620                                this.dcx()1621                                    .span_delayed_bug(*span, "use<> not allowed in dyn types");1622                                None1623                            }1624                        }));1625                    let lifetime_bound =1626                        lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));1627                    (bounds, lifetime_bound)1628                });1629                hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))1630            }1631            TyKind::ImplTrait(def_node_id, bounds) => {1632                let span = t.span;1633                match itctx {1634                    ImplTraitContext::OpaqueTy { origin } => {1635                        self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)1636                    }1637                    ImplTraitContext::Universal => {1638                        if let Some(span) = bounds.iter().find_map(|bound| match *bound {1639                            ast::GenericBound::Use(_, span) => Some(span),1640                            _ => None,1641                        }) {1642                            self.tcx.dcx().emit_err(diagnostics::NoPreciseCapturesOnApit { span });1643                        }16441645                        let def_id = self.local_def_id(*def_node_id);1646                        let name = self.tcx.item_name(def_id.to_def_id());1647                        let ident = Ident::new(name, span);1648                        let (param, bounds, path) = self.lower_universal_param_and_bounds(1649                            *def_node_id,1650                            span,1651                            ident,1652                            bounds,1653                        );1654                        self.impl_trait_defs.push(param);1655                        if let Some(bounds) = bounds {1656                            self.impl_trait_bounds.push(bounds);1657                        }1658                        path1659                    }1660                    ImplTraitContext::InBinding => {1661                        hir::TyKind::TraitAscription(self.lower_param_bounds(1662                            bounds,1663                            RelaxedBoundPolicy::Allowed(&mut Default::default()),1664                            itctx,1665                        ))1666                    }1667                    ImplTraitContext::FeatureGated(position, feature) => {1668                        let guar = self1669                            .tcx1670                            .sess1671                            .create_feature_err(1672                                MisplacedImplTrait {1673                                    span: t.span,1674                                    position: DiagArgFromDisplay(&position),1675                                },1676                                feature,1677                            )1678                            .emit();1679                        hir::TyKind::Err(guar)1680                    }1681                    ImplTraitContext::Disallowed(position) => {1682                        let guar = self.dcx().emit_err(MisplacedImplTrait {1683                            span: t.span,1684                            position: DiagArgFromDisplay(&position),1685                        });1686                        hir::TyKind::Err(guar)1687                    }1688                }1689            }1690            TyKind::Pat(ty, pat) => {1691                hir::TyKind::Pat(self.lower_ty_alloc(ty, itctx), self.lower_ty_pat(pat, ty.span))1692            }1693            TyKind::FieldOf(ty, variant, field) => hir::TyKind::FieldOf(1694                self.lower_ty_alloc(ty, itctx),1695                self.arena.alloc(hir::TyFieldPath {1696                    variant: variant.map(|variant| self.lower_ident(variant)),1697                    field: self.lower_ident(*field),1698                }),1699            ),1700            TyKind::MacCall(_) => {1701                span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")1702            }1703            TyKind::CVarArgs => {1704                let guar = self.dcx().span_delayed_bug(1705                    t.span,1706                    "`TyKind::CVarArgs` should have been handled elsewhere",1707                );1708                hir::TyKind::Err(guar)1709            }1710            TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),1711        };17121713        hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }1714    }17151716    fn lower_ty_direct_lifetime(1717        &mut self,1718        t: &Ty,1719        region: Option<Lifetime>,1720    ) -> &'hir hir::Lifetime {1721        let (region, syntax) = match region {1722            Some(region) => (region, region.ident.into()),17231724            None => {1725                let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =1726                    self.owner.get_lifetime_res(t.id)1727                {1728                    assert_eq!(start.plus(1), end);1729                    start1730                } else {1731                    self.next_node_id()1732                };1733                let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();1734                let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };1735                (region, LifetimeSyntax::Implicit)1736            }1737        };1738        self.lower_lifetime(&region, LifetimeSource::Reference, syntax)1739    }17401741    /// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =1742    /// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a1743    /// HIR type that references the TAIT.1744    ///1745    /// Given a function definition like:1746    ///1747    /// ```rust1748    /// use std::fmt::Debug;1749    ///1750    /// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {1751    ///     x1752    /// }1753    /// ```1754    ///1755    /// we will create a TAIT definition in the HIR like1756    ///1757    /// ```rust,ignore (pseudo-Rust)1758    /// type TestReturn<'a, T, 'x> = impl Debug + 'x1759    /// ```1760    ///1761    /// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:1762    ///1763    /// ```rust,ignore (pseudo-Rust)1764    /// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>1765    /// ```1766    ///1767    /// Note the subtlety around type parameters! The new TAIT, `TestReturn`, inherits all the1768    /// type parameters from the function `test` (this is implemented in the query layer, they aren't1769    /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to1770    /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters1771    /// for the lifetimes that get captured (`'x`, in our example above) and reference those.1772    #[instrument(level = "debug", skip(self), ret)]1773    fn lower_opaque_impl_trait(1774        &mut self,1775        span: Span,1776        origin: hir::OpaqueTyOrigin<LocalDefId>,1777        opaque_ty_node_id: NodeId,1778        bounds: &GenericBounds,1779        itctx: ImplTraitContext,1780    ) -> hir::TyKind<'hir> {1781        // Make sure we know that some funky desugaring has been going on here.1782        // This is a first: there is code in other places like for loop1783        // desugaring that explicitly states that we don't want to track that.1784        // Not tracking it makes lints in rustc and clippy very fragile, as1785        // frequently opened issues show.1786        let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);17871788        self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {1789            this.lower_param_bounds(1790                bounds,1791                RelaxedBoundPolicy::Allowed(&mut Default::default()),1792                itctx,1793            )1794        })1795    }17961797    fn lower_opaque_inner(1798        &mut self,1799        opaque_ty_node_id: NodeId,1800        origin: hir::OpaqueTyOrigin<LocalDefId>,1801        opaque_ty_span: Span,1802        lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],1803    ) -> hir::TyKind<'hir> {1804        let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);1805        let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);1806        debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);18071808        let bounds = lower_item_bounds(self);1809        let opaque_ty_def = hir::OpaqueTy {1810            hir_id: opaque_ty_hir_id,1811            def_id: opaque_ty_def_id,1812            bounds,1813            origin,1814            span: self.lower_span(opaque_ty_span),1815        };1816        let opaque_ty_def = self.arena.alloc(opaque_ty_def);18171818        hir::TyKind::OpaqueDef(opaque_ty_def)1819    }18201821    fn lower_precise_capturing_args(1822        &mut self,1823        precise_capturing_args: &[PreciseCapturingArg],1824    ) -> &'hir [hir::PreciseCapturingArg<'hir>] {1825        self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {1826            PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(1827                self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),1828            ),1829            PreciseCapturingArg::Arg(path, id) => {1830                let [segment] = path.segments.as_slice() else {1831                    panic!();1832                };1833                let res = self.get_partial_res(*id).map_or(Res::Err, |partial_res| {1834                    partial_res.full_res().expect("no partial res expected for precise capture arg")1835                });1836                hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {1837                    hir_id: self.lower_node_id(*id),1838                    ident: self.lower_ident(segment.ident),1839                    res: self.lower_res(res),1840                })1841            }1842        }))1843    }18441845    fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {1846        self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {1847            PatKind::Missing => None,1848            PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),1849            PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),1850            _ => {1851                self.dcx().span_delayed_bug(1852                    param.pat.span,1853                    "non-missing/ident/wild param pat must trigger an error",1854                );1855                None1856            }1857        }))1858    }18591860    /// Lowers a function declaration.1861    ///1862    /// `decl`: the unlowered (AST) function declaration.1863    ///1864    /// `fn_node_id`: `impl Trait` arguments are lowered into generic parameters on the given1865    /// `NodeId`.1866    ///1867    /// `transform_return_type`: if `Some`, applies some conversion to the return type, such as is1868    /// needed for `async fn` and `gen fn`. See [`CoroutineKind`] for more details.1869    #[instrument(level = "debug", skip(self))]1870    fn lower_fn_decl(1871        &mut self,1872        decl: &FnDecl,1873        fn_node_id: NodeId,1874        fn_span: Span,1875        kind: FnDeclKind,1876        coro: Option<CoroutineKind>,1877    ) -> &'hir hir::FnDecl<'hir> {1878        let c_variadic = decl.c_variadic();1879        let mut splatted = decl.splatted();18801881        // Skip the `...` (`CVarArgs`) trailing arguments from the AST,1882        // as they are not explicit in HIR/Ty function signatures.1883        // (instead, the `c_variadic` flag is set to `true`)1884        let mut inputs = &decl.inputs[..];1885        if decl.c_variadic() {1886            // Splat + variadic errors in AST validation, so just ignore one of them here.1887            splatted = None;1888            inputs = &inputs[..inputs.len() - 1];1889        }1890        let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {1891            let itctx = match kind {1892                FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {1893                    ImplTraitContext::Universal1894                }1895                FnDeclKind::ExternFn => {1896                    ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)1897                }1898                FnDeclKind::Closure => {1899                    ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)1900                }1901                FnDeclKind::Pointer => {1902                    ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)1903                }1904            };1905            self.lower_ty(&param.ty, itctx)1906        }));19071908        let output = match coro {1909            Some(coro) => {1910                let fn_def_id = self.owner.def_id;1911                self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind)1912            }1913            None => match &decl.output {1914                FnRetTy::Ty(ty) => {1915                    let itctx = match kind {1916                        FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {1917                            origin: hir::OpaqueTyOrigin::FnReturn {1918                                parent: self.owner.def_id,1919                                in_trait_or_impl: None,1920                            },1921                        },1922                        FnDeclKind::Trait => ImplTraitContext::OpaqueTy {1923                            origin: hir::OpaqueTyOrigin::FnReturn {1924                                parent: self.owner.def_id,1925                                in_trait_or_impl: Some(hir::RpitContext::Trait),1926                            },1927                        },1928                        FnDeclKind::Impl => ImplTraitContext::OpaqueTy {1929                            origin: hir::OpaqueTyOrigin::FnReturn {1930                                parent: self.owner.def_id,1931                                in_trait_or_impl: Some(hir::RpitContext::TraitImpl),1932                            },1933                        },1934                        FnDeclKind::ExternFn => {1935                            ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)1936                        }1937                        FnDeclKind::Closure => {1938                            ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)1939                        }1940                        FnDeclKind::Pointer => {1941                            ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)1942                        }1943                    };1944                    hir::FnRetTy::Return(self.lower_ty_alloc(ty, itctx))1945                }1946                FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),1947            },1948        };19491950        let fn_decl_kind = hir::FnDeclFlags::default()1951            .set_implicit_self(decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {1952                let is_mutable_pat = matches!(1953                    arg.pat.kind,1954                    PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)1955                );19561957                match &arg.ty.kind {1958                    TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,1959                    TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,1960                    // Given we are only considering `ImplicitSelf` types, we needn't consider1961                    // the case where we have a mutable pattern to a reference as that would1962                    // no longer be an `ImplicitSelf`.1963                    TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)1964                        if mt.ty.kind.is_implicit_self() =>1965                    {1966                        match mt.mutbl {1967                            hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,1968                            hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,1969                        }1970                    }1971                    _ => hir::ImplicitSelfKind::None,1972                }1973            }))1974            .set_lifetime_elision_allowed(1975                self.owner.id == fn_node_id && self.owner.lifetime_elision_allowed,1976            )1977            .set_c_variadic(c_variadic)1978            .set_splatted(splatted, inputs.len())1979            .unwrap();19801981        self.arena.alloc(hir::FnDecl { inputs, output, fn_decl_kind })1982    }19831984    // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`1985    // combined with the following definition of `OpaqueTy`:1986    //1987    //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;1988    //1989    // `output`: unlowered output type (`T` in `-> T`)1990    // `fn_node_id`: `NodeId` of the parent function (used to create child impl trait definition)1991    // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created1992    #[instrument(level = "debug", skip(self))]1993    fn lower_coroutine_fn_ret_ty(1994        &mut self,1995        output: &FnRetTy,1996        fn_def_id: LocalDefId,1997        coro: CoroutineKind,1998        fn_kind: FnDeclKind,1999    ) -> hir::FnRetTy<'hir> {2000        let span = self.lower_span(output.span());

Findings

✓ No findings reported for this file.

Get this view in your editor

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