compiler/rustc_ast_lowering/src/lib.rs RUST 3,382 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 3,382.
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(const_default)]35#![feature(const_trait_impl)]36#![feature(default_field_values)]37#![feature(deref_patterns)]38#![recursion_limit = "256"]39// tidy-alphabetical-end4041use std::mem;42use std::sync::Arc;4344use rustc_ast::mut_visit::{self, MutVisitor};45use rustc_ast::node_id::NodeMap;46use rustc_ast::visit::{self, Visitor};47use rustc_ast::{self as ast, *};48use rustc_attr_parsing::{AttributeParser, OmitDoc, Recovery, ShouldEmit};49use rustc_data_structures::fx::FxIndexMap;50use rustc_data_structures::sorted_map::SortedMap;51use rustc_data_structures::stable_hash::{StableHash, StableHasher};52use rustc_data_structures::steal::Steal;53use rustc_data_structures::tagged_ptr::TaggedRef;54use rustc_data_structures::unord::ExtendUnord;55use rustc_errors::codes::*;56use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, ErrorGuaranteed};57use rustc_hir::attrs::lang_items::LangItem;58use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};59use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap};60use rustc_hir::definitions::PerParentDisambiguatorState;61use rustc_hir::lints::DelayedLint;62use rustc_hir::{63    self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource,64    LifetimeSyntax, MissingLifetimeKind, ParamName, Target, TraitCandidate, find_attr,65};66use rustc_index::{Idx, IndexVec};67use rustc_macros::extension;68use rustc_middle::queries::Providers;69use rustc_middle::span_bug;70use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt};71use rustc_session::diagnostics::add_feature_diagnostics;72use rustc_span::symbol::{Ident, Symbol, kw, sym};73use rustc_span::{DUMMY_SP, DesugaringKind, Span};74use smallvec::{SmallVec, smallvec};75use thin_vec::ThinVec;76use tracing::{debug, instrument, trace};7778use crate::diagnostics::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait};7980macro_rules! arena_vec {81    ($this:expr; $($x:expr),*) => (82        $this.arena.alloc_from_iter([$($x),*])83    );84}8586mod asm;87mod block;88mod contract;89mod delegation;90mod diagnostics;91mod expr;92mod format;93mod index;94mod item;95mod pat;96mod path;97pub mod stability;9899pub fn provide(providers: &mut Providers) {100    providers.index_ast = index_ast;101    providers.lower_to_hir = lower_to_hir;102}103104#[cfg(debug_assertions)]105pub(crate) mod re_lowering {106    use rustc_ast::NodeId;107    use rustc_ast::node_id::NodeMap;108    use rustc_hir as hir;109110    use crate::LoweringContext;111112    #[derive(Debug, Default)]113    pub(crate) struct ReloweringChecker {114        node_id_to_local_id: NodeMap<hir::ItemLocalId>,115        can_relower: bool,116    }117118    impl ReloweringChecker {119        pub(crate) fn assert_node_is_not_relowered(120            &mut self,121            ast_node_id: NodeId,122            local_id: hir::ItemLocalId,123        ) {124            if !self.can_relower {125                let old = self.node_id_to_local_id.insert(ast_node_id, local_id);126                assert_eq!(old, None);127            }128        }129130        pub(crate) fn allow_relowering<'a, 'hir, TRes>(131            ctx: &mut LoweringContext<'a, 'hir>,132            op: impl FnOnce(&mut LoweringContext<'a, 'hir>) -> TRes,133        ) -> TRes {134            assert!(!ctx.relowering_checker.can_relower, "reentrant relowering is not supported");135136            ctx.relowering_checker.can_relower = true;137138            let res = op(ctx);139140            ctx.relowering_checker.can_relower = false;141142            res143        }144    }145}146147struct LoweringContext<'a, 'hir> {148    tcx: TyCtxt<'hir>,149    resolver: &'a ResolverAstLowering<'hir>,150    current_disambiguator: PerParentDisambiguatorState,151152    /// Used to allocate HIR nodes.153    arena: &'hir hir::Arena<'hir>,154155    /// Bodies inside the owner being lowered.156    bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,157    /// `#[define_opaque]` attributes158    define_opaque: Option<&'hir [(Span, LocalDefId)]>,159    /// Attributes inside the owner being lowered.160    attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,161    /// Collect items that were created by lowering the current owner.162    children: LocalDefIdMap<hir::MaybeOwner<'hir>>,163164    contract_ensures: Option<(Span, Ident, HirId)>,165166    coroutine_kind: Option<hir::CoroutineKind>,167168    /// When inside an `async` context, this is the `HirId` of the169    /// `task_context` local bound to the resume argument of the coroutine.170    task_context: Option<HirId>,171172    /// Used to get the current `fn`'s def span to point to when using `await`173    /// outside of an `async fn`.174    current_item: Option<Span>,175176    try_block_scope: TryBlockScope,177    loop_scope: Option<HirId>,178    is_in_loop_condition: bool,179    is_in_dyn_type: bool,180181    current_hir_id_owner: hir::OwnerId,182    owner: &'a PerOwnerResolverData<'hir>,183    item_local_id_counter: hir::ItemLocalId,184    trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>,185186    impl_trait_defs: Vec<hir::GenericParam<'hir>>,187    impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,188189    /// NodeIds of pattern identifiers and labelled nodes that are lowered inside the current HIR owner.190    ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,191    /// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering check.192    #[cfg(debug_assertions)]193    relowering_checker: re_lowering::ReloweringChecker,194    /// The `NodeId` space is split in two.195    /// `0..resolver.next_node_id` are created by the resolver on the AST.196    /// The higher part `resolver.next_node_id..next_node_id` are created during lowering.197    next_node_id: NodeId,198    /// Maps the `NodeId`s created during lowering to `LocalDefId`s.199    node_id_to_def_id: NodeMap<LocalDefId>,200    /// Overlay over resolver's `partial_res_map` used by delegation.201    /// This only contains `PartialRes::new(Res::Local(self_param_id))`,202    /// so we only store `self_param_id`.203    partial_res_overrides: NodeMap<NodeId>,204205    allow_contracts: Arc<[Symbol]>,206    allow_try_trait: Arc<[Symbol]>,207    allow_gen_future: Arc<[Symbol]>,208    allow_pattern_type: Arc<[Symbol]>,209    allow_async_gen: Arc<[Symbol]>,210    allow_async_iterator: Arc<[Symbol]>,211    allow_for_await: Arc<[Symbol]>,212    allow_async_fn_traits: Arc<[Symbol]>,213214    delayed_lints: Vec<DelayedLint>,215216    /// Stack of `move(...)` collection states. A plain closure body pushes217    /// `Some`, so `move(...)` expressions can record the generated locals they218    /// should lower to. Nested bodies that cannot use `move(...)` push `None`.219    move_expr_bindings: Vec<Option<expr::MoveExprState<'hir>>>,220221    attribute_parser: AttributeParser<'hir>,222}223224impl<'a, 'hir> LoweringContext<'a, 'hir> {225    fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>, owner: NodeId) -> Self {226        let current_ast_owner = &resolver.owners[&owner];227        let current_hir_id_owner = hir::OwnerId { def_id: current_ast_owner.def_id };228        let current_disambiguator = resolver229            .disambiguators230            .get(&current_hir_id_owner.def_id)231            .map(|s| s.steal())232            .unwrap_or_else(|| PerParentDisambiguatorState::new(current_hir_id_owner.def_id));233234        Self {235            tcx,236            resolver,237            current_disambiguator,238            owner: current_ast_owner,239            arena: tcx.hir_arena,240241            // HirId handling.242            bodies: Vec::new(),243            define_opaque: None,244            attrs: SortedMap::default(),245            children: LocalDefIdMap::default(),246            contract_ensures: None,247            current_hir_id_owner,248            // 0 corresponds to `owner` lowered as `current_hir_id_owner`,249            // and we never call `lower_node_id(owner)`.250            item_local_id_counter: hir::ItemLocalId::new(1),251            ident_and_label_to_local_id: Default::default(),252253            #[cfg(debug_assertions)]254            relowering_checker: Default::default(),255256            trait_map: Default::default(),257            next_node_id: resolver.next_node_id,258            node_id_to_def_id: NodeMap::default(),259            partial_res_overrides: NodeMap::default(),260261            // Lowering state.262            try_block_scope: TryBlockScope::Function,263            loop_scope: None,264            is_in_loop_condition: false,265            is_in_dyn_type: false,266            coroutine_kind: None,267            task_context: None,268            current_item: None,269            impl_trait_defs: Vec::new(),270            impl_trait_bounds: Vec::new(),271            allow_contracts: [sym::contracts_internals].into(),272            allow_try_trait: [273                sym::try_trait_v2,274                sym::try_trait_v2_residual,275                sym::yeet_desugar_details,276            ]277            .into(),278            allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),279            allow_gen_future: if tcx.features().async_fn_track_caller() {280                [sym::gen_future, sym::closure_track_caller].into()281            } else {282                [sym::gen_future].into()283            },284            allow_for_await: [sym::async_gen_internals, sym::async_iterator].into(),285            allow_async_fn_traits: [sym::async_fn_traits].into(),286            allow_async_gen: [sym::async_gen_internals].into(),287            // FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller`288            // interact with `gen`/`async gen` blocks289            allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),290291            move_expr_bindings: Vec::new(),292            attribute_parser: AttributeParser::new(293                tcx.sess,294                tcx.features(),295                tcx.registered_attr_tools(()),296                ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },297            ),298            delayed_lints: Vec::new(),299        }300    }301302    pub(crate) fn dcx(&self) -> DiagCtxtHandle<'hir> {303        self.tcx.dcx()304    }305}306307struct SpanLowerer {308    is_incremental: bool,309    def_id: LocalDefId,310}311312impl SpanLowerer {313    fn lower(&self, span: Span) -> Span {314        if self.is_incremental {315            span.with_parent(Some(self.def_id))316        } else {317            // Do not make spans relative when not using incremental compilation.318            span319        }320    }321}322323#[extension(trait ResolverAstLoweringExt<'tcx>)]324impl<'tcx> ResolverAstLowering<'tcx> {325    fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'tcx>) -> Option<Vec<usize>> {326        let ExprKind::Path(None, path) = &expr.kind else {327            return None;328        };329330        // Don't perform legacy const generics rewriting if the path already331        // has generic arguments.332        if path.segments.last().unwrap().args.is_some() {333            return None;334        }335336        // We do not need to look at `partial_res_overrides`. That map only contains overrides for337        // `self_param` locals. And here we are looking for the function definition that `expr`338        // resolves to.339        let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?;340341        // We only support cross-crate argument rewriting. Uses342        // within the same crate should be updated to use the new343        // const generics style.344        if def_id.is_local() {345            return None;346        }347348        // we can use parsed attrs here since for other crates they're already available349        find_attr!(350            tcx, def_id,351            RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes352        )353        .map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect())354    }355}356357/// How relaxed bounds `?Trait` should be treated.358///359/// Relaxed bounds should only be allowed in places where we later360/// (namely during HIR ty lowering) perform *sized elaboration*.361#[derive(Debug)]362enum RelaxedBoundPolicy<'a> {363    /// The `DefId` refers to the trait that is being relaxed.364    Allowed(&'a mut FxIndexMap<DefId, Span>),365    Forbidden(RelaxedBoundForbiddenReason),366}367impl RelaxedBoundPolicy<'_> {368    fn reborrow(&mut self) -> RelaxedBoundPolicy<'_> {369        match self {370            RelaxedBoundPolicy::Allowed(m) => RelaxedBoundPolicy::Allowed(m),371            RelaxedBoundPolicy::Forbidden(reason) => RelaxedBoundPolicy::Forbidden(*reason),372        }373    }374}375376#[derive(Clone, Copy, Debug)]377enum RelaxedBoundForbiddenReason {378    TraitObjectTy,379    SuperTrait,380    TraitAlias,381    AssocTyBounds,382    /// We do not allow where bounds doing relaxed bounds,383    /// except if it's for generic parameters of the current item.384    WhereBound,385}386387/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,388/// and if so, what meaning it has.389#[derive(Debug, Copy, Clone, PartialEq, Eq)]390enum ImplTraitContext {391    /// Treat `impl Trait` as shorthand for a new universal generic parameter.392    /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually393    /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.394    ///395    /// Newly generated parameters should be inserted into the given `Vec`.396    Universal,397398    /// Treat `impl Trait` as shorthand for a new opaque type.399    /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually400    /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.401    ///402    OpaqueTy { origin: hir::OpaqueTyOrigin<LocalDefId> },403404    /// Treat `impl Trait` as a "trait ascription", which is like a type405    /// variable but that also enforces that a set of trait goals hold.406    ///407    /// This is useful to guide inference for unnameable types.408    InBinding,409410    /// `impl Trait` is unstably accepted in this position.411    FeatureGated(ImplTraitPosition, Symbol),412    /// `impl Trait` is not accepted in this position.413    Disallowed(ImplTraitPosition),414415    /// An error has already been emitted for this type.416    AlreadyErrored(ErrorGuaranteed),417}418419/// Position in which `impl Trait` is disallowed.420#[derive(Debug, Copy, Clone, PartialEq, Eq)]421enum ImplTraitPosition {422    Path,423    Variable,424    Trait,425    Bound,426    Generic,427    ExternFnParam,428    ClosureParam,429    PointerParam,430    FnTraitParam,431    ExternFnReturn,432    ClosureReturn,433    PointerReturn,434    FnTraitReturn,435    GenericDefault,436    ConstTy,437    StaticTy,438    AssocTy,439    FieldTy,440    Cast,441    ImplSelf,442    OffsetOf,443}444445impl std::fmt::Display for ImplTraitPosition {446    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {447        let name = match self {448            ImplTraitPosition::Path => "paths",449            ImplTraitPosition::Variable => "the type of variable bindings",450            ImplTraitPosition::Trait => "traits",451            ImplTraitPosition::Bound => "bounds",452            ImplTraitPosition::Generic => "generics",453            ImplTraitPosition::ExternFnParam => "`extern fn` parameters",454            ImplTraitPosition::ClosureParam => "closure parameters",455            ImplTraitPosition::PointerParam => "`fn` pointer parameters",456            ImplTraitPosition::FnTraitParam => "the parameters of `Fn` trait bounds",457            ImplTraitPosition::ExternFnReturn => "`extern fn` return types",458            ImplTraitPosition::ClosureReturn => "closure return types",459            ImplTraitPosition::PointerReturn => "`fn` pointer return types",460            ImplTraitPosition::FnTraitReturn => "the return type of `Fn` trait bounds",461            ImplTraitPosition::GenericDefault => "generic parameter defaults",462            ImplTraitPosition::ConstTy => "const types",463            ImplTraitPosition::StaticTy => "static types",464            ImplTraitPosition::AssocTy => "associated types",465            ImplTraitPosition::FieldTy => "field types",466            ImplTraitPosition::Cast => "cast expression types",467            ImplTraitPosition::ImplSelf => "impl headers",468            ImplTraitPosition::OffsetOf => "`offset_of!` parameters",469        };470471        write!(f, "{name}")472    }473}474475#[derive(Copy, Clone, Debug, PartialEq, Eq)]476enum FnDeclKind {477    Fn,478    Inherent,479    ExternFn,480    Closure,481    Pointer,482    Trait,483    Impl,484}485486#[derive(Copy, Clone, Debug)]487enum TryBlockScope {488    /// There isn't a `try` block, so a `?` will use `return`.489    Function,490    /// We're inside a `try { … }` block, so a `?` will block-break491    /// from that block using a type depending only on the argument.492    Homogeneous(HirId),493    /// We're inside a `try as _ { … }` block, so a `?` will block-break494    /// from that block using the type specified.495    Heterogeneous(HirId),496}497498fn index_ast<'tcx>(499    tcx: TyCtxt<'tcx>,500    (): (),501) -> IndexVec<LocalDefId, Steal<(Arc<ResolverAstLowering<'tcx>>, AstOwner)>> {502    // Queries that borrow `resolver_for_lowering`.503    tcx.ensure_done().output_filenames(());504    tcx.ensure_done().early_lint_checks(());505    tcx.ensure_done().get_lang_items(());506    tcx.ensure_done().debugger_visualizers(LOCAL_CRATE);507508    let (resolver, krate) = tcx.resolver_for_lowering();509    let mut resolver = resolver.steal();510    let mut krate = krate.steal();511512    let mut indexer = Indexer {513        owners: &resolver.owners,514        index: IndexVec::new(),515        next_node_id: resolver.next_node_id,516    };517    indexer.visit_crate(&mut krate);518    indexer.insert(CRATE_NODE_ID, AstOwner::Crate(Box::new(krate)));519    resolver.next_node_id = indexer.next_node_id;520521    let index = indexer.index;522    let resolver = Arc::new(resolver);523    let index = index.into_iter().map(|owner| Steal::new((Arc::clone(&resolver), owner))).collect();524    return index;525526    struct Indexer<'s, 'hir> {527        owners: &'s NodeMap<PerOwnerResolverData<'hir>>,528        index: IndexVec<LocalDefId, AstOwner>,529        next_node_id: NodeId,530    }531532    impl Indexer<'_, '_> {533        fn insert(&mut self, id: NodeId, node: AstOwner) {534            let def_id = self.owners[&id].def_id;535            self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner);536            self.index[def_id] = node;537        }538539        fn make_dummy<K>(540            &mut self,541            id: NodeId,542            span: Span,543            dummy: impl FnOnce(Box<MacCall>) -> K,544        ) -> Box<Item<K>> {545            use rustc_ast::token::Delimiter;546            use rustc_ast::tokenstream::{DelimSpan, TokenStream};547            use thin_vec::thin_vec;548549            Box::new(Item {550                attrs: AttrVec::default(),551                id,552                span,553                vis: Visibility { kind: VisibilityKind::Public, span },554                // Lacking a better choice, we replace the contents with a macro call.555                // Unexpanded macros should never reach lowering, so this is not confusing.556                kind: dummy(Box::new(MacCall {557                    path: Path { span, segments: thin_vec![] },558                    args: Box::new(DelimArgs {559                        dspan: DelimSpan::from_single(span),560                        delim: Delimiter::Parenthesis,561                        tokens: TokenStream::new(Vec::new()),562                    }),563                })),564                tokens: None,565            })566        }567568        fn replace_with_dummy<K>(569            &mut self,570            item: &mut ast::Item<K>,571            dummy: impl FnOnce(Box<MacCall>) -> K,572            node: impl FnOnce(Box<Item<K>>) -> AstOwner,573        ) {574            let dummy = self.make_dummy(item.id, item.span, dummy);575            let item = mem::replace(item, *dummy);576            self.insert(item.id, node(Box::new(item)));577        }578579        #[tracing::instrument(level = "trace", skip(self))]580        fn visit_item_id_use_tree(581            &mut self,582            tree: &UseTree,583            parent: LocalDefId,584            items: &mut SmallVec<[Box<Item>; 1]>,585        ) {586            match tree.kind {587                UseTreeKind::Glob(_) | UseTreeKind::Simple(_) => {}588                UseTreeKind::Nested { items: ref nested_vec, span } => {589                    for &(ref nested, id) in nested_vec {590                        self.insert(id, AstOwner::NestedUseTree(parent));591                        items.push(self.make_dummy(id, span, ItemKind::MacCall));592593                        let def_id = self.owners[&id].def_id;594                        self.visit_item_id_use_tree(nested, def_id, items);595                    }596                }597            }598        }599    }600601    impl MutVisitor for Indexer<'_, '_> {602        fn visit_attribute(&mut self, _: &mut Attribute) {603            // We do not want to lower expressions that appear in attributes,604            // as they are not accessible to the rest of the HIR.605        }606607        fn flat_map_item(&mut self, mut item: Box<Item>) -> SmallVec<[Box<Item>; 1]> {608            let def_id = self.owners[&item.id].def_id;609            mut_visit::walk_item(self, &mut *item);610            let dummy = self.make_dummy(item.id, item.span, ItemKind::MacCall);611            let mut items = smallvec![dummy];612            if let ItemKind::Use(ref use_tree) = item.kind {613                self.visit_item_id_use_tree(use_tree, def_id, &mut items);614            }615            self.insert(item.id, AstOwner::Item(item));616            items617        }618619        fn flat_map_stmt(&mut self, stmt: Stmt) -> SmallVec<[Stmt; 1]> {620            let Stmt { id, span, kind } = stmt;621            let mut id = Some(id);622            mut_visit::walk_flat_map_stmt_kind(self, kind)623                .into_iter()624                .map(|kind| {625                    // Expanding the current statement is a nested `use` item,626                    // it is expanded into several flat `use` items.627                    // Create new NodeIds for the corresponding statements628                    // as two statements cannot have the same.629                    let id = id.take().unwrap_or_else(|| {630                        let next = self.next_node_id;631                        self.next_node_id.increment_by(1);632                        next633                    });634                    Stmt { id, kind, span }635                })636                .collect()637        }638639        fn visit_assoc_item(&mut self, item: &mut AssocItem, ctxt: visit::AssocCtxt) {640            mut_visit::walk_assoc_item(self, item, ctxt);641            match ctxt {642                visit::AssocCtxt::Trait => {643                    self.replace_with_dummy(item, AssocItemKind::MacCall, AstOwner::TraitItem)644                }645                visit::AssocCtxt::Impl { .. } => {646                    self.replace_with_dummy(item, AssocItemKind::MacCall, AstOwner::ImplItem)647                }648            }649        }650651        fn visit_foreign_item(&mut self, item: &mut ForeignItem) {652            mut_visit::walk_item(self, item);653            self.replace_with_dummy(item, ForeignItemKind::MacCall, AstOwner::ForeignItem);654        }655    }656}657658#[instrument(level = "trace", skip(tcx))]659fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> {660    let ast_index = tcx.index_ast(());661    let resolver_and_node = ast_index.get(def_id).map(Steal::steal);662663    let fallback_to_ancestor = |parent_id| {664        // The item did not exist in the AST, it was created while lowering another item.665        // `parent_id` may be different from the direct parent of `def_id`,666        // for instance use-trees are lowered by the first sibling.667        let mut parent_info = tcx.lower_to_hir(parent_id);668        if let hir::MaybeOwner::NonOwner(hir_id) = parent_info {669            // `parent_id` could also not be a owner either.670            // For instance if `def_id` is an enum variant field,671            // the direct parent is the enum variant.672            // In that case `hir_id.owner` point to the actual HIR owner673            // and skips all non-owner parents, so fetch the HIR associated to it.674            parent_info = tcx.lower_to_hir(hir_id.owner);675        }676677        let parent_info = parent_info.unwrap();678        *parent_info.children.get(&def_id).unwrap_or_else(|| {679            panic!(680                "{:?} does not appear in children of {:?}",681                def_id,682                parent_info.nodes.node().def_id()683            )684        })685    };686687    let Some((resolver, node)) = resolver_and_node else {688        // `ast_index` does not contain all definitions, only up-to the highest689        // `LocalDefId` which has a non-trivial `AstOwner`. Gracefully handle690        // other definitions, in particular those nested inside this highest definition.691        return fallback_to_ancestor(tcx.local_parent(def_id));692    };693694    let mut item_lowerer = item::ItemLowerer { tcx, resolver: &*resolver };695696    let item = match &node {697        // The item existed in the AST.698        AstOwner::Crate(c) => item_lowerer.lower_crate(&c),699        AstOwner::Item(item) => item_lowerer.lower_item(&item),700        AstOwner::TraitItem(item) => item_lowerer.lower_trait_item(&item),701        AstOwner::ImplItem(item) => item_lowerer.lower_impl_item(&item),702        AstOwner::ForeignItem(item) => item_lowerer.lower_foreign_item(&item),703        AstOwner::NestedUseTree(owner_id) => fallback_to_ancestor(*owner_id),704        // The item existed in the AST, but is not a HIR owner.705        // Fetch the correct information from its parent.706        AstOwner::NonOwner => fallback_to_ancestor(tcx.local_parent(def_id)),707    };708709    tcx.sess.time("drop_ast", || mem::drop(node));710711    item712}713714#[derive(Copy, Clone, PartialEq, Debug)]715enum ParamMode {716    /// Any path in a type context.717    Explicit,718    /// The `module::Type` in `module::Type::method` in an expression.719    Optional,720}721722#[derive(Copy, Clone, Debug)]723enum AllowReturnTypeNotation {724    /// Only in types, since RTN is denied later during HIR lowering.725    Yes,726    /// All other positions (path expr, method, use tree).727    No,728}729730enum GenericArgsMode {731    /// Allow paren sugar, don't allow RTN.732    ParenSugar,733    /// Allow RTN, don't allow paren sugar.734    ReturnTypeNotation,735    // Error if parenthesized generics or RTN are encountered.736    Err,737    /// Silence errors when lowering generics. Only used with `Res::Err`.738    Silence,739}740741impl<'hir> LoweringContext<'_, 'hir> {742    fn create_def(743        &mut self,744        node_id: NodeId,745        name: Option<Symbol>,746        def_kind: DefKind,747        span: Span,748    ) -> LocalDefId {749        let parent = self.current_hir_id_owner.def_id;750        assert_ne!(node_id, ast::DUMMY_NODE_ID);751        assert!(752            self.opt_local_def_id(node_id).is_none(),753            "adding a def'n for node-id {:?} and def kind {:?} but a previous def'n exists: {:?}",754            node_id,755            def_kind,756            self.tcx.hir_def_key(self.local_def_id(node_id)),757        );758759        let def_id = self760            .tcx761            .at(span)762            .create_def(parent, name, def_kind, None, &mut self.current_disambiguator)763            .def_id();764765        debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);766        self.node_id_to_def_id.insert(node_id, def_id);767768        def_id769    }770771    fn next_node_id(&mut self) -> NodeId {772        let start = self.next_node_id;773        let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");774        self.next_node_id = NodeId::from_u32(next);775        start776    }777778    /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name779    /// resolver (if any).780    #[instrument(level = "trace", skip(self), ret)]781    fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {782        self.node_id_to_def_id783            .get(&node)784            .or_else(|| self.owner.node_id_to_def_id.get(&node))785            .copied()786    }787788    fn local_def_id(&self, node: NodeId) -> LocalDefId {789        self.opt_local_def_id(node).unwrap_or_else(|| {790            self.resolver.owners.items().any(|(id, items)| {791                items.node_id_to_def_id.items().any(|(node_id, def_id)| {792                    if *node_id == node {793                        let actual_owner = items.node_id_to_def_id.get(id);794                        panic!("{def_id:?} ({node_id}) was found in {actual_owner:?} ({id})",)795                    }796                    false797                })798            });799            panic!("no entry for node id: `{node:?}`");800        })801    }802803    fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {804        match self.partial_res_overrides.get(&id) {805            Some(self_param_id) => Some(PartialRes::new(Res::Local(*self_param_id))),806            None => self.resolver.partial_res_map.get(&id).copied(),807        }808    }809810    /// Given the id of an owner node in the AST, returns the corresponding `OwnerId`.811    fn owner_id(&self, node: NodeId) -> hir::OwnerId {812        hir::OwnerId { def_id: self.resolver.owners[&node].def_id }813    }814815    /// Freshen the `LoweringContext` and ready it to lower a nested item.816    /// The lowered item is registered into `self.children`.817    ///818    /// This function sets up `HirId` lowering infrastructure,819    /// and stashes the shared mutable state to avoid pollution by the closure.820    #[instrument(level = "debug", skip(self, f))]821    fn with_hir_id_owner(822        &mut self,823        owner: NodeId,824        f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,825    ) {826        let owner_id = self.owner_id(owner);827        let def_id = owner_id.def_id;828829        let new_disambig = self830            .resolver831            .disambiguators832            .get(&def_id)833            .map(|s| s.steal())834            .unwrap_or_else(|| PerParentDisambiguatorState::new(def_id));835836        let disambiguator = mem::replace(&mut self.current_disambiguator, new_disambig);837        let current_ast_owner = mem::replace(&mut self.owner, &self.resolver.owners[&owner]);838        let current_attrs = mem::take(&mut self.attrs);839        let current_bodies = mem::take(&mut self.bodies);840        let current_define_opaque = mem::take(&mut self.define_opaque);841        let current_ident_and_label_to_local_id = mem::take(&mut self.ident_and_label_to_local_id);842843        #[cfg(debug_assertions)]844        let current_relowering_checker = mem::take(&mut self.relowering_checker);845        let current_trait_map = mem::take(&mut self.trait_map);846        let current_owner = mem::replace(&mut self.current_hir_id_owner, owner_id);847        let current_local_counter =848            mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));849        let current_impl_trait_defs = mem::take(&mut self.impl_trait_defs);850        let current_impl_trait_bounds = mem::take(&mut self.impl_trait_bounds);851        let current_delayed_lints = mem::take(&mut self.delayed_lints);852        let current_children = mem::take(&mut self.children);853854        // Do not reset `next_node_id` and `node_id_to_def_id`:855        // we want `f` to be able to refer to the `LocalDefId`s that the caller created.856        // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.857858        // Always allocate the first `HirId` for the owner itself.859        #[cfg(debug_assertions)]860        self.relowering_checker.assert_node_is_not_relowered(owner, hir::ItemLocalId::ZERO);861862        let item = f(self);863        assert_eq!(owner_id, item.def_id());864        // `f` should have consumed all the elements in these vectors when constructing `item`.865        assert!(self.impl_trait_defs.is_empty());866        assert!(self.impl_trait_bounds.is_empty());867        let info = self.make_owner_info(item);868869        self.current_disambiguator = disambiguator;870        self.owner = current_ast_owner;871        self.attrs = current_attrs;872        self.bodies = current_bodies;873        self.define_opaque = current_define_opaque;874        self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;875876        #[cfg(debug_assertions)]877        {878            self.relowering_checker = current_relowering_checker;879        }880        self.trait_map = current_trait_map;881        self.current_hir_id_owner = current_owner;882        self.item_local_id_counter = current_local_counter;883        self.impl_trait_defs = current_impl_trait_defs;884        self.impl_trait_bounds = current_impl_trait_bounds;885        self.delayed_lints = current_delayed_lints;886        self.children = current_children;887        self.children.extend_unord(info.children.items().map(|(&def_id, &info)| (def_id, info)));888889        debug_assert!(!self.children.contains_key(&owner_id.def_id));890        self.children.insert(owner_id.def_id, hir::MaybeOwner::Owner(info));891    }892893    fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {894        let attrs = mem::take(&mut self.attrs);895        let mut bodies = mem::take(&mut self.bodies);896        let define_opaque = mem::take(&mut self.define_opaque);897        let trait_map = mem::take(&mut self.trait_map);898        let delayed_lints = Steal::new(mem::take(&mut self.delayed_lints).into_boxed_slice());899        let children = mem::take(&mut self.children);900901        #[cfg(debug_assertions)]902        for (id, attrs) in attrs.iter() {903            // Verify that we do not store empty slices in the map.904            if attrs.is_empty() {905                panic!("Stored empty attributes for {:?}", id);906            }907        }908909        bodies.sort_by_key(|(k, _)| *k);910        let bodies = SortedMap::from_presorted_elements(bodies);911912        // Don't hash unless necessary, because it's expensive.913        let rustc_middle::hir::Hashes { bodies_hash, attrs_hash } =914            self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque);915        let num_nodes = self.item_local_id_counter.as_usize();916        let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);917        let nodes = hir::OwnerNodes { opt_hash: bodies_hash, nodes, bodies };918        let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };919920        let opt_hash = self.tcx.needs_hir_hash().then(|| {921            self.tcx.with_stable_hashing_context(|mut hcx| {922                let mut stable_hasher = StableHasher::new();923                bodies_hash.unwrap().stable_hash(&mut hcx, &mut stable_hasher);924                attrs_hash.unwrap().stable_hash(&mut hcx, &mut stable_hasher);925                // Do not hash delayed_lints.926                parenting.stable_hash(&mut hcx, &mut stable_hasher);927                trait_map.stable_hash(&mut hcx, &mut stable_hasher);928                children.stable_hash(&mut hcx, &mut stable_hasher);929                stable_hasher.finish()930            })931        });932933        self.arena.alloc(hir::OwnerInfo {934            opt_hash,935            nodes,936            parenting,937            attrs,938            trait_map,939            delayed_lints,940            children,941        })942    }943944    /// This method allocates a new `HirId` for the given `NodeId`.945    /// Take care not to call this method if the resulting `HirId` is then not946    /// actually used in the HIR, as that would trigger an assertion in the947    /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped948    /// properly. Calling the method twice with the same `NodeId` is also forbidden.949    #[instrument(level = "debug", skip(self), ret)]950    fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId {951        assert_ne!(ast_node_id, DUMMY_NODE_ID);952953        let owner = self.current_hir_id_owner;954        let local_id = self.item_local_id_counter;955        assert_ne!(local_id, hir::ItemLocalId::ZERO);956        self.item_local_id_counter.increment_by(1);957        let hir_id = HirId { owner, local_id };958959        if let Some(def_id) = self.opt_local_def_id(ast_node_id) {960            self.children.insert(def_id, hir::MaybeOwner::NonOwner(hir_id));961        }962963        if let Some(traits) = self.owner.trait_map.get(&ast_node_id) {964            self.trait_map.insert(hir_id.local_id, *traits);965        }966967        // Check whether the same `NodeId` is lowered more than once.968        #[cfg(debug_assertions)]969        self.relowering_checker.assert_node_is_not_relowered(ast_node_id, local_id);970971        hir_id972    }973974    /// Generate a new `HirId` without a backing `NodeId`.975    #[instrument(level = "debug", skip(self), ret)]976    fn next_id(&mut self) -> HirId {977        let owner = self.current_hir_id_owner;978        let local_id = self.item_local_id_counter;979        assert_ne!(local_id, hir::ItemLocalId::ZERO);980        self.item_local_id_counter.increment_by(1);981        HirId { owner, local_id }982    }983984    #[instrument(level = "trace", skip(self))]985    fn lower_res(&mut self, res: Res<NodeId>) -> Res {986        let res: Result<Res, ()> = res.apply_id(|id| {987            let owner = self.current_hir_id_owner;988            let local_id = self.ident_and_label_to_local_id.get(&id).copied().ok_or(())?;989            Ok(HirId { owner, local_id })990        });991        trace!(?res);992993        // We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.994        // This can happen when trying to lower the return type `x` in erroneous code like995        //   async fn foo(x: u8) -> x {}996        // In that case, `x` is lowered as a function parameter, and the return type is lowered as997        // an opaque type as a synthesized HIR owner.998        res.unwrap_or(Res::Err)999    }10001001    fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {1002        self.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())1003    }10041005    fn lower_import_res(&mut self, id: NodeId, span: Span) -> PerNS<Option<Res>> {1006        debug_assert_eq!(id, self.owner.id);1007        let per_ns = self.owner.import_res.map(|res| res.map(|res| self.lower_res(res)));1008        if per_ns.is_empty() {1009            // Propagate the error to all namespaces, just to be sure.1010            self.dcx().span_delayed_bug(span, "no resolution for an import");1011            let err = Some(Res::Err);1012            return PerNS { type_ns: err, value_ns: err, macro_ns: err };1013        }1014        per_ns1015    }10161017    fn make_lang_item_qpath(1018        &mut self,1019        lang_item: LangItem,1020        span: Span,1021        args: Option<&'hir hir::GenericArgs<'hir>>,1022    ) -> hir::QPath<'hir> {1023        hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))1024    }10251026    fn make_lang_item_path(1027        &mut self,1028        lang_item: LangItem,1029        span: Span,1030        args: Option<&'hir hir::GenericArgs<'hir>>,1031    ) -> &'hir hir::Path<'hir> {1032        let def_id = self.tcx.require_lang_item(lang_item, span);1033        let def_kind = self.tcx.def_kind(def_id);1034        let res = Res::Def(def_kind, def_id);1035        self.arena.alloc(hir::Path {1036            span,1037            res,1038            segments: self.arena.alloc_from_iter([hir::PathSegment {1039                ident: Ident::new(lang_item.name(), span),1040                hir_id: self.next_id(),1041                res,1042                args,1043                infer_args: args.is_none(),1044                delegation_child_segment: false,1045            }]),1046        })1047    }10481049    /// Reuses the span but adds information like the kind of the desugaring and features that are1050    /// allowed inside this span.1051    fn mark_span_with_reason(1052        &self,1053        reason: DesugaringKind,1054        span: Span,1055        allow_internal_unstable: Option<Arc<[Symbol]>>,1056    ) -> Span {1057        self.tcx.with_stable_hashing_context(|hcx| {1058            span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx)1059        })1060    }10611062    fn span_lowerer(&self) -> SpanLowerer {1063        SpanLowerer {1064            is_incremental: self.tcx.sess.opts.incremental.is_some(),1065            def_id: self.current_hir_id_owner.def_id,1066        }1067    }10681069    /// Intercept all spans entering HIR.1070    /// Mark a span as relative to the current owning item.1071    fn lower_span(&self, span: Span) -> Span {1072        self.span_lowerer().lower(span)1073    }10741075    fn lower_ident(&self, ident: Ident) -> Ident {1076        Ident::new(ident.name, self.lower_span(ident.span))1077    }10781079    /// Converts a lifetime into a new generic parameter.1080    #[instrument(level = "debug", skip(self))]1081    fn lifetime_res_to_generic_param(1082        &mut self,1083        ident: Ident,1084        node_id: NodeId,1085        kind: MissingLifetimeKind,1086        source: hir::GenericParamSource,1087    ) -> hir::GenericParam<'hir> {1088        // Late resolution delegates to us the creation of the `LocalDefId`.1089        let _def_id = self.create_def(1090            node_id,1091            Some(kw::UnderscoreLifetime),1092            DefKind::LifetimeParam,1093            ident.span,1094        );1095        debug!(?_def_id);10961097        let hir_id = self.lower_node_id(node_id);1098        let def_id = self.local_def_id(node_id);1099        hir::GenericParam {1100            hir_id,1101            def_id,1102            name: hir::ParamName::Fresh,1103            span: self.lower_span(ident.span),1104            pure_wrt_drop: false,1105            kind: hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided(kind) },1106            colon_span: None,1107            source,1108        }1109    }11101111    /// Lowers a lifetime binder that defines `generic_params`, returning the corresponding HIR1112    /// nodes. The returned list includes any "extra" lifetime parameters that were added by the1113    /// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id1114    /// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime1115    /// parameters will be successful.1116    #[instrument(level = "debug", skip(self), ret)]1117    #[inline]1118    fn lower_lifetime_binder(1119        &mut self,1120        binder: NodeId,1121        generic_params: &[GenericParam],1122    ) -> &'hir [hir::GenericParam<'hir>] {1123        // Start by creating params for extra lifetimes params, as this creates the definitions1124        // that may be referred to by the AST inside `generic_params`.1125        let extra_lifetimes = self.owner.extra_lifetime_params(binder);1126        debug!(?extra_lifetimes);1127        let extra_lifetimes: Vec<_> = extra_lifetimes1128            .iter()1129            .map(|&(ident, node_id, res)| {1130                self.lifetime_res_to_generic_param(1131                    ident,1132                    node_id,1133                    res,1134                    hir::GenericParamSource::Binder,1135                )1136            })1137            .collect();1138        let arena = self.arena;1139        let explicit_generic_params =1140            self.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder);1141        arena.alloc_from_iter(explicit_generic_params.chain(extra_lifetimes.into_iter()))1142    }11431144    fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {1145        let was_in_dyn_type = self.is_in_dyn_type;1146        self.is_in_dyn_type = in_scope;11471148        let result = f(self);11491150        self.is_in_dyn_type = was_in_dyn_type;11511152        result1153    }11541155    fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {1156        let current_item = self.current_item;1157        self.current_item = Some(scope_span);11581159        let was_in_loop_condition = self.is_in_loop_condition;1160        self.is_in_loop_condition = false;11611162        let old_contract = self.contract_ensures.take();11631164        let try_block_scope = mem::replace(&mut self.try_block_scope, TryBlockScope::Function);1165        let loop_scope = self.loop_scope.take();1166        let ret = f(self);1167        self.try_block_scope = try_block_scope;1168        self.loop_scope = loop_scope;11691170        self.contract_ensures = old_contract;11711172        self.is_in_loop_condition = was_in_loop_condition;11731174        self.current_item = current_item;11751176        ret1177    }11781179    fn lower_attrs(1180        &mut self,1181        id: HirId,1182        attrs: &[Attribute],1183        target_span: Span,1184        target: Target,1185    ) -> &'hir [hir::Attribute] {1186        self.lower_attrs_with_extra(id, attrs, target_span, target, &[])1187    }11881189    fn lower_attrs_with_extra(1190        &mut self,1191        id: HirId,1192        attrs: &[Attribute],1193        target_span: Span,1194        target: Target,1195        extra_hir_attributes: &[hir::Attribute],1196    ) -> &'hir [hir::Attribute] {1197        if attrs.is_empty() && extra_hir_attributes.is_empty() {1198            &[]1199        } else {1200            let mut lowered_attrs =1201                self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target);1202            lowered_attrs.extend(extra_hir_attributes.iter().cloned());12031204            assert_eq!(id.owner, self.current_hir_id_owner);1205            let ret = self.arena.alloc_from_iter(lowered_attrs);12061207            // this is possible if an item contained syntactical attribute,1208            // but none of them parse successfully or all of them were ignored1209            // for not being built-in attributes at all. They could be remaining1210            // unexpanded attributes used as markers in proc-macro derives for example.1211            // This will have emitted some diagnostics for the misparse, but will then1212            // not emit the attribute making the list empty.1213            if ret.is_empty() {1214                &[]1215            } else {1216                self.attrs.insert(id.local_id, ret);1217                ret1218            }1219        }1220    }12211222    fn lower_attrs_vec(1223        &mut self,1224        attrs: &[Attribute],1225        target_span: Span,1226        target_hir_id: HirId,1227        target: Target,1228    ) -> Vec<hir::Attribute> {1229        let l = self.span_lowerer();1230        self.attribute_parser.parse_attribute_list(1231            attrs,1232            target_span,1233            target,1234            OmitDoc::Lower,1235            |s| l.lower(s),1236            |lint_id, span, kind| {1237                self.delayed_lints.push(DelayedLint {1238                    lint_id,1239                    id: target_hir_id,1240                    span,1241                    callback: Box::new(move |dcx, level, sess: &dyn std::any::Any| {1242                        let sess = sess1243                            .downcast_ref::<rustc_session::Session>()1244                            .expect("expected `Session`");1245                        (kind.0)(dcx, level, sess)1246                    }),1247                });1248            },1249        )1250    }12511252    fn alias_attrs(&mut self, id: HirId, target_id: HirId) {1253        assert_eq!(id.owner, self.current_hir_id_owner);1254        assert_eq!(target_id.owner, self.current_hir_id_owner);1255        if let Some(&a) = self.attrs.get(&target_id.local_id) {1256            assert!(!a.is_empty());1257            self.attrs.insert(id.local_id, a);1258        }1259    }12601261    fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {1262        args.clone()1263    }12641265    /// Lower an associated item constraint.1266    #[instrument(level = "debug", skip_all)]1267    fn lower_assoc_item_constraint(1268        &mut self,1269        constraint: &AssocItemConstraint,1270        itctx: ImplTraitContext,1271    ) -> hir::AssocItemConstraint<'hir> {1272        debug!(?constraint, ?itctx);1273        // Lower the generic arguments for the associated item.1274        let gen_args = if let Some(gen_args) = &constraint.gen_args {1275            let gen_args_ctor = match gen_args {1276                GenericArgs::AngleBracketed(data) => {1277                    self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).01278                }1279                GenericArgs::Parenthesized(data) => {1280                    if let Some(first_char) = constraint.ident.as_str().chars().next()1281                        && first_char.is_ascii_lowercase()1282                    {1283                        let err = match (&data.inputs[..], &data.output) {1284                            ([_, ..], FnRetTy::Default(_)) => {1285                                diagnostics::BadReturnTypeNotation::Inputs {1286                                    span: data.inputs_span,1287                                }1288                            }1289                            ([], FnRetTy::Default(_)) => {1290                                diagnostics::BadReturnTypeNotation::NeedsDots {1291                                    span: data.inputs_span,1292                                }1293                            }1294                            // The case `T: Trait<method(..) -> Ret>` is handled in the parser.1295                            (_, FnRetTy::Ty(ty)) => {1296                                let span = data.inputs_span.shrink_to_hi().to(ty.span);1297                                diagnostics::BadReturnTypeNotation::Output {1298                                    span,1299                                    suggestion: diagnostics::RTNSuggestion {1300                                        output: span,1301                                        input: data.inputs_span,1302                                    },1303                                }1304                            }1305                        };1306                        let mut err = self.dcx().create_err(err);1307                        if !self.tcx.features().return_type_notation()1308                            && self.tcx.sess.is_nightly_build()1309                        {1310                            add_feature_diagnostics(1311                                &mut err,1312                                &self.tcx.sess,1313                                sym::return_type_notation,1314                            );1315                        }1316                        err.emit();1317                        GenericArgsCtor {1318                            args: Default::default(),1319                            constraints: &[],1320                            parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,1321                            span: data.span,1322                        }1323                    } else {1324                        let guar = self.emit_bad_parenthesized_trait_in_assoc_ty(data);1325                        self.lower_angle_bracketed_parameter_data(1326                            &data.as_angle_bracketed_args(),1327                            ParamMode::Explicit,1328                            ImplTraitContext::AlreadyErrored(guar),1329                        )1330                        .01331                    }1332                }1333                GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {1334                    args: Default::default(),1335                    constraints: &[],1336                    parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,1337                    span: *span,1338                },1339            };1340            gen_args_ctor.into_generic_args(self)1341        } else {1342            hir::GenericArgs::NONE1343        };1344        let kind = match &constraint.kind {1345            AssocItemConstraintKind::Equality { term } => {1346                let term = match term {1347                    Term::Ty(ty) => self.lower_ty_alloc(ty, itctx).into(),1348                    Term::Const(c) => self.lower_anon_const_to_const_arg_and_alloc(c).into(),1349                };1350                hir::AssocItemConstraintKind::Equality { term }1351            }1352            AssocItemConstraintKind::Bound { bounds } => {1353                // Disallow ATB in dyn types1354                if self.is_in_dyn_type {1355                    let suggestion = match itctx {1356                        ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {1357                            let bound_end_span = constraint1358                                .gen_args1359                                .as_ref()1360                                .map_or(constraint.ident.span, |args| args.span());1361                            if bound_end_span.eq_ctxt(constraint.span) {1362                                Some(self.tcx.sess.source_map().next_point(bound_end_span))1363                            } else {1364                                None1365                            }1366                        }1367                        _ => None,1368                    };13691370                    let guar = self.dcx().emit_err(diagnostics::MisplacedAssocTyBinding {1371                        span: constraint.span,1372                        suggestion,1373                    });1374                    let err_ty =1375                        &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));1376                    hir::AssocItemConstraintKind::Equality { term: err_ty.into() }1377                } else {1378                    let bounds = self.lower_param_bounds(1379                        bounds,1380                        RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::AssocTyBounds),1381                        itctx,1382                    );1383                    hir::AssocItemConstraintKind::Bound { bounds }1384                }1385            }1386        };13871388        hir::AssocItemConstraint {1389            hir_id: self.lower_node_id(constraint.id),1390            ident: self.lower_ident(constraint.ident),1391            gen_args,1392            kind,1393            span: self.lower_span(constraint.span),1394        }1395    }13961397    fn emit_bad_parenthesized_trait_in_assoc_ty(1398        &self,1399        data: &ParenthesizedArgs,1400    ) -> ErrorGuaranteed {1401        // Suggest removing empty parentheses: "Trait()" -> "Trait"1402        let sub = if data.inputs.is_empty() {1403            let parentheses_span =1404                data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());1405            AssocTyParenthesesSub::Empty { parentheses_span }1406        }1407        // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`1408        else {1409            // Start of parameters to the 1st argument1410            let open_param = data.inputs_span.shrink_to_lo().to(data1411                .inputs1412                .first()1413                .unwrap()1414                .span1415                .shrink_to_lo());1416            // End of last argument to end of parameters1417            let close_param =1418                data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());1419            AssocTyParenthesesSub::NotEmpty { open_param, close_param }1420        };1421        self.dcx().emit_err(AssocTyParentheses { span: data.span, sub })1422    }14231424    #[instrument(level = "debug", skip(self))]1425    fn lower_generic_arg(1426        &mut self,1427        arg: &ast::GenericArg,1428        itctx: ImplTraitContext,1429    ) -> hir::GenericArg<'hir> {1430        match arg {1431            ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(1432                lt,1433                LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },1434                lt.ident.into(),1435            )),1436            ast::GenericArg::Type(ty) => {1437                // We cannot just match on `TyKind::Infer` as `(_)` is represented as1438                // `TyKind::Paren(TyKind::Infer)` and should also be lowered to `GenericArg::Infer`1439                if ty.is_maybe_parenthesised_infer() {1440                    return GenericArg::Infer(self.arena.alloc(hir::InferArg {1441                        hir_id: self.lower_node_id(ty.id),1442                        span: self.lower_span(ty.span),1443                        kind: hir::InferArgKind::TypeOrConst,1444                    }));1445                }14461447                match &ty.kind {1448                    // We parse const arguments as path types as we cannot distinguish them during1449                    // parsing. We try to resolve that ambiguity by attempting resolution in both the1450                    // type and value namespaces. If we resolved the path in the value namespace, we1451                    // transform it into a generic const argument.1452                    //1453                    // Note that even under `#![feature(min_generic_const_args)]`, only plain paths1454                    // to constants are allowed - e.g. `A::<T::ASSOC_CONST>` and1455                    // `A::<CONST_WITH_PARAM::<2>>` are disallowed (they must be wrapped in `{ }`).1456                    //1457                    // FIXME: Should we be handling `(PATH_TO_CONST)`?1458                    TyKind::Path(None, path)1459                        if path.is_single_argless_ident()1460                            && let Some(res) = self1461                                .get_partial_res(ty.id)1462                                .and_then(|partial_res| partial_res.full_res())1463                            && !res.matches_ns(Namespace::TypeNS) =>1464                    {1465                        let ct =1466                            self.lower_const_path_to_const_arg(&None, path, res, ty.id, ty.span);1467                        let ct = self.arena.alloc(ct);1468                        return GenericArg::Const(ct.try_as_ambig_ct().unwrap());1469                    }1470                    TyKind::DirectConstArg(expr)1471                        if self.tcx.features().min_generic_const_args() =>1472                    {1473                        let ct = match self.can_lower_expr_to_const_arg_direct(1474                            expr,1475                            DirectConstArgContext::MacrolessMinGenericConstArgs,1476                        ) {1477                            Ok(()) => self.lower_expr_to_const_arg_direct(expr, None),1478                            Err(e) => e.emit(self),1479                        };1480                        let ct = self.arena.alloc(ct);1481                        return match ct.try_as_ambig_ct() {1482                            Some(ct) => GenericArg::Const(ct),1483                            None => GenericArg::Infer(self.arena.alloc(hir::InferArg {1484                                hir_id: ct.hir_id,1485                                span: ct.span,1486                                kind: hir::InferArgKind::Const,1487                            })),1488                        };1489                    }1490                    _ => {}1491                }1492                GenericArg::Type(self.lower_ty_alloc(ty, itctx).try_as_ambig_ty().unwrap())1493            }1494            ast::GenericArg::Const(ct) => {1495                let ct = self.lower_anon_const_to_const_arg_and_alloc(ct);1496                match ct.try_as_ambig_ct() {1497                    Some(ct) => GenericArg::Const(ct),1498                    None => GenericArg::Infer(self.arena.alloc(hir::InferArg {1499                        hir_id: ct.hir_id,1500                        span: ct.span,1501                        kind: hir::InferArgKind::Const,1502                    })),1503                }1504            }1505        }1506    }15071508    #[instrument(level = "debug", skip(self))]1509    fn lower_ty_alloc(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {1510        self.arena.alloc(self.lower_ty(t, itctx))1511    }15121513    fn lower_path_ty(1514        &mut self,1515        t: &Ty,1516        qself: &Option<Box<QSelf>>,1517        path: &Path,1518        param_mode: ParamMode,1519        itctx: ImplTraitContext,1520    ) -> hir::Ty<'hir> {1521        // Check whether we should interpret this as a bare trait object.1522        // This check mirrors the one in late resolution. We only introduce this special case in1523        // the rare occurrence we need to lower `Fresh` anonymous lifetimes.1524        // The other cases when a qpath should be opportunistically made a trait object are handled1525        // by `ty_path`.1526        if qself.is_none()1527            && let Some(partial_res) = self.get_partial_res(t.id)1528            && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()1529        {1530            let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {1531                let bound = this.lower_poly_trait_ref(1532                    &PolyTraitRef {1533                        bound_generic_params: ThinVec::new(),1534                        modifiers: TraitBoundModifiers::NONE,1535                        trait_ref: TraitRef { path: path.clone(), ref_id: t.id },1536                        span: t.span,1537                        parens: ast::Parens::No,1538                    },1539                    RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitObjectTy),1540                    itctx,1541                );1542                let bounds = this.arena.alloc_from_iter([bound]);1543                let lifetime_bound = this.elided_dyn_bound(t.span);1544                (bounds, lifetime_bound)1545            });1546            let kind = hir::TyKind::TraitObject(1547                bounds,1548                TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),1549            );1550            return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };1551        }15521553        let id = self.lower_node_id(t.id);1554        let qpath = self.lower_qpath(1555            t.id,1556            qself,1557            path,1558            param_mode,1559            AllowReturnTypeNotation::Yes,1560            itctx,1561            None,1562        );1563        self.ty_path(id, t.span, qpath)1564    }15651566    fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {1567        hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }1568    }15691570    fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {1571        self.ty(span, hir::TyKind::Tup(tys))1572    }15731574    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {1575        let kind = match &t.kind {1576            TyKind::Infer => hir::TyKind::Infer(()),1577            TyKind::Err(guar) => hir::TyKind::Err(*guar),1578            TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty_alloc(ty, itctx)),1579            TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),1580            TyKind::Ref(region, mt) => {1581                let lifetime = self.lower_ty_direct_lifetime(t, *region);1582                hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))1583            }1584            TyKind::PinnedRef(region, mt) => {1585                let lifetime = self.lower_ty_direct_lifetime(t, *region);1586                let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));1587                let span = self.lower_span(t.span);1588                let arg = hir::Ty { kind, span, hir_id: self.next_id() };1589                let args = self.arena.alloc(hir::GenericArgs {1590                    args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),1591                    constraints: &[],1592                    parenthesized: hir::GenericArgsParentheses::No,1593                    span_ext: span,1594                });1595                let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args));1596                hir::TyKind::Path(path)1597            }1598            TyKind::FnPtr(f) => {1599                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);1600                hir::TyKind::FnPtr(self.arena.alloc(hir::FnPtrTy {1601                    generic_params,1602                    safety: self.lower_safety(f.safety, hir::Safety::Safe),1603                    abi: self.lower_extern(f.ext),1604                    decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),1605                    param_idents: self.lower_fn_params_to_idents(&f.decl),1606                }))1607            }1608            TyKind::UnsafeBinder(f) => {1609                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);1610                hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {1611                    generic_params,1612                    inner_ty: self.lower_ty_alloc(&f.inner_ty, itctx),1613                }))1614            }1615            TyKind::Never => hir::TyKind::Never,1616            TyKind::Tup(tys) => hir::TyKind::Tup(1617                self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty(ty, itctx))),1618            ),1619            TyKind::Paren(ty) => {1620                return self.lower_ty(ty, itctx);1621            }1622            TyKind::Path(qself, path) => {1623                return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);1624            }1625            TyKind::ImplicitSelf => {1626                let hir_id = self.next_id();1627                let res = self.expect_full_res(t.id);1628                let res = self.lower_res(res);1629                hir::TyKind::Path(hir::QPath::Resolved(1630                    None,1631                    self.arena.alloc(hir::Path {1632                        res,1633                        segments: arena_vec![self; hir::PathSegment::new(1634                            Ident::with_dummy_span(kw::SelfUpper),1635                            hir_id,1636                            res1637                        )],1638                        span: self.lower_span(t.span),1639                    }),1640                ))1641            }1642            TyKind::Array(ty, length) => hir::TyKind::Array(1643                self.lower_ty_alloc(ty, itctx),1644                self.lower_array_length_to_const_arg(length),1645            ),1646            TyKind::TraitObject(bounds, kind) => {1647                let mut lifetime_bound = None;1648                let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {1649                    let bounds =1650                        this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {1651                            // We can safely ignore constness here since AST validation1652                            // takes care of rejecting invalid modifier combinations and1653                            // const trait bounds in trait object types.1654                            GenericBound::Trait(ty) => {1655                                let trait_ref = this.lower_poly_trait_ref(1656                                    ty,1657                                    RelaxedBoundPolicy::Forbidden(1658                                        RelaxedBoundForbiddenReason::TraitObjectTy,1659                                    ),1660                                    itctx,1661                                );1662                                Some(trait_ref)1663                            }1664                            GenericBound::Outlives(lifetime) => {1665                                if lifetime_bound.is_none() {1666                                    lifetime_bound = Some(this.lower_lifetime(1667                                        lifetime,1668                                        LifetimeSource::Other,1669                                        lifetime.ident.into(),1670                                    ));1671                                }1672                                None1673                            }1674                            // Ignore `use` syntax since that is not valid in objects.1675                            GenericBound::Use(_, span) => {1676                                this.dcx()1677                                    .span_delayed_bug(*span, "use<> not allowed in dyn types");1678                                None1679                            }1680                        }));1681                    let lifetime_bound =1682                        lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));1683                    (bounds, lifetime_bound)1684                });1685                hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))1686            }1687            TyKind::ImplTrait(def_node_id, bounds) => {1688                let span = t.span;1689                match itctx {1690                    ImplTraitContext::OpaqueTy { origin } => {1691                        self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)1692                    }1693                    ImplTraitContext::Universal => {1694                        if let Some(span) = bounds.iter().find_map(|bound| match *bound {1695                            ast::GenericBound::Use(_, span) => Some(span),1696                            _ => None,1697                        }) {1698                            self.tcx.dcx().emit_err(diagnostics::NoPreciseCapturesOnApit { span });1699                        }17001701                        let def_id = self.local_def_id(*def_node_id);1702                        let name = self.tcx.item_name(def_id.to_def_id());1703                        let ident = Ident::new(name, span);1704                        let (param, bounds, path) = self.lower_universal_param_and_bounds(1705                            *def_node_id,1706                            span,1707                            ident,1708                            bounds,1709                        );1710                        self.impl_trait_defs.push(param);1711                        if let Some(bounds) = bounds {1712                            self.impl_trait_bounds.push(bounds);1713                        }1714                        path1715                    }1716                    ImplTraitContext::InBinding => {1717                        hir::TyKind::TraitAscription(self.lower_param_bounds(1718                            bounds,1719                            RelaxedBoundPolicy::Allowed(&mut Default::default()),1720                            itctx,1721                        ))1722                    }1723                    ImplTraitContext::FeatureGated(position, feature) => {1724                        let guar = self1725                            .tcx1726                            .sess1727                            .create_feature_err(1728                                MisplacedImplTrait {1729                                    span: t.span,1730                                    position: DiagArgFromDisplay(&position),1731                                },1732                                feature,1733                            )1734                            .emit();1735                        hir::TyKind::Err(guar)1736                    }1737                    ImplTraitContext::Disallowed(position) => {1738                        let guar = self.dcx().emit_err(MisplacedImplTrait {1739                            span: t.span,1740                            position: DiagArgFromDisplay(&position),1741                        });1742                        hir::TyKind::Err(guar)1743                    }1744                    ImplTraitContext::AlreadyErrored(guar) => {1745                        // `GenericArgs::Parenthesized` stores its inputs as `Param`s, so the def1746                        // collector visits `impl Trait` in a universal context and creates a1747                        // `DefKind::TyParam`. During recovery we reinterpret these arguments as1748                        // angle-bracketed, where lowering may otherwise expect an opaque type.1749                        // The parenthesized syntax has already been rejected, so avoid lowering1750                        // this `impl Trait` with the inconsistent `DefKind`.1751                        hir::TyKind::Err(guar)1752                    }1753                }1754            }1755            TyKind::Pat(ty, pat) => {1756                hir::TyKind::Pat(self.lower_ty_alloc(ty, itctx), self.lower_ty_pat(pat, ty.span))1757            }1758            TyKind::FieldOf(ty, variant, field) => hir::TyKind::FieldOf(1759                self.lower_ty_alloc(ty, itctx),1760                self.arena.alloc(hir::TyFieldPath {1761                    variant: variant.map(|variant| self.lower_ident(variant)),1762                    field: self.lower_ident(*field),1763                }),1764            ),1765            TyKind::MacCall(_) => {1766                span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")1767            }1768            TyKind::CVarArgs => {1769                let guar = self.dcx().span_delayed_bug(1770                    t.span,1771                    "`TyKind::CVarArgs` should have been handled elsewhere",1772                );1773                hir::TyKind::Err(guar)1774            }1775            TyKind::View(ty, fields) => {1776                let ty = self.lower_ty_alloc(ty, itctx);1777                let fields = self.arena.alloc_slice(fields);1778                hir::TyKind::View(ty, fields)1779            }1780            TyKind::DirectConstArg(expr) => {1781                let e = self.emit_bad_direct_const_arg(t.span, expr, "type");1782                hir::TyKind::Err(e)1783            }1784            TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),1785        };17861787        hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }1788    }17891790    pub(crate) fn emit_bad_direct_const_arg(1791        &mut self,1792        span: Span,1793        expr: &Expr,1794        expected: &'static str,1795    ) -> ErrorGuaranteed {1796        let msg = format!("expected {expected}, found `direct_const_arg!()` constant");1797        if expr::WillCreateDefIdsVisitor.visit_expr(expr).is_break() {1798            // FIXME(mgca): make this non-fatal once we have a better way to handle1799            // nested items in invalid `direct_const_arg!()` arguments.1800            self.dcx().struct_span_fatal(span, msg).emit()1801        } else {1802            self.dcx().struct_span_err(span, msg).emit()1803        }1804    }18051806    fn lower_ty_direct_lifetime(1807        &mut self,1808        t: &Ty,1809        region: Option<Lifetime>,1810    ) -> &'hir hir::Lifetime {1811        let (region, syntax) = match region {1812            Some(region) => (region, region.ident.into()),18131814            None => {1815                let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =1816                    self.owner.get_lifetime_res(t.id)1817                {1818                    assert_eq!(start.plus(1), end);1819                    start1820                } else {1821                    self.next_node_id()1822                };1823                let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();1824                let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };1825                (region, LifetimeSyntax::Implicit)1826            }1827        };1828        self.lower_lifetime(&region, LifetimeSource::Reference, syntax)1829    }18301831    /// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =1832    /// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a1833    /// HIR type that references the TAIT.1834    ///1835    /// Given a function definition like:1836    ///1837    /// ```rust1838    /// use std::fmt::Debug;1839    ///1840    /// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {1841    ///     x1842    /// }1843    /// ```1844    ///1845    /// we will create a TAIT definition in the HIR like1846    ///1847    /// ```rust,ignore (pseudo-Rust)1848    /// type TestReturn<'a, T, 'x> = impl Debug + 'x1849    /// ```1850    ///1851    /// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:1852    ///1853    /// ```rust,ignore (pseudo-Rust)1854    /// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>1855    /// ```1856    ///1857    /// Note the subtlety around type parameters! The new TAIT, `TestReturn`, inherits all the1858    /// type parameters from the function `test` (this is implemented in the query layer, they aren't1859    /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to1860    /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters1861    /// for the lifetimes that get captured (`'x`, in our example above) and reference those.1862    #[instrument(level = "debug", skip(self), ret)]1863    fn lower_opaque_impl_trait(1864        &mut self,1865        span: Span,1866        origin: hir::OpaqueTyOrigin<LocalDefId>,1867        opaque_ty_node_id: NodeId,1868        bounds: &GenericBounds,1869        itctx: ImplTraitContext,1870    ) -> hir::TyKind<'hir> {1871        // Make sure we know that some funky desugaring has been going on here.1872        // This is a first: there is code in other places like for loop1873        // desugaring that explicitly states that we don't want to track that.1874        // Not tracking it makes lints in rustc and clippy very fragile, as1875        // frequently opened issues show.1876        let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);18771878        self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {1879            this.lower_param_bounds(1880                bounds,1881                RelaxedBoundPolicy::Allowed(&mut Default::default()),1882                itctx,1883            )1884        })1885    }18861887    fn lower_opaque_inner(1888        &mut self,1889        opaque_ty_node_id: NodeId,1890        origin: hir::OpaqueTyOrigin<LocalDefId>,1891        opaque_ty_span: Span,1892        lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],1893    ) -> hir::TyKind<'hir> {1894        let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);1895        let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);1896        debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);18971898        let bounds = lower_item_bounds(self);1899        let opaque_ty_def = hir::OpaqueTy {1900            hir_id: opaque_ty_hir_id,1901            def_id: opaque_ty_def_id,1902            bounds,1903            origin,1904            span: self.lower_span(opaque_ty_span),1905        };1906        let opaque_ty_def = self.arena.alloc(opaque_ty_def);19071908        hir::TyKind::OpaqueDef(opaque_ty_def)1909    }19101911    fn lower_precise_capturing_args(1912        &mut self,1913        precise_capturing_args: &[PreciseCapturingArg],1914    ) -> &'hir [hir::PreciseCapturingArg<'hir>] {1915        self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {1916            PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(1917                self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),1918            ),1919            PreciseCapturingArg::Arg(path, id) => {1920                let [segment] = path.segments.as_slice() else {1921                    panic!();1922                };1923                let res = self.get_partial_res(*id).map_or(Res::Err, |partial_res| {1924                    partial_res.full_res().expect("no partial res expected for precise capture arg")1925                });1926                hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {1927                    hir_id: self.lower_node_id(*id),1928                    ident: self.lower_ident(segment.ident),1929                    res: self.lower_res(res),1930                })1931            }1932        }))1933    }19341935    fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {1936        self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {1937            PatKind::Missing => None,1938            PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),1939            PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),1940            _ => {1941                self.dcx().span_delayed_bug(1942                    param.pat.span,1943                    "non-missing/ident/wild param pat must trigger an error",1944                );1945                None1946            }1947        }))1948    }19491950    /// Lowers a function declaration.1951    ///1952    /// `decl`: the unlowered (AST) function declaration.1953    ///1954    /// `fn_node_id`: `impl Trait` arguments are lowered into generic parameters on the given1955    /// `NodeId`.1956    ///1957    /// `transform_return_type`: if `Some`, applies some conversion to the return type, such as is1958    /// needed for `async fn` and `gen fn`. See [`CoroutineKind`] for more details.1959    #[instrument(level = "debug", skip(self))]1960    fn lower_fn_decl(1961        &mut self,1962        decl: &FnDecl,1963        fn_node_id: NodeId,1964        fn_span: Span,1965        kind: FnDeclKind,1966        coro: Option<CoroutineMarker>,1967    ) -> &'hir hir::FnDecl<'hir> {1968        let c_variadic = decl.c_variadic();1969        let mut splatted = decl.splatted();19701971        // Skip the `...` (`CVarArgs`) trailing arguments from the AST,1972        // as they are not explicit in HIR/Ty function signatures.1973        // (instead, the `c_variadic` flag is set to `true`)1974        let mut inputs = &decl.inputs[..];1975        if decl.c_variadic() {1976            // Splat + variadic errors in AST validation, so just ignore one of them here.1977            splatted = None;1978            inputs = &inputs[..inputs.len() - 1];1979        }1980        let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {1981            let itctx = match kind {1982                FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {1983                    ImplTraitContext::Universal1984                }1985                FnDeclKind::ExternFn => {1986                    ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)1987                }1988                FnDeclKind::Closure => {1989                    ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)1990                }1991                FnDeclKind::Pointer => {1992                    ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)1993                }1994            };1995            self.lower_ty(&param.ty, itctx)1996        }));19971998        let output = match coro {1999            Some(coro) => {2000                let fn_def_id = self.owner.def_id;

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.