compiler/rustc_ast_lowering/src/lib.rs RUST 3,037 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 3,037.
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(box_patterns)]35#![recursion_limit = "256"]36// tidy-alphabetical-end3738use std::mem;39use std::sync::Arc;4041use rustc_ast::node_id::NodeMap;42use rustc_ast::visit::Visitor;43use rustc_ast::{self as ast, *};44use rustc_attr_parsing::{AttributeParser, OmitDoc, Recovery, ShouldEmit};45use rustc_data_structures::fingerprint::Fingerprint;46use rustc_data_structures::fx::FxIndexSet;47use rustc_data_structures::sorted_map::SortedMap;48use rustc_data_structures::stable_hasher::{StableHash, StableHasher};49use rustc_data_structures::steal::Steal;50use rustc_data_structures::tagged_ptr::TaggedRef;51use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle};52use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};53use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};54use rustc_hir::definitions::PerParentDisambiguatorState;55use rustc_hir::lints::DelayedLint;56use rustc_hir::{57    self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource,58    LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr,59};60use rustc_index::{Idx, IndexSlice, IndexVec};61use rustc_macros::extension;62use rustc_middle::hir::{self as mid_hir};63use rustc_middle::span_bug;64use rustc_middle::ty::{DelegationInfo, ResolverAstLowering, TyCtxt};65use rustc_session::errors::add_feature_diagnostics;66use rustc_span::symbol::{Ident, Symbol, kw, sym};67use rustc_span::{DUMMY_SP, DesugaringKind, Span};68use smallvec::SmallVec;69use thin_vec::ThinVec;70use tracing::{debug, instrument, trace};7172use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait};73use crate::item::Owners;7475macro_rules! arena_vec {76    ($this:expr; $($x:expr),*) => (77        $this.arena.alloc_from_iter([$($x),*])78    );79}8081mod asm;82mod block;83mod contract;84mod delegation;85mod errors;86mod expr;87mod format;88mod index;89mod item;90mod pat;91mod path;92pub mod stability;9394struct LoweringContext<'a, 'hir> {95    tcx: TyCtxt<'hir>,96    resolver: &'a ResolverAstLowering<'hir>,97    current_disambiguator: PerParentDisambiguatorState,9899    /// Used to allocate HIR nodes.100    arena: &'hir hir::Arena<'hir>,101102    /// Bodies inside the owner being lowered.103    bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,104    /// `#[define_opaque]` attributes105    define_opaque: Option<&'hir [(Span, LocalDefId)]>,106    /// Attributes inside the owner being lowered.107    attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,108    /// Collect items that were created by lowering the current owner.109    children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>,110111    contract_ensures: Option<(Span, Ident, HirId)>,112113    coroutine_kind: Option<hir::CoroutineKind>,114115    /// When inside an `async` context, this is the `HirId` of the116    /// `task_context` local bound to the resume argument of the coroutine.117    task_context: Option<HirId>,118119    /// Used to get the current `fn`'s def span to point to when using `await`120    /// outside of an `async fn`.121    current_item: Option<Span>,122123    try_block_scope: TryBlockScope,124    loop_scope: Option<HirId>,125    is_in_loop_condition: bool,126    is_in_dyn_type: bool,127128    current_hir_id_owner: hir::OwnerId,129    item_local_id_counter: hir::ItemLocalId,130    trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>,131132    impl_trait_defs: Vec<hir::GenericParam<'hir>>,133    impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,134135    /// NodeIds of pattern identifiers and labelled nodes that are lowered inside the current HIR owner.136    ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,137    /// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering check.138    #[cfg(debug_assertions)]139    node_id_to_local_id: NodeMap<hir::ItemLocalId>,140    /// The `NodeId` space is split in two.141    /// `0..resolver.next_node_id` are created by the resolver on the AST.142    /// The higher part `resolver.next_node_id..next_node_id` are created during lowering.143    next_node_id: NodeId,144    /// Maps the `NodeId`s created during lowering to `LocalDefId`s.145    node_id_to_def_id: NodeMap<LocalDefId>,146    /// Overlay over resolver's `partial_res_map` used by delegation.147    /// This only contains `PartialRes::new(Res::Local(self_param_id))`,148    /// so we only store `self_param_id`.149    partial_res_overrides: NodeMap<NodeId>,150151    allow_contracts: Arc<[Symbol]>,152    allow_try_trait: Arc<[Symbol]>,153    allow_gen_future: Arc<[Symbol]>,154    allow_pattern_type: Arc<[Symbol]>,155    allow_async_gen: Arc<[Symbol]>,156    allow_async_iterator: Arc<[Symbol]>,157    allow_for_await: Arc<[Symbol]>,158    allow_async_fn_traits: Arc<[Symbol]>,159160    delayed_lints: Vec<DelayedLint>,161162    attribute_parser: AttributeParser<'hir>,163}164165impl<'a, 'hir> LoweringContext<'a, 'hir> {166    fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>) -> Self {167        Self {168            tcx,169            resolver,170            current_disambiguator: Default::default(),171            arena: tcx.hir_arena,172173            // HirId handling.174            bodies: Vec::new(),175            define_opaque: None,176            attrs: SortedMap::default(),177            children: Vec::default(),178            contract_ensures: None,179            current_hir_id_owner: hir::CRATE_OWNER_ID,180            item_local_id_counter: hir::ItemLocalId::ZERO,181            ident_and_label_to_local_id: Default::default(),182            #[cfg(debug_assertions)]183            node_id_to_local_id: Default::default(),184            trait_map: Default::default(),185            next_node_id: resolver.next_node_id,186            node_id_to_def_id: NodeMap::default(),187            partial_res_overrides: NodeMap::default(),188189            // Lowering state.190            try_block_scope: TryBlockScope::Function,191            loop_scope: None,192            is_in_loop_condition: false,193            is_in_dyn_type: false,194            coroutine_kind: None,195            task_context: None,196            current_item: None,197            impl_trait_defs: Vec::new(),198            impl_trait_bounds: Vec::new(),199            allow_contracts: [sym::contracts_internals].into(),200            allow_try_trait: [201                sym::try_trait_v2,202                sym::try_trait_v2_residual,203                sym::yeet_desugar_details,204            ]205            .into(),206            allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),207            allow_gen_future: if tcx.features().async_fn_track_caller() {208                [sym::gen_future, sym::closure_track_caller].into()209            } else {210                [sym::gen_future].into()211            },212            allow_for_await: [sym::async_gen_internals, sym::async_iterator].into(),213            allow_async_fn_traits: [sym::async_fn_traits].into(),214            allow_async_gen: [sym::async_gen_internals].into(),215            // FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller`216            // interact with `gen`/`async gen` blocks217            allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),218219            attribute_parser: AttributeParser::new(220                tcx.sess,221                tcx.features(),222                tcx.registered_tools(()),223                ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },224            ),225            delayed_lints: Vec::new(),226        }227    }228229    pub(crate) fn dcx(&self) -> DiagCtxtHandle<'hir> {230        self.tcx.dcx()231    }232}233234struct SpanLowerer {235    is_incremental: bool,236    def_id: LocalDefId,237}238239impl SpanLowerer {240    fn lower(&self, span: Span) -> Span {241        if self.is_incremental {242            span.with_parent(Some(self.def_id))243        } else {244            // Do not make spans relative when not using incremental compilation.245            span246        }247    }248}249250#[extension(trait ResolverAstLoweringExt<'tcx>)]251impl<'tcx> ResolverAstLowering<'tcx> {252    fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'tcx>) -> Option<Vec<usize>> {253        let ExprKind::Path(None, path) = &expr.kind else {254            return None;255        };256257        // Don't perform legacy const generics rewriting if the path already258        // has generic arguments.259        if path.segments.last().unwrap().args.is_some() {260            return None;261        }262263        // We do not need to look at `partial_res_overrides`. That map only contains overrides for264        // `self_param` locals. And here we are looking for the function definition that `expr`265        // resolves to.266        let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?;267268        // We only support cross-crate argument rewriting. Uses269        // within the same crate should be updated to use the new270        // const generics style.271        if def_id.is_local() {272            return None;273        }274275        // we can use parsed attrs here since for other crates they're already available276        find_attr!(277            tcx, def_id,278            RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes279        )280        .map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect())281    }282283    /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.284    fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>> {285        self.import_res_map.get(&id).copied().unwrap_or_default()286    }287288    /// Obtains resolution for a label with the given `NodeId`.289    fn get_label_res(&self, id: NodeId) -> Option<NodeId> {290        self.label_res_map.get(&id).copied()291    }292293    /// Obtains resolution for a lifetime with the given `NodeId`.294    fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes> {295        self.lifetimes_res_map.get(&id).copied()296    }297298    /// Obtain the list of lifetimes parameters to add to an item.299    ///300    /// Extra lifetime parameters should only be added in places that can appear301    /// as a `binder` in `LifetimeRes`.302    ///303    /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring304    /// should appear at the enclosing `PolyTraitRef`.305    fn extra_lifetime_params(&self, id: NodeId) -> &[(Ident, NodeId, LifetimeRes)] {306        self.extra_lifetime_params_map.get(&id).map_or(&[], |v| &v[..])307    }308309    fn delegation_info(&self, id: LocalDefId) -> Option<&DelegationInfo> {310        self.delegation_infos.get(&id)311    }312313    fn opt_local_def_id(&self, id: NodeId) -> Option<LocalDefId> {314        self.node_id_to_def_id.get(&id).copied()315    }316317    fn local_def_id(&self, id: NodeId) -> LocalDefId {318        self.opt_local_def_id(id).expect("must have def_id")319    }320321    fn lifetime_elision_allowed(&self, id: NodeId) -> bool {322        self.lifetime_elision_allowed.contains(&id)323    }324}325326/// How relaxed bounds `?Trait` should be treated.327///328/// Relaxed bounds should only be allowed in places where we later329/// (namely during HIR ty lowering) perform *sized elaboration*.330#[derive(Clone, Copy, Debug)]331enum RelaxedBoundPolicy<'a> {332    Allowed,333    AllowedIfOnTyParam(NodeId, &'a [ast::GenericParam]),334    Forbidden(RelaxedBoundForbiddenReason),335}336337#[derive(Clone, Copy, Debug)]338enum RelaxedBoundForbiddenReason {339    TraitObjectTy,340    SuperTrait,341    TraitAlias,342    AssocTyBounds,343    LateBoundVarsInScope,344}345346/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,347/// and if so, what meaning it has.348#[derive(Debug, Copy, Clone, PartialEq, Eq)]349enum ImplTraitContext {350    /// Treat `impl Trait` as shorthand for a new universal generic parameter.351    /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually352    /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.353    ///354    /// Newly generated parameters should be inserted into the given `Vec`.355    Universal,356357    /// Treat `impl Trait` as shorthand for a new opaque type.358    /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually359    /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.360    ///361    OpaqueTy { origin: hir::OpaqueTyOrigin<LocalDefId> },362363    /// Treat `impl Trait` as a "trait ascription", which is like a type364    /// variable but that also enforces that a set of trait goals hold.365    ///366    /// This is useful to guide inference for unnameable types.367    InBinding,368369    /// `impl Trait` is unstably accepted in this position.370    FeatureGated(ImplTraitPosition, Symbol),371    /// `impl Trait` is not accepted in this position.372    Disallowed(ImplTraitPosition),373}374375/// Position in which `impl Trait` is disallowed.376#[derive(Debug, Copy, Clone, PartialEq, Eq)]377enum ImplTraitPosition {378    Path,379    Variable,380    Trait,381    Bound,382    Generic,383    ExternFnParam,384    ClosureParam,385    PointerParam,386    FnTraitParam,387    ExternFnReturn,388    ClosureReturn,389    PointerReturn,390    FnTraitReturn,391    GenericDefault,392    ConstTy,393    StaticTy,394    AssocTy,395    FieldTy,396    Cast,397    ImplSelf,398    OffsetOf,399}400401impl std::fmt::Display for ImplTraitPosition {402    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {403        let name = match self {404            ImplTraitPosition::Path => "paths",405            ImplTraitPosition::Variable => "the type of variable bindings",406            ImplTraitPosition::Trait => "traits",407            ImplTraitPosition::Bound => "bounds",408            ImplTraitPosition::Generic => "generics",409            ImplTraitPosition::ExternFnParam => "`extern fn` parameters",410            ImplTraitPosition::ClosureParam => "closure parameters",411            ImplTraitPosition::PointerParam => "`fn` pointer parameters",412            ImplTraitPosition::FnTraitParam => "the parameters of `Fn` trait bounds",413            ImplTraitPosition::ExternFnReturn => "`extern fn` return types",414            ImplTraitPosition::ClosureReturn => "closure return types",415            ImplTraitPosition::PointerReturn => "`fn` pointer return types",416            ImplTraitPosition::FnTraitReturn => "the return type of `Fn` trait bounds",417            ImplTraitPosition::GenericDefault => "generic parameter defaults",418            ImplTraitPosition::ConstTy => "const types",419            ImplTraitPosition::StaticTy => "static types",420            ImplTraitPosition::AssocTy => "associated types",421            ImplTraitPosition::FieldTy => "field types",422            ImplTraitPosition::Cast => "cast expression types",423            ImplTraitPosition::ImplSelf => "impl headers",424            ImplTraitPosition::OffsetOf => "`offset_of!` parameters",425        };426427        write!(f, "{name}")428    }429}430431#[derive(Copy, Clone, Debug, PartialEq, Eq)]432enum FnDeclKind {433    Fn,434    Inherent,435    ExternFn,436    Closure,437    Pointer,438    Trait,439    Impl,440}441442#[derive(Copy, Clone)]443enum AstOwner<'a> {444    NonOwner,445    Crate(&'a ast::Crate),446    Item(&'a ast::Item),447    AssocItem(&'a ast::AssocItem, visit::AssocCtxt),448    ForeignItem(&'a ast::ForeignItem),449}450451#[derive(Copy, Clone, Debug)]452enum TryBlockScope {453    /// There isn't a `try` block, so a `?` will use `return`.454    Function,455    /// We're inside a `try { … }` block, so a `?` will block-break456    /// from that block using a type depending only on the argument.457    Homogeneous(HirId),458    /// We're inside a `try as _ { … }` block, so a `?` will block-break459    /// from that block using the type specified.460    Heterogeneous(HirId),461}462463fn index_crate<'a, 'b>(464    resolver: &'b ResolverAstLowering<'b>,465    krate: &'a Crate,466) -> IndexVec<LocalDefId, AstOwner<'a>> {467    let mut indexer = Indexer { resolver, index: IndexVec::new() };468    *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) =469        AstOwner::Crate(krate);470    visit::walk_crate(&mut indexer, krate);471472    return indexer.index;473474    struct Indexer<'a, 'b> {475        resolver: &'b ResolverAstLowering<'b>,476        index: IndexVec<LocalDefId, AstOwner<'a>>,477    }478479    impl<'a, 'b> visit::Visitor<'a> for Indexer<'a, 'b> {480        fn visit_attribute(&mut self, _: &'a Attribute) {481            // We do not want to lower expressions that appear in attributes,482            // as they are not accessible to the rest of the HIR.483        }484485        fn visit_item(&mut self, item: &'a ast::Item) {486            let def_id = self.resolver.local_def_id(item.id);487            *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item);488            visit::walk_item(self, item)489        }490491        fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {492            let def_id = self.resolver.local_def_id(item.id);493            *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =494                AstOwner::AssocItem(item, ctxt);495            visit::walk_assoc_item(self, item, ctxt);496        }497498        fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {499            let def_id = self.resolver.local_def_id(item.id);500            *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =501                AstOwner::ForeignItem(item);502            visit::walk_item(self, item);503        }504    }505}506507/// Compute the hash for the HIR of the full crate.508/// This hash will then be part of the crate_hash which is stored in the metadata.509fn compute_hir_hash(510    tcx: TyCtxt<'_>,511    owners: &IndexSlice<LocalDefId, hir::MaybeOwner<'_>>,512) -> Fingerprint {513    let mut hir_body_nodes: Vec<_> = owners514        .iter_enumerated()515        .filter_map(|(def_id, info)| {516            let info = info.as_owner()?;517            let def_path_hash = tcx.hir_def_path_hash(def_id);518            Some((def_path_hash, info))519        })520        .collect();521    hir_body_nodes.sort_unstable_by_key(|bn| bn.0);522523    tcx.with_stable_hashing_context(|mut hcx| {524        let mut stable_hasher = StableHasher::new();525        hir_body_nodes.stable_hash(&mut hcx, &mut stable_hasher);526        stable_hasher.finish()527    })528}529530pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {531    // Queries that borrow `resolver_for_lowering`.532    tcx.ensure_done().output_filenames(());533    tcx.ensure_done().early_lint_checks(());534    tcx.ensure_done().debugger_visualizers(LOCAL_CRATE);535    tcx.ensure_done().get_lang_items(());536    let (resolver, krate) = tcx.resolver_for_lowering().steal();537538    let ast_index = index_crate(&resolver, &krate);539    let mut owners = IndexVec::from_fn_n(540        |_| hir::MaybeOwner::Phantom,541        tcx.definitions_untracked().def_index_count(),542    );543544    let mut lowerer = item::ItemLowerer {545        tcx,546        resolver: &resolver,547        ast_index: &ast_index,548        owners: Owners::IndexVec(&mut owners),549    };550551    let mut delayed_ids: FxIndexSet<LocalDefId> = Default::default();552553    for def_id in ast_index.indices() {554        match &ast_index[def_id] {555            AstOwner::Item(Item { kind: ItemKind::Delegation { .. }, .. })556            | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) => {557                delayed_ids.insert(def_id);558            }559            _ => lowerer.lower_node(def_id),560        };561    }562563    // Don't hash unless necessary, because it's expensive.564    let opt_hir_hash =565        if tcx.needs_hir_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };566567    let delayed_resolver = Steal::new((resolver, krate));568    mid_hir::Crate::new(owners, delayed_ids, delayed_resolver, opt_hir_hash)569}570571/// Lowers an AST owner corresponding to `def_id`, now only delegations are lowered this way.572pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) {573    let krate = tcx.hir_crate(());574575    let (resolver, krate) = &*krate.delayed_resolver.borrow();576577    // FIXME!!!(fn_delegation): make ast index lifetime same as resolver,578    // as it is too bad to reindex whole crate on each delegation lowering.579    let ast_index = index_crate(resolver, krate);580581    let mut map = Default::default();582    let mut lowerer = item::ItemLowerer {583        tcx,584        resolver: &resolver,585        ast_index: &ast_index,586        owners: Owners::Map(&mut map),587    };588589    lowerer.lower_node(def_id);590591    for (child_def_id, owner) in map {592        tcx.feed_delayed_owner(child_def_id, owner);593    }594}595596#[derive(Copy, Clone, PartialEq, Debug)]597enum ParamMode {598    /// Any path in a type context.599    Explicit,600    /// The `module::Type` in `module::Type::method` in an expression.601    Optional,602}603604#[derive(Copy, Clone, Debug)]605enum AllowReturnTypeNotation {606    /// Only in types, since RTN is denied later during HIR lowering.607    Yes,608    /// All other positions (path expr, method, use tree).609    No,610}611612enum GenericArgsMode {613    /// Allow paren sugar, don't allow RTN.614    ParenSugar,615    /// Allow RTN, don't allow paren sugar.616    ReturnTypeNotation,617    // Error if parenthesized generics or RTN are encountered.618    Err,619    /// Silence errors when lowering generics. Only used with `Res::Err`.620    Silence,621}622623impl<'hir> LoweringContext<'_, 'hir> {624    fn create_def(625        &mut self,626        node_id: NodeId,627        name: Option<Symbol>,628        def_kind: DefKind,629        span: Span,630    ) -> LocalDefId {631        let parent = self.current_hir_id_owner.def_id;632        assert_ne!(node_id, ast::DUMMY_NODE_ID);633        assert!(634            self.opt_local_def_id(node_id).is_none(),635            "adding a def'n for node-id {:?} and def kind {:?} but a previous def'n exists: {:?}",636            node_id,637            def_kind,638            self.tcx.hir_def_key(self.local_def_id(node_id)),639        );640641        let def_id = self642            .tcx643            .at(span)644            .create_def(parent, name, def_kind, None, &mut self.current_disambiguator)645            .def_id();646647        debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);648        self.node_id_to_def_id.insert(node_id, def_id);649650        def_id651    }652653    fn next_node_id(&mut self) -> NodeId {654        let start = self.next_node_id;655        let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");656        self.next_node_id = NodeId::from_u32(next);657        start658    }659660    /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name661    /// resolver (if any).662    fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {663        self.node_id_to_def_id664            .get(&node)665            .or_else(|| self.resolver.node_id_to_def_id.get(&node))666            .copied()667    }668669    fn local_def_id(&self, node: NodeId) -> LocalDefId {670        self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))671    }672673    fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {674        match self.partial_res_overrides.get(&id) {675            Some(self_param_id) => Some(PartialRes::new(Res::Local(*self_param_id))),676            None => self.resolver.partial_res_map.get(&id).copied(),677        }678    }679680    /// Given the id of an owner node in the AST, returns the corresponding `OwnerId`.681    fn owner_id(&self, node: NodeId) -> hir::OwnerId {682        hir::OwnerId { def_id: self.local_def_id(node) }683    }684685    /// Freshen the `LoweringContext` and ready it to lower a nested item.686    /// The lowered item is registered into `self.children`.687    ///688    /// This function sets up `HirId` lowering infrastructure,689    /// and stashes the shared mutable state to avoid pollution by the closure.690    #[instrument(level = "debug", skip(self, f))]691    fn with_hir_id_owner(692        &mut self,693        owner: NodeId,694        f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,695    ) {696        let owner_id = self.owner_id(owner);697        let def_id = owner_id.def_id;698699        let new_disambig = self700            .resolver701            .disambiguators702            .get(&def_id)703            .map(|s| s.steal())704            .unwrap_or_else(|| PerParentDisambiguatorState::new(def_id));705706        let disambiguator = std::mem::replace(&mut self.current_disambiguator, new_disambig);707        let current_attrs = std::mem::take(&mut self.attrs);708        let current_bodies = std::mem::take(&mut self.bodies);709        let current_define_opaque = std::mem::take(&mut self.define_opaque);710        let current_ident_and_label_to_local_id =711            std::mem::take(&mut self.ident_and_label_to_local_id);712713        #[cfg(debug_assertions)]714        let current_node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id);715        let current_trait_map = std::mem::take(&mut self.trait_map);716        let current_owner = std::mem::replace(&mut self.current_hir_id_owner, owner_id);717        let current_local_counter =718            std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));719        let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);720        let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);721        let current_delayed_lints = std::mem::take(&mut self.delayed_lints);722723        // Do not reset `next_node_id` and `node_id_to_def_id`:724        // we want `f` to be able to refer to the `LocalDefId`s that the caller created.725        // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.726727        // Always allocate the first `HirId` for the owner itself.728        #[cfg(debug_assertions)]729        {730            let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO);731            debug_assert_eq!(_old, None);732        }733734        let item = f(self);735        assert_eq!(owner_id, item.def_id());736        // `f` should have consumed all the elements in these vectors when constructing `item`.737        assert!(self.impl_trait_defs.is_empty());738        assert!(self.impl_trait_bounds.is_empty());739        let info = self.make_owner_info(item);740741        self.current_disambiguator = disambiguator;742        self.attrs = current_attrs;743        self.bodies = current_bodies;744        self.define_opaque = current_define_opaque;745        self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;746747        #[cfg(debug_assertions)]748        {749            self.node_id_to_local_id = current_node_id_to_local_id;750        }751        self.trait_map = current_trait_map;752        self.current_hir_id_owner = current_owner;753        self.item_local_id_counter = current_local_counter;754        self.impl_trait_defs = current_impl_trait_defs;755        self.impl_trait_bounds = current_impl_trait_bounds;756        self.delayed_lints = current_delayed_lints;757758        debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id));759        self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info)));760    }761762    fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {763        let attrs = std::mem::take(&mut self.attrs);764        let mut bodies = std::mem::take(&mut self.bodies);765        let define_opaque = std::mem::take(&mut self.define_opaque);766        let trait_map = std::mem::take(&mut self.trait_map);767        let delayed_lints = Steal::new(std::mem::take(&mut self.delayed_lints).into_boxed_slice());768769        #[cfg(debug_assertions)]770        for (id, attrs) in attrs.iter() {771            // Verify that we do not store empty slices in the map.772            if attrs.is_empty() {773                panic!("Stored empty attributes for {:?}", id);774            }775        }776777        bodies.sort_by_key(|(k, _)| *k);778        let bodies = SortedMap::from_presorted_elements(bodies);779780        // Don't hash unless necessary, because it's expensive.781        let rustc_middle::hir::Hashes { opt_hash_including_bodies, attrs_hash } =782            self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque);783        let num_nodes = self.item_local_id_counter.as_usize();784        let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);785        let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };786        let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };787788        self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map, delayed_lints })789    }790791    /// This method allocates a new `HirId` for the given `NodeId`.792    /// Take care not to call this method if the resulting `HirId` is then not793    /// actually used in the HIR, as that would trigger an assertion in the794    /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped795    /// properly. Calling the method twice with the same `NodeId` is also forbidden.796    #[instrument(level = "debug", skip(self), ret)]797    fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId {798        assert_ne!(ast_node_id, DUMMY_NODE_ID);799800        let owner = self.current_hir_id_owner;801        let local_id = self.item_local_id_counter;802        assert_ne!(local_id, hir::ItemLocalId::ZERO);803        self.item_local_id_counter.increment_by(1);804        let hir_id = HirId { owner, local_id };805806        if let Some(def_id) = self.opt_local_def_id(ast_node_id) {807            self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));808        }809810        if let Some(traits) = self.resolver.trait_map.get(&ast_node_id) {811            self.trait_map.insert(hir_id.local_id, &traits[..]);812        }813814        // Check whether the same `NodeId` is lowered more than once.815        #[cfg(debug_assertions)]816        {817            let old = self.node_id_to_local_id.insert(ast_node_id, local_id);818            assert_eq!(old, None);819        }820821        hir_id822    }823824    /// Generate a new `HirId` without a backing `NodeId`.825    #[instrument(level = "debug", skip(self), ret)]826    fn next_id(&mut self) -> HirId {827        let owner = self.current_hir_id_owner;828        let local_id = self.item_local_id_counter;829        assert_ne!(local_id, hir::ItemLocalId::ZERO);830        self.item_local_id_counter.increment_by(1);831        HirId { owner, local_id }832    }833834    #[instrument(level = "trace", skip(self))]835    fn lower_res(&mut self, res: Res<NodeId>) -> Res {836        let res: Result<Res, ()> = res.apply_id(|id| {837            let owner = self.current_hir_id_owner;838            let local_id = self.ident_and_label_to_local_id.get(&id).copied().ok_or(())?;839            Ok(HirId { owner, local_id })840        });841        trace!(?res);842843        // We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.844        // This can happen when trying to lower the return type `x` in erroneous code like845        //   async fn foo(x: u8) -> x {}846        // In that case, `x` is lowered as a function parameter, and the return type is lowered as847        // an opaque type as a synthesized HIR owner.848        res.unwrap_or(Res::Err)849    }850851    fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {852        self.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())853    }854855    fn lower_import_res(&mut self, id: NodeId, span: Span) -> PerNS<Option<Res>> {856        let per_ns = self.resolver.get_import_res(id);857        let per_ns = per_ns.map(|res| res.map(|res| self.lower_res(res)));858        if per_ns.is_empty() {859            // Propagate the error to all namespaces, just to be sure.860            self.dcx().span_delayed_bug(span, "no resolution for an import");861            let err = Some(Res::Err);862            return PerNS { type_ns: err, value_ns: err, macro_ns: err };863        }864        per_ns865    }866867    fn make_lang_item_qpath(868        &mut self,869        lang_item: hir::LangItem,870        span: Span,871        args: Option<&'hir hir::GenericArgs<'hir>>,872    ) -> hir::QPath<'hir> {873        hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))874    }875876    fn make_lang_item_path(877        &mut self,878        lang_item: hir::LangItem,879        span: Span,880        args: Option<&'hir hir::GenericArgs<'hir>>,881    ) -> &'hir hir::Path<'hir> {882        let def_id = self.tcx.require_lang_item(lang_item, span);883        let def_kind = self.tcx.def_kind(def_id);884        let res = Res::Def(def_kind, def_id);885        self.arena.alloc(hir::Path {886            span,887            res,888            segments: self.arena.alloc_from_iter([hir::PathSegment {889                ident: Ident::new(lang_item.name(), span),890                hir_id: self.next_id(),891                res,892                args,893                infer_args: args.is_none(),894            }]),895        })896    }897898    /// Reuses the span but adds information like the kind of the desugaring and features that are899    /// allowed inside this span.900    fn mark_span_with_reason(901        &self,902        reason: DesugaringKind,903        span: Span,904        allow_internal_unstable: Option<Arc<[Symbol]>>,905    ) -> Span {906        self.tcx.with_stable_hashing_context(|hcx| {907            span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx)908        })909    }910911    fn span_lowerer(&self) -> SpanLowerer {912        SpanLowerer {913            is_incremental: self.tcx.sess.opts.incremental.is_some(),914            def_id: self.current_hir_id_owner.def_id,915        }916    }917918    /// Intercept all spans entering HIR.919    /// Mark a span as relative to the current owning item.920    fn lower_span(&self, span: Span) -> Span {921        self.span_lowerer().lower(span)922    }923924    fn lower_ident(&self, ident: Ident) -> Ident {925        Ident::new(ident.name, self.lower_span(ident.span))926    }927928    /// Converts a lifetime into a new generic parameter.929    #[instrument(level = "debug", skip(self))]930    fn lifetime_res_to_generic_param(931        &mut self,932        ident: Ident,933        node_id: NodeId,934        res: LifetimeRes,935        source: hir::GenericParamSource,936    ) -> Option<hir::GenericParam<'hir>> {937        let (name, kind) = match res {938            LifetimeRes::Param { .. } => {939                (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)940            }941            LifetimeRes::Fresh { param, kind, .. } => {942                // Late resolution delegates to us the creation of the `LocalDefId`.943                let _def_id = self.create_def(944                    param,945                    Some(kw::UnderscoreLifetime),946                    DefKind::LifetimeParam,947                    ident.span,948                );949                debug!(?_def_id);950951                (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))952            }953            LifetimeRes::Static { .. } | LifetimeRes::Error(..) => return None,954            res => panic!(955                "Unexpected lifetime resolution {:?} for {:?} at {:?}",956                res, ident, ident.span957            ),958        };959        let hir_id = self.lower_node_id(node_id);960        let def_id = self.local_def_id(node_id);961        Some(hir::GenericParam {962            hir_id,963            def_id,964            name,965            span: self.lower_span(ident.span),966            pure_wrt_drop: false,967            kind: hir::GenericParamKind::Lifetime { kind },968            colon_span: None,969            source,970        })971    }972973    /// Lowers a lifetime binder that defines `generic_params`, returning the corresponding HIR974    /// nodes. The returned list includes any "extra" lifetime parameters that were added by the975    /// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id976    /// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime977    /// parameters will be successful.978    #[instrument(level = "debug", skip(self), ret)]979    #[inline]980    fn lower_lifetime_binder(981        &mut self,982        binder: NodeId,983        generic_params: &[GenericParam],984    ) -> &'hir [hir::GenericParam<'hir>] {985        // Start by creating params for extra lifetimes params, as this creates the definitions986        // that may be referred to by the AST inside `generic_params`.987        let extra_lifetimes = self.resolver.extra_lifetime_params(binder);988        debug!(?extra_lifetimes);989        let extra_lifetimes: Vec<_> = extra_lifetimes990            .iter()991            .filter_map(|&(ident, node_id, res)| {992                self.lifetime_res_to_generic_param(993                    ident,994                    node_id,995                    res,996                    hir::GenericParamSource::Binder,997                )998            })999            .collect();1000        let arena = self.arena;1001        let explicit_generic_params =1002            self.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder);1003        arena.alloc_from_iter(explicit_generic_params.chain(extra_lifetimes.into_iter()))1004    }10051006    fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {1007        let was_in_dyn_type = self.is_in_dyn_type;1008        self.is_in_dyn_type = in_scope;10091010        let result = f(self);10111012        self.is_in_dyn_type = was_in_dyn_type;10131014        result1015    }10161017    fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {1018        let current_item = self.current_item;1019        self.current_item = Some(scope_span);10201021        let was_in_loop_condition = self.is_in_loop_condition;1022        self.is_in_loop_condition = false;10231024        let old_contract = self.contract_ensures.take();10251026        let try_block_scope = mem::replace(&mut self.try_block_scope, TryBlockScope::Function);1027        let loop_scope = self.loop_scope.take();1028        let ret = f(self);1029        self.try_block_scope = try_block_scope;1030        self.loop_scope = loop_scope;10311032        self.contract_ensures = old_contract;10331034        self.is_in_loop_condition = was_in_loop_condition;10351036        self.current_item = current_item;10371038        ret1039    }10401041    fn lower_attrs(1042        &mut self,1043        id: HirId,1044        attrs: &[Attribute],1045        target_span: Span,1046        target: Target,1047    ) -> &'hir [hir::Attribute] {1048        self.lower_attrs_with_extra(id, attrs, target_span, target, &[])1049    }10501051    fn lower_attrs_with_extra(1052        &mut self,1053        id: HirId,1054        attrs: &[Attribute],1055        target_span: Span,1056        target: Target,1057        extra_hir_attributes: &[hir::Attribute],1058    ) -> &'hir [hir::Attribute] {1059        if attrs.is_empty() && extra_hir_attributes.is_empty() {1060            &[]1061        } else {1062            let mut lowered_attrs =1063                self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target);1064            lowered_attrs.extend(extra_hir_attributes.iter().cloned());10651066            assert_eq!(id.owner, self.current_hir_id_owner);1067            let ret = self.arena.alloc_from_iter(lowered_attrs);10681069            // this is possible if an item contained syntactical attribute,1070            // but none of them parse successfully or all of them were ignored1071            // for not being built-in attributes at all. They could be remaining1072            // unexpanded attributes used as markers in proc-macro derives for example.1073            // This will have emitted some diagnostics for the misparse, but will then1074            // not emit the attribute making the list empty.1075            if ret.is_empty() {1076                &[]1077            } else {1078                self.attrs.insert(id.local_id, ret);1079                ret1080            }1081        }1082    }10831084    fn lower_attrs_vec(1085        &mut self,1086        attrs: &[Attribute],1087        target_span: Span,1088        target_hir_id: HirId,1089        target: Target,1090    ) -> Vec<hir::Attribute> {1091        let l = self.span_lowerer();1092        self.attribute_parser.parse_attribute_list(1093            attrs,1094            target_span,1095            target,1096            OmitDoc::Lower,1097            |s| l.lower(s),1098            |lint_id, span, kind| {1099                self.delayed_lints.push(DelayedLint {1100                    lint_id,1101                    id: target_hir_id,1102                    span,1103                    callback: Box::new(move |dcx, level, sess: &dyn std::any::Any| {1104                        let sess = sess1105                            .downcast_ref::<rustc_session::Session>()1106                            .expect("expected `Session`");1107                        (kind.0)(dcx, level, sess)1108                    }),1109                });1110            },1111        )1112    }11131114    fn alias_attrs(&mut self, id: HirId, target_id: HirId) {1115        assert_eq!(id.owner, self.current_hir_id_owner);1116        assert_eq!(target_id.owner, self.current_hir_id_owner);1117        if let Some(&a) = self.attrs.get(&target_id.local_id) {1118            assert!(!a.is_empty());1119            self.attrs.insert(id.local_id, a);1120        }1121    }11221123    fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {1124        args.clone()1125    }11261127    /// Lower an associated item constraint.1128    #[instrument(level = "debug", skip_all)]1129    fn lower_assoc_item_constraint(1130        &mut self,1131        constraint: &AssocItemConstraint,1132        itctx: ImplTraitContext,1133    ) -> hir::AssocItemConstraint<'hir> {1134        debug!(?constraint, ?itctx);1135        // Lower the generic arguments for the associated item.1136        let gen_args = if let Some(gen_args) = &constraint.gen_args {1137            let gen_args_ctor = match gen_args {1138                GenericArgs::AngleBracketed(data) => {1139                    self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).01140                }1141                GenericArgs::Parenthesized(data) => {1142                    if let Some(first_char) = constraint.ident.as_str().chars().next()1143                        && first_char.is_ascii_lowercase()1144                    {1145                        let err = match (&data.inputs[..], &data.output) {1146                            ([_, ..], FnRetTy::Default(_)) => {1147                                errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }1148                            }1149                            ([], FnRetTy::Default(_)) => {1150                                errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span }1151                            }1152                            // The case `T: Trait<method(..) -> Ret>` is handled in the parser.1153                            (_, FnRetTy::Ty(ty)) => {1154                                let span = data.inputs_span.shrink_to_hi().to(ty.span);1155                                errors::BadReturnTypeNotation::Output {1156                                    span,1157                                    suggestion: errors::RTNSuggestion {1158                                        output: span,1159                                        input: data.inputs_span,1160                                    },1161                                }1162                            }1163                        };1164                        let mut err = self.dcx().create_err(err);1165                        if !self.tcx.features().return_type_notation()1166                            && self.tcx.sess.is_nightly_build()1167                        {1168                            add_feature_diagnostics(1169                                &mut err,1170                                &self.tcx.sess,1171                                sym::return_type_notation,1172                            );1173                        }1174                        err.emit();1175                        GenericArgsCtor {1176                            args: Default::default(),1177                            constraints: &[],1178                            parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,1179                            span: data.span,1180                        }1181                    } else {1182                        self.emit_bad_parenthesized_trait_in_assoc_ty(data);1183                        // FIXME(return_type_notation): we could issue a feature error1184                        // if the parens are empty and there's no return type.1185                        self.lower_angle_bracketed_parameter_data(1186                            &data.as_angle_bracketed_args(),1187                            ParamMode::Explicit,1188                            itctx,1189                        )1190                        .01191                    }1192                }1193                GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {1194                    args: Default::default(),1195                    constraints: &[],1196                    parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,1197                    span: *span,1198                },1199            };1200            gen_args_ctor.into_generic_args(self)1201        } else {1202            hir::GenericArgs::NONE1203        };1204        let kind = match &constraint.kind {1205            AssocItemConstraintKind::Equality { term } => {1206                let term = match term {1207                    Term::Ty(ty) => self.lower_ty_alloc(ty, itctx).into(),1208                    Term::Const(c) => self.lower_anon_const_to_const_arg_and_alloc(c).into(),1209                };1210                hir::AssocItemConstraintKind::Equality { term }1211            }1212            AssocItemConstraintKind::Bound { bounds } => {1213                // Disallow ATB in dyn types1214                if self.is_in_dyn_type {1215                    let suggestion = match itctx {1216                        ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {1217                            let bound_end_span = constraint1218                                .gen_args1219                                .as_ref()1220                                .map_or(constraint.ident.span, |args| args.span());1221                            if bound_end_span.eq_ctxt(constraint.span) {1222                                Some(self.tcx.sess.source_map().next_point(bound_end_span))1223                            } else {1224                                None1225                            }1226                        }1227                        _ => None,1228                    };12291230                    let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {1231                        span: constraint.span,1232                        suggestion,1233                    });1234                    let err_ty =1235                        &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));1236                    hir::AssocItemConstraintKind::Equality { term: err_ty.into() }1237                } else {1238                    let bounds = self.lower_param_bounds(1239                        bounds,1240                        RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::AssocTyBounds),1241                        itctx,1242                    );1243                    hir::AssocItemConstraintKind::Bound { bounds }1244                }1245            }1246        };12471248        hir::AssocItemConstraint {1249            hir_id: self.lower_node_id(constraint.id),1250            ident: self.lower_ident(constraint.ident),1251            gen_args,1252            kind,1253            span: self.lower_span(constraint.span),1254        }1255    }12561257    fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {1258        // Suggest removing empty parentheses: "Trait()" -> "Trait"1259        let sub = if data.inputs.is_empty() {1260            let parentheses_span =1261                data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());1262            AssocTyParenthesesSub::Empty { parentheses_span }1263        }1264        // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`1265        else {1266            // Start of parameters to the 1st argument1267            let open_param = data.inputs_span.shrink_to_lo().to(data1268                .inputs1269                .first()1270                .unwrap()1271                .span1272                .shrink_to_lo());1273            // End of last argument to end of parameters1274            let close_param =1275                data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());1276            AssocTyParenthesesSub::NotEmpty { open_param, close_param }1277        };1278        self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });1279    }12801281    #[instrument(level = "debug", skip(self))]1282    fn lower_generic_arg(1283        &mut self,1284        arg: &ast::GenericArg,1285        itctx: ImplTraitContext,1286    ) -> hir::GenericArg<'hir> {1287        match arg {1288            ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(1289                lt,1290                LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },1291                lt.ident.into(),1292            )),1293            ast::GenericArg::Type(ty) => {1294                // We cannot just match on `TyKind::Infer` as `(_)` is represented as1295                // `TyKind::Paren(TyKind::Infer)` and should also be lowered to `GenericArg::Infer`1296                if ty.is_maybe_parenthesised_infer() {1297                    return GenericArg::Infer(hir::InferArg {1298                        hir_id: self.lower_node_id(ty.id),1299                        span: self.lower_span(ty.span),1300                    });1301                }13021303                match &ty.kind {1304                    // We parse const arguments as path types as we cannot distinguish them during1305                    // parsing. We try to resolve that ambiguity by attempting resolution in both the1306                    // type and value namespaces. If we resolved the path in the value namespace, we1307                    // transform it into a generic const argument.1308                    //1309                    // FIXME: Should we be handling `(PATH_TO_CONST)`?1310                    TyKind::Path(None, path) => {1311                        if let Some(res) = self1312                            .get_partial_res(ty.id)1313                            .and_then(|partial_res| partial_res.full_res())1314                        {1315                            if !res.matches_ns(Namespace::TypeNS)1316                                && path.is_potential_trivial_const_arg()1317                            {1318                                debug!(1319                                    "lower_generic_arg: Lowering type argument as const argument: {:?}",1320                                    ty,1321                                );13221323                                let ct =1324                                    self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);1325                                return GenericArg::Const(ct.try_as_ambig_ct().unwrap());1326                            }1327                        }1328                    }1329                    _ => {}1330                }1331                GenericArg::Type(self.lower_ty_alloc(ty, itctx).try_as_ambig_ty().unwrap())1332            }1333            ast::GenericArg::Const(ct) => {1334                let ct = self.lower_anon_const_to_const_arg_and_alloc(ct);1335                match ct.try_as_ambig_ct() {1336                    Some(ct) => GenericArg::Const(ct),1337                    None => GenericArg::Infer(hir::InferArg { hir_id: ct.hir_id, span: ct.span }),1338                }1339            }1340        }1341    }13421343    #[instrument(level = "debug", skip(self))]1344    fn lower_ty_alloc(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {1345        self.arena.alloc(self.lower_ty(t, itctx))1346    }13471348    fn lower_path_ty(1349        &mut self,1350        t: &Ty,1351        qself: &Option<Box<QSelf>>,1352        path: &Path,1353        param_mode: ParamMode,1354        itctx: ImplTraitContext,1355    ) -> hir::Ty<'hir> {1356        // Check whether we should interpret this as a bare trait object.1357        // This check mirrors the one in late resolution. We only introduce this special case in1358        // the rare occurrence we need to lower `Fresh` anonymous lifetimes.1359        // The other cases when a qpath should be opportunistically made a trait object are handled1360        // by `ty_path`.1361        if qself.is_none()1362            && let Some(partial_res) = self.get_partial_res(t.id)1363            && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()1364        {1365            let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {1366                let bound = this.lower_poly_trait_ref(1367                    &PolyTraitRef {1368                        bound_generic_params: ThinVec::new(),1369                        modifiers: TraitBoundModifiers::NONE,1370                        trait_ref: TraitRef { path: path.clone(), ref_id: t.id },1371                        span: t.span,1372                        parens: ast::Parens::No,1373                    },1374                    RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitObjectTy),1375                    itctx,1376                );1377                let bounds = this.arena.alloc_from_iter([bound]);1378                let lifetime_bound = this.elided_dyn_bound(t.span);1379                (bounds, lifetime_bound)1380            });1381            let kind = hir::TyKind::TraitObject(1382                bounds,1383                TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),1384            );1385            return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };1386        }13871388        let id = self.lower_node_id(t.id);1389        let qpath = self.lower_qpath(1390            t.id,1391            qself,1392            path,1393            param_mode,1394            AllowReturnTypeNotation::Yes,1395            itctx,1396            None,1397        );1398        self.ty_path(id, t.span, qpath)1399    }14001401    fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {1402        hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }1403    }14041405    fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {1406        self.ty(span, hir::TyKind::Tup(tys))1407    }14081409    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {1410        let kind = match &t.kind {1411            TyKind::Infer => hir::TyKind::Infer(()),1412            TyKind::Err(guar) => hir::TyKind::Err(*guar),1413            TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty_alloc(ty, itctx)),1414            TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),1415            TyKind::Ref(region, mt) => {1416                let lifetime = self.lower_ty_direct_lifetime(t, *region);1417                hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))1418            }1419            TyKind::PinnedRef(region, mt) => {1420                let lifetime = self.lower_ty_direct_lifetime(t, *region);1421                let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));1422                let span = self.lower_span(t.span);1423                let arg = hir::Ty { kind, span, hir_id: self.next_id() };1424                let args = self.arena.alloc(hir::GenericArgs {1425                    args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),1426                    constraints: &[],1427                    parenthesized: hir::GenericArgsParentheses::No,1428                    span_ext: span,1429                });1430                let path = self.make_lang_item_qpath(hir::LangItem::Pin, span, Some(args));1431                hir::TyKind::Path(path)1432            }1433            TyKind::FnPtr(f) => {1434                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);1435                hir::TyKind::FnPtr(self.arena.alloc(hir::FnPtrTy {1436                    generic_params,1437                    safety: self.lower_safety(f.safety, hir::Safety::Safe),1438                    abi: self.lower_extern(f.ext),1439                    decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),1440                    param_idents: self.lower_fn_params_to_idents(&f.decl),1441                }))1442            }1443            TyKind::UnsafeBinder(f) => {1444                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);1445                hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {1446                    generic_params,1447                    inner_ty: self.lower_ty_alloc(&f.inner_ty, itctx),1448                }))1449            }1450            TyKind::Never => hir::TyKind::Never,1451            TyKind::Tup(tys) => hir::TyKind::Tup(1452                self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty(ty, itctx))),1453            ),1454            TyKind::Paren(ty) => {1455                return self.lower_ty(ty, itctx);1456            }1457            TyKind::Path(qself, path) => {1458                return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);1459            }1460            TyKind::ImplicitSelf => {1461                let hir_id = self.next_id();1462                let res = self.expect_full_res(t.id);1463                let res = self.lower_res(res);1464                hir::TyKind::Path(hir::QPath::Resolved(1465                    None,1466                    self.arena.alloc(hir::Path {1467                        res,1468                        segments: arena_vec![self; hir::PathSegment::new(1469                            Ident::with_dummy_span(kw::SelfUpper),1470                            hir_id,1471                            res1472                        )],1473                        span: self.lower_span(t.span),1474                    }),1475                ))1476            }1477            TyKind::Array(ty, length) => hir::TyKind::Array(1478                self.lower_ty_alloc(ty, itctx),1479                self.lower_array_length_to_const_arg(length),1480            ),1481            TyKind::TraitObject(bounds, kind) => {1482                let mut lifetime_bound = None;1483                let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {1484                    let bounds =1485                        this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {1486                            // We can safely ignore constness here since AST validation1487                            // takes care of rejecting invalid modifier combinations and1488                            // const trait bounds in trait object types.1489                            GenericBound::Trait(ty) => {1490                                let trait_ref = this.lower_poly_trait_ref(1491                                    ty,1492                                    RelaxedBoundPolicy::Forbidden(1493                                        RelaxedBoundForbiddenReason::TraitObjectTy,1494                                    ),1495                                    itctx,1496                                );1497                                Some(trait_ref)1498                            }1499                            GenericBound::Outlives(lifetime) => {1500                                if lifetime_bound.is_none() {1501                                    lifetime_bound = Some(this.lower_lifetime(1502                                        lifetime,1503                                        LifetimeSource::Other,1504                                        lifetime.ident.into(),1505                                    ));1506                                }1507                                None1508                            }1509                            // Ignore `use` syntax since that is not valid in objects.1510                            GenericBound::Use(_, span) => {1511                                this.dcx()1512                                    .span_delayed_bug(*span, "use<> not allowed in dyn types");1513                                None1514                            }1515                        }));1516                    let lifetime_bound =1517                        lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));1518                    (bounds, lifetime_bound)1519                });1520                hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))1521            }1522            TyKind::ImplTrait(def_node_id, bounds) => {1523                let span = t.span;1524                match itctx {1525                    ImplTraitContext::OpaqueTy { origin } => {1526                        self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)1527                    }1528                    ImplTraitContext::Universal => {1529                        if let Some(span) = bounds.iter().find_map(|bound| match *bound {1530                            ast::GenericBound::Use(_, span) => Some(span),1531                            _ => None,1532                        }) {1533                            self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });1534                        }15351536                        let def_id = self.local_def_id(*def_node_id);1537                        let name = self.tcx.item_name(def_id.to_def_id());1538                        let ident = Ident::new(name, span);1539                        let (param, bounds, path) = self.lower_universal_param_and_bounds(1540                            *def_node_id,1541                            span,1542                            ident,1543                            bounds,1544                        );1545                        self.impl_trait_defs.push(param);1546                        if let Some(bounds) = bounds {1547                            self.impl_trait_bounds.push(bounds);1548                        }1549                        path1550                    }1551                    ImplTraitContext::InBinding => hir::TyKind::TraitAscription(1552                        self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx),1553                    ),1554                    ImplTraitContext::FeatureGated(position, feature) => {1555                        let guar = self1556                            .tcx1557                            .sess1558                            .create_feature_err(1559                                MisplacedImplTrait {1560                                    span: t.span,1561                                    position: DiagArgFromDisplay(&position),1562                                },1563                                feature,1564                            )1565                            .emit();1566                        hir::TyKind::Err(guar)1567                    }1568                    ImplTraitContext::Disallowed(position) => {1569                        let guar = self.dcx().emit_err(MisplacedImplTrait {1570                            span: t.span,1571                            position: DiagArgFromDisplay(&position),1572                        });1573                        hir::TyKind::Err(guar)1574                    }1575                }1576            }1577            TyKind::Pat(ty, pat) => {1578                hir::TyKind::Pat(self.lower_ty_alloc(ty, itctx), self.lower_ty_pat(pat, ty.span))1579            }1580            TyKind::FieldOf(ty, variant, field) => hir::TyKind::FieldOf(1581                self.lower_ty_alloc(ty, itctx),1582                self.arena.alloc(hir::TyFieldPath {1583                    variant: variant.map(|variant| self.lower_ident(variant)),1584                    field: self.lower_ident(*field),1585                }),1586            ),1587            TyKind::MacCall(_) => {1588                span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")1589            }1590            TyKind::CVarArgs => {1591                let guar = self.dcx().span_delayed_bug(1592                    t.span,1593                    "`TyKind::CVarArgs` should have been handled elsewhere",1594                );1595                hir::TyKind::Err(guar)1596            }1597            TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),1598        };15991600        hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }1601    }16021603    fn lower_ty_direct_lifetime(1604        &mut self,1605        t: &Ty,1606        region: Option<Lifetime>,1607    ) -> &'hir hir::Lifetime {1608        let (region, syntax) = match region {1609            Some(region) => (region, region.ident.into()),16101611            None => {1612                let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =1613                    self.resolver.get_lifetime_res(t.id)1614                {1615                    assert_eq!(start.plus(1), end);1616                    start1617                } else {1618                    self.next_node_id()1619                };1620                let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();1621                let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };1622                (region, LifetimeSyntax::Implicit)1623            }1624        };1625        self.lower_lifetime(&region, LifetimeSource::Reference, syntax)1626    }16271628    /// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =1629    /// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a1630    /// HIR type that references the TAIT.1631    ///1632    /// Given a function definition like:1633    ///1634    /// ```rust1635    /// use std::fmt::Debug;1636    ///1637    /// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {1638    ///     x1639    /// }1640    /// ```1641    ///1642    /// we will create a TAIT definition in the HIR like1643    ///1644    /// ```rust,ignore (pseudo-Rust)1645    /// type TestReturn<'a, T, 'x> = impl Debug + 'x1646    /// ```1647    ///1648    /// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:1649    ///1650    /// ```rust,ignore (pseudo-Rust)1651    /// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>1652    /// ```1653    ///1654    /// Note the subtlety around type parameters! The new TAIT, `TestReturn`, inherits all the1655    /// type parameters from the function `test` (this is implemented in the query layer, they aren't1656    /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to1657    /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters1658    /// for the lifetimes that get captured (`'x`, in our example above) and reference those.1659    #[instrument(level = "debug", skip(self), ret)]1660    fn lower_opaque_impl_trait(1661        &mut self,1662        span: Span,1663        origin: hir::OpaqueTyOrigin<LocalDefId>,1664        opaque_ty_node_id: NodeId,1665        bounds: &GenericBounds,1666        itctx: ImplTraitContext,1667    ) -> hir::TyKind<'hir> {1668        // Make sure we know that some funky desugaring has been going on here.1669        // This is a first: there is code in other places like for loop1670        // desugaring that explicitly states that we don't want to track that.1671        // Not tracking it makes lints in rustc and clippy very fragile, as1672        // frequently opened issues show.1673        let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);16741675        self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {1676            this.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx)1677        })1678    }16791680    fn lower_opaque_inner(1681        &mut self,1682        opaque_ty_node_id: NodeId,1683        origin: hir::OpaqueTyOrigin<LocalDefId>,1684        opaque_ty_span: Span,1685        lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],1686    ) -> hir::TyKind<'hir> {1687        let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);1688        let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);1689        debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);16901691        let bounds = lower_item_bounds(self);1692        let opaque_ty_def = hir::OpaqueTy {1693            hir_id: opaque_ty_hir_id,1694            def_id: opaque_ty_def_id,1695            bounds,1696            origin,1697            span: self.lower_span(opaque_ty_span),1698        };1699        let opaque_ty_def = self.arena.alloc(opaque_ty_def);17001701        hir::TyKind::OpaqueDef(opaque_ty_def)1702    }17031704    fn lower_precise_capturing_args(1705        &mut self,1706        precise_capturing_args: &[PreciseCapturingArg],1707    ) -> &'hir [hir::PreciseCapturingArg<'hir>] {1708        self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {1709            PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(1710                self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),1711            ),1712            PreciseCapturingArg::Arg(path, id) => {1713                let [segment] = path.segments.as_slice() else {1714                    panic!();1715                };1716                let res = self.get_partial_res(*id).map_or(Res::Err, |partial_res| {1717                    partial_res.full_res().expect("no partial res expected for precise capture arg")1718                });1719                hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {1720                    hir_id: self.lower_node_id(*id),1721                    ident: self.lower_ident(segment.ident),1722                    res: self.lower_res(res),1723                })1724            }1725        }))1726    }17271728    fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {1729        self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {1730            PatKind::Missing => None,1731            PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),1732            PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),1733            _ => {1734                self.dcx().span_delayed_bug(1735                    param.pat.span,1736                    "non-missing/ident/wild param pat must trigger an error",1737                );1738                None1739            }1740        }))1741    }17421743    /// Lowers a function declaration.1744    ///1745    /// `decl`: the unlowered (AST) function declaration.1746    ///1747    /// `fn_node_id`: `impl Trait` arguments are lowered into generic parameters on the given1748    /// `NodeId`.1749    ///1750    /// `transform_return_type`: if `Some`, applies some conversion to the return type, such as is1751    /// needed for `async fn` and `gen fn`. See [`CoroutineKind`] for more details.1752    #[instrument(level = "debug", skip(self))]1753    fn lower_fn_decl(1754        &mut self,1755        decl: &FnDecl,1756        fn_node_id: NodeId,1757        fn_span: Span,1758        kind: FnDeclKind,1759        coro: Option<CoroutineKind>,1760    ) -> &'hir hir::FnDecl<'hir> {1761        let c_variadic = decl.c_variadic();17621763        // Skip the `...` (`CVarArgs`) trailing arguments from the AST,1764        // as they are not explicit in HIR/Ty function signatures.1765        // (instead, the `c_variadic` flag is set to `true`)1766        let mut inputs = &decl.inputs[..];1767        if decl.c_variadic() {1768            inputs = &inputs[..inputs.len() - 1];1769        }1770        let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {1771            let itctx = match kind {1772                FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {1773                    ImplTraitContext::Universal1774                }1775                FnDeclKind::ExternFn => {1776                    ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)1777                }1778                FnDeclKind::Closure => {1779                    ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)1780                }1781                FnDeclKind::Pointer => {1782                    ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)1783                }1784            };1785            self.lower_ty(&param.ty, itctx)1786        }));17871788        let output = match coro {1789            Some(coro) => {1790                let fn_def_id = self.local_def_id(fn_node_id);1791                self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind)1792            }1793            None => match &decl.output {1794                FnRetTy::Ty(ty) => {1795                    let itctx = match kind {1796                        FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {1797                            origin: hir::OpaqueTyOrigin::FnReturn {1798                                parent: self.local_def_id(fn_node_id),1799                                in_trait_or_impl: None,1800                            },1801                        },1802                        FnDeclKind::Trait => ImplTraitContext::OpaqueTy {1803                            origin: hir::OpaqueTyOrigin::FnReturn {1804                                parent: self.local_def_id(fn_node_id),1805                                in_trait_or_impl: Some(hir::RpitContext::Trait),1806                            },1807                        },1808                        FnDeclKind::Impl => ImplTraitContext::OpaqueTy {1809                            origin: hir::OpaqueTyOrigin::FnReturn {1810                                parent: self.local_def_id(fn_node_id),1811                                in_trait_or_impl: Some(hir::RpitContext::TraitImpl),1812                            },1813                        },1814                        FnDeclKind::ExternFn => {1815                            ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)1816                        }1817                        FnDeclKind::Closure => {1818                            ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)1819                        }1820                        FnDeclKind::Pointer => {1821                            ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)1822                        }1823                    };1824                    hir::FnRetTy::Return(self.lower_ty_alloc(ty, itctx))1825                }1826                FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),1827            },1828        };18291830        let fn_decl_kind = hir::FnDeclFlags::default()1831            .set_implicit_self(decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {1832                let is_mutable_pat = matches!(1833                    arg.pat.kind,1834                    PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)1835                );18361837                match &arg.ty.kind {1838                    TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,1839                    TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,1840                    // Given we are only considering `ImplicitSelf` types, we needn't consider1841                    // the case where we have a mutable pattern to a reference as that would1842                    // no longer be an `ImplicitSelf`.1843                    TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)1844                        if mt.ty.kind.is_implicit_self() =>1845                    {1846                        match mt.mutbl {1847                            hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,1848                            hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,1849                        }1850                    }1851                    _ => hir::ImplicitSelfKind::None,1852                }1853            }))1854            .set_lifetime_elision_allowed(self.resolver.lifetime_elision_allowed(fn_node_id))1855            .set_c_variadic(c_variadic);18561857        self.arena.alloc(hir::FnDecl { inputs, output, fn_decl_kind })1858    }18591860    // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`1861    // combined with the following definition of `OpaqueTy`:1862    //1863    //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;1864    //1865    // `output`: unlowered output type (`T` in `-> T`)1866    // `fn_node_id`: `NodeId` of the parent function (used to create child impl trait definition)1867    // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created1868    #[instrument(level = "debug", skip(self))]1869    fn lower_coroutine_fn_ret_ty(1870        &mut self,1871        output: &FnRetTy,1872        fn_def_id: LocalDefId,1873        coro: CoroutineKind,1874        fn_kind: FnDeclKind,1875    ) -> hir::FnRetTy<'hir> {1876        let span = self.lower_span(output.span());18771878        let (opaque_ty_node_id, allowed_features) = match coro {1879            CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),1880            CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),1881            CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {1882                (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))1883            }1884        };18851886        let opaque_ty_span =1887            self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);18881889        let in_trait_or_impl = match fn_kind {1890            FnDeclKind::Trait => Some(hir::RpitContext::Trait),1891            FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),1892            FnDeclKind::Fn | FnDeclKind::Inherent => None,1893            FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),1894        };18951896        let opaque_ty_ref = self.lower_opaque_inner(1897            opaque_ty_node_id,1898            hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },1899            opaque_ty_span,1900            |this| {1901                let bound = this.lower_coroutine_fn_output_type_to_bound(1902                    output,1903                    coro,1904                    opaque_ty_span,1905                    ImplTraitContext::OpaqueTy {1906                        origin: hir::OpaqueTyOrigin::FnReturn {1907                            parent: fn_def_id,1908                            in_trait_or_impl,1909                        },1910                    },1911                );1912                arena_vec![this; bound]1913            },1914        );19151916        let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);1917        hir::FnRetTy::Return(self.arena.alloc(opaque_ty))1918    }19191920    /// Transforms `-> T` into `Future<Output = T>`.1921    fn lower_coroutine_fn_output_type_to_bound(1922        &mut self,1923        output: &FnRetTy,1924        coro: CoroutineKind,1925        opaque_ty_span: Span,1926        itctx: ImplTraitContext,1927    ) -> hir::GenericBound<'hir> {1928        // Compute the `T` in `Future<Output = T>` from the return type.1929        let output_ty = match output {1930            FnRetTy::Ty(ty) => {1931                // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the1932                // `impl Future` opaque type that `async fn` implicitly1933                // generates.1934                self.lower_ty_alloc(ty, itctx)1935            }1936            FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),1937        };19381939        // "<$assoc_ty_name = T>"1940        let (assoc_ty_name, trait_lang_item) = match coro {1941            CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),1942            CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),1943            CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),1944        };19451946        let bound_args = self.arena.alloc(hir::GenericArgs {1947            args: &[],1948            constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],1949            parenthesized: hir::GenericArgsParentheses::No,1950            span_ext: DUMMY_SP,1951        });19521953        hir::GenericBound::Trait(hir::PolyTraitRef {1954            bound_generic_params: &[],1955            modifiers: hir::TraitBoundModifiers::NONE,1956            trait_ref: hir::TraitRef {1957                path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),1958                hir_ref_id: self.next_id(),1959            },1960            span: opaque_ty_span,1961        })1962    }19631964    #[instrument(level = "trace", skip(self))]1965    fn lower_param_bound(1966        &mut self,1967        tpb: &GenericBound,1968        rbp: RelaxedBoundPolicy<'_>,1969        itctx: ImplTraitContext,1970    ) -> hir::GenericBound<'hir> {1971        match tpb {1972            GenericBound::Trait(p) => {1973                hir::GenericBound::Trait(self.lower_poly_trait_ref(p, rbp, itctx))1974            }1975            GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(1976                lifetime,1977                LifetimeSource::OutlivesBound,1978                lifetime.ident.into(),1979            )),1980            GenericBound::Use(args, span) => hir::GenericBound::Use(1981                self.lower_precise_capturing_args(args),1982                self.lower_span(*span),1983            ),1984        }1985    }19861987    fn lower_lifetime(1988        &mut self,1989        l: &Lifetime,1990        source: LifetimeSource,1991        syntax: LifetimeSyntax,1992    ) -> &'hir hir::Lifetime {1993        self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)1994    }19951996    fn lower_lifetime_hidden_in_path(1997        &mut self,1998        id: NodeId,1999        span: Span,2000        angle_brackets: AngleBrackets,

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.